Whamcloud - gitweb
merge devel to lcfg
authorrread <rread>
Thu, 2 Oct 2003 19:52:38 +0000 (19:52 +0000)
committerrread <rread>
Thu, 2 Oct 2003 19:52:38 +0000 (19:52 +0000)
23 files changed:
lnet/klnds/gmlnd/Makefile.mk [new file with mode: 0644]
lnet/klnds/gmlnd/gmlnd_api.c [new file with mode: 0644]
lnet/klnds/gmlnd/gmlnd_comm.c [new file with mode: 0644]
lnet/klnds/gmlnd/gmlnd_module.c [new file with mode: 0644]
lnet/klnds/gmlnd/gmlnd_utils.c [new file with mode: 0644]
lnet/utils/gmlndnid.c [new file with mode: 0644]
lustre/kernel_patches/patches/2.6.0-test5-mm4.patch [new file with mode: 0644]
lustre/kernel_patches/patches/dump_netdev_over_netpoll.patch [new file with mode: 0644]
lustre/kernel_patches/patches/export-netpoll.patch [new file with mode: 0644]
lustre/kernel_patches/patches/kexec-2.6.0-test5-full.patch [new file with mode: 0644]
lustre/kernel_patches/patches/kgdb-over-netpoll.patch [new file with mode: 0644]
lustre/kernel_patches/patches/lkcd-cvs-2.6.0-test5.patch [new file with mode: 0644]
lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test5.patch [new file with mode: 0644]
lustre/kernel_patches/patches/netconsole-over-netpoll.patch [new file with mode: 0644]
lustre/kernel_patches/patches/netpoll-core.patch [new file with mode: 0644]
lustre/kernel_patches/patches/uml-patch-2.6.0-test5.patch [new file with mode: 0644]
lustre/kernel_patches/pc/uml-patch-2.6.0-test5.pc [new file with mode: 0644]
lustre/portals/knals/gmnal/Makefile.mk [new file with mode: 0644]
lustre/portals/knals/gmnal/gmnal_api.c [new file with mode: 0644]
lustre/portals/knals/gmnal/gmnal_comm.c [new file with mode: 0644]
lustre/portals/knals/gmnal/gmnal_module.c [new file with mode: 0644]
lustre/portals/knals/gmnal/gmnal_utils.c [new file with mode: 0644]
lustre/portals/utils/gmnalnid.c [new file with mode: 0644]

diff --git a/lnet/klnds/gmlnd/Makefile.mk b/lnet/klnds/gmlnd/Makefile.mk
new file mode 100644 (file)
index 0000000..b799a47
--- /dev/null
@@ -0,0 +1,10 @@
+# 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 ../../Kernelenv
+
+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/gmlnd_api.c b/lnet/klnds/gmlnd/gmlnd_api.c
new file mode 100644 (file)
index 0000000..40d23db
--- /dev/null
@@ -0,0 +1,474 @@
+/* -*- 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_stxd(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_stxd(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_stxd(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_stxd(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_stxd(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_stxd(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));
+}
+
+EXPORT_SYMBOL(gmnal_init);
+EXPORT_SYMBOL(gmnal_fini);
+EXPORT_SYMBOL(gmnal_api_forward);
+EXPORT_SYMBOL(gmnal_api_validate);
+EXPORT_SYMBOL(gmnal_api_yield);
+EXPORT_SYMBOL(gmnal_api_lock);
+EXPORT_SYMBOL(gmnal_api_unlock);
+EXPORT_SYMBOL(gmnal_api_shutdown);
diff --git a/lnet/klnds/gmlnd/gmlnd_comm.c b/lnet/klnds/gmlnd/gmlnd_comm.c
new file mode 100644 (file)
index 0000000..9e32145
--- /dev/null
@@ -0,0 +1,1316 @@
+/* -*- 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;
+
+       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);
+               CDEBUG(D_INFO, "got [%s]\n", gmnal_rxevent(rxevent));
+               if (nal_data->ctthread_flag == GMNAL_THREAD_STOP) {
+                       CDEBUG(D_INFO, "time to exit\n");
+                       break;
+               }
+               switch (GM_RECV_EVENT_TYPE(rxevent)) {
+
+                       case(GM_RECV_EVENT):
+                               CDEBUG(D_NET, "CTTHREAD:: GM_RECV_EVENT\n");
+                               GMNAL_GM_UNLOCK(nal_data);
+                               gmnal_add_rxtwe(nal_data, rxevent);
+                               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;
+       gm_recv_event_t         *rxevent = NULL;
+       gm_recv_t               *recv = NULL;
+       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;
+               }
+               rxevent = we->rx;
+               CDEBUG(D_INFO, "thread got [%s]\n", gmnal_rxevent(rxevent));
+               recv = (gm_recv_t*)&(rxevent->recv);
+               buffer = gm_ntohp(recv->buffer);
+               PORTAL_FREE(we, sizeof(gmnal_rxtwe_t));
+
+               switch(((gmnal_msghdr_t*)buffer)->type) {
+               case(GMNAL_SMALL_MESSAGE):
+                       gmnal_pre_receive(nal_data, recv, 
+                                          GMNAL_SMALL_MESSAGE);
+               break;  
+               case(GMNAL_LARGE_MESSAGE_INIT):
+                       gmnal_pre_receive(nal_data, recv, 
+                                          GMNAL_LARGE_MESSAGE_INIT);
+               break;  
+               case(GMNAL_LARGE_MESSAGE_ACK):
+                       gmnal_pre_receive(nal_data, recv, 
+                                          GMNAL_LARGE_MESSAGE_ACK);
+               break;  
+               default:
+                       CDEBUG(D_ERROR, "Unsupported message type\n");
+                       gmnal_rx_bad(nal_data, recv, NULL);
+               }
+       }
+
+       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, gm_recv_t *recv, 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], recv [%p] type [%d]\n", 
+              nal_data, recv, gmnal_type);
+
+       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);
+
+       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, gm_recv_t *recv, gmnal_srxd_t *srxd)
+{
+       CDEBUG(D_TRACE, "Can't handle message\n");
+
+       if (!srxd)
+               srxd = gmnal_rxbuffer_to_srxd(nal_data, 
+                                              gm_ntohp(recv->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");
+       }
+       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
+        */
+       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_stxd_t    *stxd = 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
+                */
+               stxd = gmnal_get_stxd(nal_data, 1);
+               stxd->srxd = srxd;
+               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");
+                               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, stxd);
+                               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");
+                               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, stxd);
+                               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");
+                               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, stxd);
+                               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_stxd_t    *stxd = (gmnal_stxd_t*)context;
+       gmnal_srxd_t    *srxd = stxd->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_stxd(nal_data, stxd);
+
+       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;
+}
+
+
+
+
+EXPORT_SYMBOL(gmnal_rx_thread);
+EXPORT_SYMBOL(gmnal_ct_thread);
+EXPORT_SYMBOL(gmnal_pre_receive);
+EXPORT_SYMBOL(gmnal_rx_requeue_buffer);
+EXPORT_SYMBOL(gmnal_rx_bad);
+EXPORT_SYMBOL(gmnal_small_rx);
+EXPORT_SYMBOL(gmnal_large_tx);
+EXPORT_SYMBOL(gmnal_large_tx_callback);
+EXPORT_SYMBOL(gmnal_small_tx_callback);
diff --git a/lnet/klnds/gmlnd/gmlnd_module.c b/lnet/klnds/gmlnd/gmlnd_module.c
new file mode 100644 (file)
index 0000000..8e0f64c
--- /dev/null
@@ -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 portal_ioctl_data *data, 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", 
+              data->ioc_nal_cmd, private);
+       nal_data = (gmnal_data_t*)private;
+       switch(data->ioc_nal_cmd) {
+       /*
+        * just reuse already defined GET_NID. Should define GMNAL version
+        */
+       case(GMNAL_IOC_GET_GNID):
+
+               PORTAL_ALLOC(name, data->ioc_plen1);
+               copy_from_user(name, data->ioc_pbuf1, data->ioc_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(data->ioc_pbuf2, &gnid, data->ioc_plen2);
+       break;
+       default:
+               CDEBUG(D_INFO, "gmnal_cmd UNKNOWN[%d]\n", data->ioc_nal_cmd);
+               data->ioc_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 (file)
index 0000000..84fc3a0
--- /dev/null
@@ -0,0 +1,1007 @@
+/* -*- 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 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.
+ */
+int
+gmnal_alloc_stxd(gmnal_data_t *nal_data)
+{
+       int ntx = 0, nstx = 0, i = 0, nrxt_stx = 10;
+       gmnal_stxd_t    *txd = NULL;
+       void    *txbuffer = NULL;
+
+       CDEBUG(D_TRACE, "gmnal_alloc_small tx\n");
+
+       GMNAL_GM_LOCK(nal_data);
+       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);
+       
+       nstx = ntx/2;
+       /*
+        * num_stxds from gmnal_module.c
+        */
+       nstx = num_stxds;
+        nrxt_stx = nstx + 1;
+
+       CDEBUG(D_INFO, "Allocated [%d] send tokens to small messages\n", nstx);
+
+
+       /*
+        * 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);
+       
+       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);
+       }
+
+       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_stxd(gmnal_data_t *nal_data)
+{
+       gmnal_stxd_t *txd = nal_data->stxd, *_txd = 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));
+       }
+       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;
+               if (txd)
+                       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;
+               if (txd)
+                       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;
+}
+
+
+/*
+ *     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);
+       }
+
+}
+
+int
+gmnal_add_rxtwe(gmnal_data_t *nal_data, gm_recv_event_t *rxevent)
+{
+       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->rx = rxevent;
+
+       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);
+}
+
+EXPORT_SYMBOL(gmnal_yield);
+EXPORT_SYMBOL(gmnal_alloc_srxd);
+EXPORT_SYMBOL(gmnal_get_srxd);
+EXPORT_SYMBOL(gmnal_return_srxd);
+EXPORT_SYMBOL(gmnal_free_srxd);
+EXPORT_SYMBOL(gmnal_alloc_stxd);
+EXPORT_SYMBOL(gmnal_get_stxd);
+EXPORT_SYMBOL(gmnal_return_stxd);
+EXPORT_SYMBOL(gmnal_free_stxd);
+EXPORT_SYMBOL(gmnal_rxbuffer_to_srxd);
+EXPORT_SYMBOL(gmnal_rxevent);
+EXPORT_SYMBOL(gmnal_gm_error);
+EXPORT_SYMBOL(gmnal_stop_ctthread);
+EXPORT_SYMBOL(gmnal_add_rxtwe);
+EXPORT_SYMBOL(gmnal_get_rxtwe);
diff --git a/lnet/utils/gmlndnid.c b/lnet/utils/gmlndnid.c
new file mode 100644 (file)
index 0000000..701a814
--- /dev/null
@@ -0,0 +1,118 @@
+/* -*- 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;
+       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);
+       }
+
+
+
+        PORTAL_IOC_INIT (data);
+
+       /*
+        *      set up the inputs
+        */
+       len = strlen(name) + 1;
+       data.ioc_pbuf1 = malloc(len);
+       strcpy(data.ioc_pbuf1, name);
+       data.ioc_plen1 = len;
+
+       /*
+        *      set up the outputs
+        */
+       data.ioc_pbuf2 = (void*)&nid;
+       data.ioc_plen2 = sizeof(unsigned int*);
+
+        pfd = open("/dev/portals", O_RDWR);
+        if ( pfd < 0 ) {
+                perror("opening portals device");
+               free(data.ioc_pbuf1);
+                exit(-1);
+        }
+
+        data.ioc_nal = GMNAL;
+       data.ioc_nal_cmd = GMNAL_IOC_GET_GNID;
+/*
+       data.ioc_len += data.ioc_inllen1;
+       data.ioc_len += data.ioc_plen1;
+*/
+        rc = ioctl (pfd, IOC_PORTAL_NAL_CMD, &data);
+        if (rc < 0)
+        {
+               perror ("Can't get my NID");
+        }
+                        
+       free(data.ioc_pbuf1);
+       close(pfd);
+       printf("%u\n", nid);
+        exit(nid);
+}
diff --git a/lustre/kernel_patches/patches/2.6.0-test5-mm4.patch b/lustre/kernel_patches/patches/2.6.0-test5-mm4.patch
new file mode 100644 (file)
index 0000000..3f36ac7
--- /dev/null
@@ -0,0 +1,243558 @@
+Index: linux-2.6.0-test5/arch/alpha/boot/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/boot/misc.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/boot/misc.c   2003-09-27 11:38:18.536710376 +0800
+@@ -106,8 +106,8 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
+-      if (free_mem_ptr <= 0) error("Memory error\n");
++      if (size <0) error("Malloc error");
++      if (free_mem_ptr <= 0) error("Memory error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+@@ -140,7 +140,7 @@
+ int fill_inbuf(void)
+ {
+       if (insize != 0)
+-              error("ran out of input data\n");
++              error("ran out of input data");
+       inbuf = input_data;
+       insize = input_data_size;
+Index: linux-2.6.0-test5/arch/alpha/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/Kconfig  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/Kconfig       2003-09-27 11:38:18.543709312 +0800
+@@ -484,6 +484,9 @@
+         Otherwise, say N.
++config EISA_ALWAYS
++      def_bool EISA
++
+ config SMP
+       bool "Symmetric multi-processing support"
+       depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
+Index: linux-2.6.0-test5/arch/alpha/kernel/core_irongate.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/kernel/core_irongate.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/kernel/core_irongate.c        2003-09-27 11:38:18.546708856 +0800
+@@ -391,7 +391,7 @@
+               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);
+Index: linux-2.6.0-test5/arch/alpha/kernel/core_marvel.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/kernel/core_marvel.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/kernel/core_marvel.c  2003-09-27 11:38:18.553707792 +0800
+@@ -696,7 +696,7 @@
+                       }
+                       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");
+Index: linux-2.6.0-test5/arch/alpha/kernel/core_titan.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/alpha/kernel/core_titan.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/alpha/kernel/core_titan.c   2003-09-27 11:38:18.562706424 +0800
+@@ -534,7 +534,7 @@
+                       }
+                       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");
+Index: linux-2.6.0-test5/arch/arm26/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm26/boot/compressed/misc.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm26/boot/compressed/misc.c        2003-09-27 11:38:18.564706120 +0800
+@@ -191,8 +191,8 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
+-      if (free_mem_ptr <= 0) error("Memory error\n");
++      if (size <0) error("Malloc error");
++      if (free_mem_ptr <= 0) error("Memory error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+@@ -236,7 +236,7 @@
+ int fill_inbuf(void)
+ {
+       if (insize != 0)
+-              error("ran out of input data\n");
++              error("ran out of input data");
+       inbuf = input_data;
+       insize = &input_data_end[0] - &input_data[0];
+Index: linux-2.6.0-test5/arch/arm26/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm26/kernel/setup.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm26/kernel/setup.c        2003-09-27 11:38:18.569705360 +0800
+@@ -286,7 +286,7 @@
+       if (tag->hdr.size > 2) {
+               if ((tag->u.core.flags & 1) == 0)
+                       root_mountflags &= ~MS_RDONLY;
+-              ROOT_DEV = tag->u.core.rootdev;
++              ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+       }
+       return 0;
+ }
+Index: linux-2.6.0-test5/arch/arm/boot/bootp/init.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/boot/bootp/init.S  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/boot/bootp/init.S       2003-09-27 11:38:18.570705208 +0800
+@@ -1,86 +1,69 @@
+ /*
+  *  linux/arch/arm/boot/bootp/init.S
+  *
+- *  Copyright (C) 2000-2002 Russell King
++ *  Copyright (C) 2000-2003 Russell King.
+  *
+  * 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.
+  *
+- *  Header file for splitting kernel + initrd.  Note that we pass
++ *  "Header" file for splitting kernel + initrd.  Note that we pass
+  *  r0 through to r3 straight through.
++ *
++ *  This demonstrates how to append code to the start of the kernel
++ *  zImage, and boot the kernel without copying it around.  This
++ *  example would be simpler; if we didn't have an object of unknown
++ *  size immediately following the kernel, we could build this into
++ *  a binary blob, and concatenate the zImage using the cat command.
+  */
+               .section .start,#alloc,#execinstr
+               .type   _start, #function
+               .globl  _start
+-_start:               adr     r10, initdata
+-              ldr     r11, initdata
+-              sub     r11, r10, r11           @ work out exec offset
+-              b       splitify
+-              .size   _entry,. - _entry
+-
+-              .type   initdata, #object
+-initdata:     .word   initdata                @ compiled address of this
+-              .size   initdata,. - initdata
+-
+-splitify:     adr     r13, data
+-              ldmia   r13!, {r4-r6}           @ move the initrd
+-              add     r4, r4, r11             @ correction
+-              bl      move
++
++_start:               adr     r12, kernel_start       @ offset of kernel zImage
++              ldr     r4, [r12, #0x2c]        @ length of zImage
++              adr     r13, data
++              add     r4, r4, r12             @ end of zImage, start of initrd
++              ldmia   r13!, {r5-r6}           @ r5 = dest, r6 = length
++              bl      move                    @ move the initrd
+ /*
+- * Setup the initrd parameters to pass to the kernel.  This can either be
+- * passed in via a param_struct or a tag list.  We spot the param_struct
+- * method by looking at the first word; this should either indicate a page
+- * size of 4K, 16K or 32K.
++ * Setup the initrd parameters to pass to the kernel.  This can only be
++ * passed in via the tagged list.
+  */
+-              ldmia   r13, {r4-r8}            @ get size and addr of initrd
+-                                              @ r5 = ATAG_INITRD
+-                                              @ r6 = initrd start
+-                                              @ r7 = initrd end
+-                                              @ r8 = param_struct address
+-              ldr     r9, [r8, #0]            @ no param struct?
+-              teq     r9, #0x1000             @ 4K?
+-              teqne   r9, #0x4000             @ 16K?
+-              teqne   r9, #0x8000             @ 32K?
+-              beq     param_struct
+-
+-              ldr     r9, [r8, #4]            @ get first tag
+-              teq     r9, r4
+-              bne     taglist                 @ ok, we have a tag list
++              ldmia   r13, {r5-r9}            @ get size and addr of initrd
++                                              @ r5 = ATAG_CORE
++                                              @ r6 = ATAG_INITRD2
++                                              @ r7 = initrd start
++                                              @ r8 = initrd end
++                                              @ r9 = param_struct address
++              ldr     r10, [r9, #4]           @ get first tag
++              teq     r10, r5                 @ is it ATAG_CORE?
+ /*
+- * We didn't find a valid tag list - create one.
++ * If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
+  */
+-              str     r4, [r8, #4]
+-              mov     r4, #8
+-              str     r4, [r8, #0]
+-              mov     r4, #0
+-              str     r4, [r8, #8]
++              movne   r10, #0                 @ terminator
++              movne   r4, #2                  @ Size of this entry (2 words)
++              stmneia r8, {r4, r5, r10}       @ Size, ATAG_CORE, terminator
+ /*
+  * find the end of the tag list, and then add an INITRD tag on the end.
+  * If there is already an INITRD tag, then we ignore it; the last INITRD
+  * tag takes precidence.
+  */
+-taglist:      ldr     r9, [r8, #0]            @ tag length
+-              teq     r9, #0                  @ last tag?
+-              addne   r8, r8, r9
++taglist:      ldr     r10, [r9, #0]           @ tag length
++              teq     r10, #0                 @ last tag (zero length)?
++              addne   r9, r9, r10, lsl #2
+               bne     taglist
+-              mov     r4, #16                 @ length of initrd tag
+-              mov     r9, #0                  @ end of tag list terminator
+-              stmia   r8, {r4, r5, r6, r7, r9}
+-              adr     r12, kernel_start
++              mov     r5, #4                  @ Size of initrd tag (4 words)
++              stmia   r9, {r5, r6, r7, r8, r10}
+               mov     pc, r12                 @ call kernel
+ /*
+- * We found a param struct.  Modify the param struct for the initrd
++ * Move the block of memory length r6 from address r4 to address r5
+  */
+-param_struct: add     r8, r8, #16*4
+-              stmia   r8, {r6,r7}             @ save in param_struct
+-              mov     pc, r12                 @ call kernel
+-
+ move:         ldmia   r4!, {r7 - r10}         @ move 32-bytes at a time
+               stmia   r5!, {r7 - r10}
+               ldmia   r4!, {r7 - r10}
+@@ -89,15 +72,18 @@
+               bcs     move
+               mov     pc, lr
+-data:         .word   initrd_start
+-              .word   initrd_addr
+-              .word   initrd_len
++              .size   _start, . - _start
++
++              .type   data,#object
++data:         .word   initrd_addr             @ destination initrd address
++              .word   initrd_len              @ initrd size
+               .word   0x54410001              @ r4 = ATAG_CORE
+-              .word   0x54420005              @ r5 = ATAG_INITRD
++              .word   0x54420005              @ r5 = ATAG_INITRD2
+               .word   initrd_addr             @ r6
+               .word   initrd_len              @ r7
+               .word   params                  @ r8
++              .size   data, . - _data
+               .type   initrd_start,#object
+Index: linux-2.6.0-test5/arch/arm/boot/compressed/head-sa1100.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/boot/compressed/head-sa1100.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/boot/compressed/head-sa1100.S   2003-09-27 11:38:18.572704904 +0800
+@@ -34,6 +34,10 @@
+               @ REVISIT_PFS168: Temporary until firmware updated to use assigned machine number
+               mov     r7, #MACH_TYPE_PFS168
+ #endif
++#ifdef CONFIG_SA1100_SIMPAD
++              @ UNTIL we've something like an open bootldr
++              mov     r7, #MACH_TYPE_SIMPAD @should be 87
++#endif
+ #ifdef CONFIG_SA1100_VICTOR
+               teq     r7, #MACH_TYPE_VICTOR
+Index: linux-2.6.0-test5/arch/arm/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/boot/compressed/misc.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/boot/compressed/misc.c  2003-09-27 11:38:18.574704600 +0800
+@@ -191,8 +191,8 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
+-      if (free_mem_ptr <= 0) error("Memory error\n");
++      if (size <0) error("Malloc error");
++      if (free_mem_ptr <= 0) error("Memory error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+@@ -236,7 +236,7 @@
+ int fill_inbuf(void)
+ {
+       if (insize != 0)
+-              error("ran out of input data\n");
++              error("ran out of input data");
+       inbuf = input_data;
+       insize = &input_data_end[0] - &input_data[0];
+Index: linux-2.6.0-test5/arch/arm/common/sa1111.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/common/sa1111.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/common/sa1111.c 2003-09-27 11:38:18.583703232 +0800
+@@ -14,6 +14,7 @@
+  * All initialization functions provided here are intended to be called
+  * from machine specific code with proper arguments when required.
+  */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -54,87 +55,74 @@
+  */
+ static struct sa1111 *g_sa1111;
+-static struct sa1111_dev usb_dev = {
+-      .skpcr_mask     = SKPCR_UCLKEN,
+-      .devid          = SA1111_DEVID_USB,
+-      .irq = {
+-              IRQ_USBPWR,
+-              IRQ_HCIM,
+-              IRQ_HCIBUFFACC,
+-              IRQ_HCIRMTWKP,
+-              IRQ_NHCIMFCIR,
+-              IRQ_USB_PORT_RESUME
+-      },
++struct sa1111_dev_info {
++      unsigned long   offset;
++      unsigned long   skpcr_mask;
++      unsigned int    devid;
++      unsigned int    irq[6];
+ };
+-static struct sa1111_dev sac_dev = {
+-      .skpcr_mask     = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
+-      .devid          = SA1111_DEVID_SAC,
+-      .irq = {
+-              AUDXMTDMADONEA,
+-              AUDXMTDMADONEB,
+-              AUDRCVDMADONEA,
+-              AUDRCVDMADONEB
++static struct sa1111_dev_info sa1111_devices[] = {
++      {
++              .offset         = SA1111_USB,
++              .skpcr_mask     = SKPCR_UCLKEN,
++              .devid          = SA1111_DEVID_USB,
++              .irq = {
++                      IRQ_USBPWR,
++                      IRQ_HCIM,
++                      IRQ_HCIBUFFACC,
++                      IRQ_HCIRMTWKP,
++                      IRQ_NHCIMFCIR,
++                      IRQ_USB_PORT_RESUME
++              },
+       },
+-};
+-
+-static struct sa1111_dev ssp_dev = {
+-      .skpcr_mask     = SKPCR_SCLKEN,
+-      .devid          = SA1111_DEVID_SSP,
+-};
+-
+-static struct sa1111_dev kbd_dev = {
+-      .skpcr_mask     = SKPCR_PTCLKEN,
+-      .devid          = SA1111_DEVID_PS2,
+-      .irq = {
+-              IRQ_TPRXINT,
+-              IRQ_TPTXINT
++      {
++              .offset         = 0x0600,
++              .skpcr_mask     = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
++              .devid          = SA1111_DEVID_SAC,
++              .irq = {
++                      AUDXMTDMADONEA,
++                      AUDXMTDMADONEB,
++                      AUDRCVDMADONEA,
++                      AUDRCVDMADONEB
++              },
+       },
+-};
+-
+-static struct sa1111_dev mse_dev = {
+-      .skpcr_mask     = SKPCR_PMCLKEN,
+-      .devid          = SA1111_DEVID_PS2,
+-      .irq = {
+-              IRQ_MSRXINT,
+-              IRQ_MSTXINT
++      {
++              .offset         = 0x0800,
++              .skpcr_mask     = SKPCR_SCLKEN,
++              .devid          = SA1111_DEVID_SSP,
+       },
+-};
+-
+-static struct sa1111_dev int_dev = {
+-      .skpcr_mask     = 0,
+-      .devid          = SA1111_DEVID_INT,
+-};
+-
+-static struct sa1111_dev pcmcia_dev = {
+-      .skpcr_mask     = 0,
+-      .devid          = SA1111_DEVID_PCMCIA,
+-      .irq = {
+-              IRQ_S0_READY_NINT,
+-              IRQ_S0_CD_VALID,
+-              IRQ_S0_BVD1_STSCHG,
+-              IRQ_S1_READY_NINT,
+-              IRQ_S1_CD_VALID,
+-              IRQ_S1_BVD1_STSCHG,
++      {
++              .offset         = SA1111_KBD,
++              .skpcr_mask     = SKPCR_PTCLKEN,
++              .devid          = SA1111_DEVID_PS2,
++              .irq = {
++                      IRQ_TPRXINT,
++                      IRQ_TPTXINT
++              },
++      },
++      {
++              .offset         = SA1111_MSE,
++              .skpcr_mask     = SKPCR_PMCLKEN,
++              .devid          = SA1111_DEVID_PS2,
++              .irq = {
++                      IRQ_MSRXINT,
++                      IRQ_MSTXINT
++              },
++      },
++      {
++              .offset         = 0x1800,
++              .skpcr_mask     = 0,
++              .devid          = SA1111_DEVID_PCMCIA,
++              .irq = {
++                      IRQ_S0_READY_NINT,
++                      IRQ_S0_CD_VALID,
++                      IRQ_S0_BVD1_STSCHG,
++                      IRQ_S1_READY_NINT,
++                      IRQ_S1_CD_VALID,
++                      IRQ_S1_BVD1_STSCHG,
++              },
+       },
+-};
+-
+-static struct sa1111_dev *devs[] = {
+-      &usb_dev,
+-      &sac_dev,
+-      &ssp_dev,
+-      &kbd_dev,
+-      &mse_dev,
+-      &pcmcia_dev,
+-};
+-
+-static unsigned int dev_offset[] = {
+-      SA1111_USB,
+-      0x0600,
+-      0x0800,
+-      SA1111_KBD,
+-      SA1111_MSE,
+-      0x1800,
+ };
+ /*
+@@ -372,44 +360,45 @@
+       .wake           = sa1111_wake_highirq,
+ };
+-static void __init sa1111_init_irq(struct sa1111_dev *sadev)
++static void sa1111_setup_irq(struct sa1111 *sachip)
+ {
++      void *irqbase = sachip->base + SA1111_INTC;
+       unsigned int irq;
+       /*
+        * We're guaranteed that this region hasn't been taken.
+        */
+-      request_mem_region(sadev->res.start, 512, "irqs");
++      request_mem_region(sachip->phys + SA1111_INTC, 512, "irq");
+       /* disable all IRQs */
+-      sa1111_writel(0, sadev->mapbase + SA1111_INTEN0);
+-      sa1111_writel(0, sadev->mapbase + SA1111_INTEN1);
+-      sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN0);
+-      sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN1);
++      sa1111_writel(0, irqbase + SA1111_INTEN0);
++      sa1111_writel(0, irqbase + SA1111_INTEN1);
++      sa1111_writel(0, irqbase + SA1111_WAKEEN0);
++      sa1111_writel(0, irqbase + SA1111_WAKEEN1);
+       /*
+        * detect on rising edge.  Note: Feb 2001 Errata for SA1111
+        * specifies that S0ReadyInt and S1ReadyInt should be '1'.
+        */
+-      sa1111_writel(0, sadev->mapbase + SA1111_INTPOL0);
++      sa1111_writel(0, irqbase + SA1111_INTPOL0);
+       sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) |
+                     SA1111_IRQMASK_HI(IRQ_S1_READY_NINT),
+-                    sadev->mapbase + SA1111_INTPOL1);
++                    irqbase + SA1111_INTPOL1);
+       /* clear all IRQs */
+-      sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR0);
+-      sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR1);
++      sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
++      sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
+       for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
+               set_irq_chip(irq, &sa1111_low_chip);
+-              set_irq_chipdata(irq, sadev->mapbase);
++              set_irq_chipdata(irq, irqbase);
+               set_irq_handler(irq, do_edge_IRQ);
+               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+       }
+       for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
+               set_irq_chip(irq, &sa1111_high_chip);
+-              set_irq_chipdata(irq, sadev->mapbase);
++              set_irq_chipdata(irq, irqbase);
+               set_irq_handler(irq, do_edge_IRQ);
+               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+       }
+@@ -417,9 +406,9 @@
+       /*
+        * Register SA1111 interrupt
+        */
+-      set_irq_type(sadev->irq[0], IRQT_RISING);
+-      set_irq_data(sadev->irq[0], sadev->mapbase);
+-      set_irq_chained_handler(sadev->irq[0], sa1111_irq_handler);
++      set_irq_type(sachip->irq, IRQT_RISING);
++      set_irq_data(sachip->irq, irqbase);
++      set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
+ }
+ /*
+@@ -529,37 +518,64 @@
+ #endif
+-static void
++static void sa1111_dev_release(struct device *_dev)
++{
++      struct sa1111_dev *dev = SA1111_DEV(_dev);
++
++      release_resource(&dev->res);
++      kfree(dev);
++}
++
++static int
+ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
+-                    struct sa1111_dev *sadev, unsigned int offset)
++                    struct sa1111_dev_info *info)
+ {
+-      snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id),
+-               "%4.4x", offset);
++      struct sa1111_dev *dev;
++      int ret;
++
++      dev = kmalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
++      if (!dev) {
++              ret = -ENOMEM;
++              goto out;
++      }
++      memset(dev, 0, sizeof(struct sa1111_dev));
++
++      snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
++               "%4.4lx", info->offset);
+       /*
+        * If the parent device has a DMA mask associated with it,
+        * propagate it down to the children.
+        */
+       if (sachip->dev->dma_mask) {
+-              sadev->dma_mask = *sachip->dev->dma_mask;
+-              sadev->dev.dma_mask = &sadev->dma_mask;
++              dev->dma_mask = *sachip->dev->dma_mask;
++              dev->dev.dma_mask = &dev->dma_mask;
+       }
+-      sadev->dev.parent = sachip->dev;
+-      sadev->dev.bus    = &sa1111_bus_type;
+-      sadev->res.start  = sachip->phys + offset;
+-      sadev->res.end    = sadev->res.start + 511;
+-      sadev->res.name   = sadev->dev.bus_id;
+-      sadev->res.flags  = IORESOURCE_MEM;
+-      sadev->mapbase    = sachip->base + offset;
++      dev->devid       = info->devid;
++      dev->dev.parent  = sachip->dev;
++      dev->dev.bus     = &sa1111_bus_type;
++      dev->dev.release = sa1111_dev_release;
++      dev->res.start   = sachip->phys + info->offset;
++      dev->res.end     = dev->res.start + 511;
++      dev->res.name    = dev->dev.bus_id;
++      dev->res.flags   = IORESOURCE_MEM;
++      dev->mapbase     = sachip->base + info->offset;
+-      if (request_resource(parent, &sadev->res)) {
++      ret = request_resource(parent, &dev->res);
++      if (ret) {
+               printk("SA1111: failed to allocate resource for %s\n",
+-                      sadev->res.name);
+-              return;
++                      dev->res.name);
++              goto out;
+       }
+-      device_register(&sadev->dev);
++      ret = device_register(&dev->dev);
++      if (ret) {
++              release_resource(&dev->res);
++ out:
++              kfree(dev);
++      }
++      return ret;
+ }
+ /**
+@@ -655,11 +671,8 @@
+        * The interrupt controller must be initialised before any
+        * other device to ensure that the interrupts are available.
+        */
+-      if (irq != NO_IRQ) {
+-              int_dev.irq[0] = irq;
+-              sa1111_init_one_child(sachip, mem, &int_dev, SA1111_INTC);
+-              sa1111_init_irq(&int_dev);
+-      }
++      if (sachip->irq != NO_IRQ)
++              sa1111_setup_irq(sachip);
+       g_sa1111 = sachip;
+@@ -670,9 +683,9 @@
+       else
+               has_devs &= ~(1 << 1);
+-      for (i = 0; i < ARRAY_SIZE(devs); i++)
++      for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++)
+               if (has_devs & (1 << i))
+-                      sa1111_init_one_child(sachip, mem, devs[i], dev_offset[i]);
++                      sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
+       return 0;
+@@ -685,11 +698,26 @@
+ static void __sa1111_remove(struct sa1111 *sachip)
+ {
+-      int i;
++      struct list_head *l, *n;
++      void *irqbase = sachip->base + SA1111_INTC;
++
++      list_for_each_safe(l, n, &sachip->dev->children) {
++              struct device *d = list_to_dev(l);
+-      for (i = 0; i < ARRAY_SIZE(devs); i++) {
+-              put_device(&devs[i]->dev);
+-              release_resource(&devs[i]->res);
++              device_unregister(d);
++      }
++
++      /* disable all IRQs */
++      sa1111_writel(0, irqbase + SA1111_INTEN0);
++      sa1111_writel(0, irqbase + SA1111_INTEN1);
++      sa1111_writel(0, irqbase + SA1111_WAKEEN0);
++      sa1111_writel(0, irqbase + SA1111_WAKEEN1);
++
++      if (sachip->irq != NO_IRQ) {
++              set_irq_chained_handler(sachip->irq, NULL);
++              set_irq_data(sachip->irq, NULL);
++
++              release_mem_region(sachip->phys + SA1111_INTC, 512);
+       }
+       iounmap(sachip->base);
+@@ -958,17 +986,6 @@
+ };
+ /*
+- *    Register the SA1111 driver with LDM.
+- */
+-static int sa1111_driver_init(void)
+-{
+-      driver_register(&sa1111_device_driver);
+-      return 0;
+-}
+-
+-arch_initcall(sa1111_driver_init);
+-
+-/*
+  *    Get the parent device driver (us) structure
+  *    from a child function device
+  */
+@@ -1180,13 +1197,6 @@
+       .resume         = sa1111_bus_resume,
+ };
+-static int sa1111_rab_bus_init(void)
+-{
+-      return bus_register(&sa1111_bus_type);
+-}
+-
+-postcore_initcall(sa1111_rab_bus_init);
+-
+ int sa1111_driver_register(struct sa1111_driver *driver)
+ {
+       driver->drv.probe = sa1111_bus_probe;
+@@ -1200,6 +1210,26 @@
+       driver_unregister(&driver->drv);
+ }
++static int __init sa1111_init(void)
++{
++      int ret = bus_register(&sa1111_bus_type);
++      if (ret == 0)
++              driver_register(&sa1111_device_driver);
++      return ret;
++}
++
++static void __exit sa1111_exit(void)
++{
++      driver_unregister(&sa1111_device_driver);
++      bus_unregister(&sa1111_bus_type);
++}
++
++module_init(sa1111_init);
++module_exit(sa1111_exit);
++
++MODULE_DESCRIPTION("Intel Corporation SA1111 core driver");
++MODULE_LICENSE("GPL");
++
+ EXPORT_SYMBOL(sa1111_check_dma_bug);
+ EXPORT_SYMBOL(sa1111_select_audio_mode);
+ EXPORT_SYMBOL(sa1111_set_audio_rate);
+Index: linux-2.6.0-test5/arch/arm/common/sa1111-pcipool.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/common/sa1111-pcipool.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/common/sa1111-pcipool.c 2003-09-27 11:38:18.591702016 +0800
+@@ -51,7 +51,7 @@
+ static inline const char *slot_name(const struct pci_pool *pool)
+ {
+-      const struct pci_dev *pdev = pool->dev;
++      struct pci_dev *pdev = (struct pci_dev *)pool->dev;
+       if (pdev == 0)
+               return "[0]";
+Index: linux-2.6.0-test5/arch/arm/configs/a5k_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/a5k_defconfig      2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/a5k_defconfig   2003-09-27 11:38:18.592701864 +0800
+@@ -0,0 +1,526 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_SBUS is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_OBSOLETE=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ARCA5K=y
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++CONFIG_ARCH_A5K=y
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++CONFIG_ARCH_ACORN=y
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++# CONFIG_CPU_32 is not set
++CONFIG_CPU_26=y
++# CONFIG_PAGESIZE_16 is not set
++
++#
++# Processor Type
++#
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_ELF is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=m
++CONFIG_PARPORT_PC=m
++# CONFIG_PARPORT_PC_FIFO is not set
++CONFIG_PARPORT_PC_SUPERIO=y
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP 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_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Acorn-specific block devices
++#
++# CONFIG_BLK_DEV_FD1772 is not set
++CONFIG_BLK_DEV_MFM=m
++CONFIG_BLK_DEV_MFM_AUTODETECT=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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_ARM_ETHER1=y
++CONFIG_ARM_ETHER3=y
++# CONFIG_ARM_ETHERH 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
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# 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 is not set
++# CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++CONFIG_BLK_DEV_IDE_ICSIDE=y
++# CONFIG_BLK_DEV_IDEDMA_ICS is not set
++# CONFIG_IDEDMA_ICS_AUTO is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++# CONFIG_BLK_DEV_IDE_RAPIDE is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_UNIX98_PTYS is not set
++# CONFIG_PRINTER is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_ADFS_FS=y
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_ACORN_PARTITION=y
++CONFIG_ACORN_PARTITION_ADFS=y
++CONFIG_ACORN_PARTITION_ICS=y
++CONFIG_ACORN_PARTITION_POWERTEC=y
++CONFIG_ACORN_PARTITION_RISCIX=y
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_874 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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_8 is not set
++# CONFIG_NLS_ISO8859_9 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_UTF8 is not set
++
++#
++# Console drivers
++#
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_ACORN=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_MFB=y
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_NO_PGT_CACHE=y
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/adi_evb_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/adi_evb_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/adi_evb_defconfig       2003-09-27 11:38:18.593701712 +0800
+@@ -0,0 +1,681 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++CONFIG_ARCH_ADIFCC=y
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++CONFIG_ARCH_ADI_EVB=y
++CONFIG_XSCALE_PMU_TIMER=y
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++# CONFIG_CPU_32v4 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_XSCALE=y
++CONFIG_ARM_THUMB=y
++# CONFIG_XSCALE_TOOLS is not set
++CONFIG_XSCALE_WRITE_ALLOC=y
++CONFIG_XSCALE_PMU=y
++CONFIG_ARM_THUMB=y
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/mtdblock1 mem=32M initrd=0xc0800000,3M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++CONFIG_MTD_ADI_EVB=y
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE 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
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE 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_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_HPUSBSCSI is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_SLAB=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/adsbitsy_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/adsbitsy_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/adsbitsy_defconfig      2003-09-27 11:38:18.595701408 +0800
+@@ -0,0 +1,664 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++CONFIG_SA1100_ADSBITSY=y
++CONFIG_SA1111=y
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=off mem=32M root=/dev/ram ramdisk=8192 initrd=0xc0800000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE 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
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_AUDIO_UCB1200=y
++CONFIG_ADC_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=y
++CONFIG_USB_OHCI_NOPCI=y
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_HID is not set
++# CONFIG_USB_KBD is not set
++CONFIG_USB_MOUSE=y
++# CONFIG_USB_WACOM is not set
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_PWC is not set
++# CONFIG_USB_SE401 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_NET1080 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/anakin_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/anakin_defconfig   2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/anakin_defconfig        2003-09-27 11:38:18.596701256 +0800
+@@ -0,0 +1,632 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++CONFIG_ARCH_ANAKIN=y
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_32v5 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++CONFIG_CPU_SA110=y
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_CPU_XSCALE is not set
++# CONFIG_XSCALE_PMU is not set
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++# CONFIG_DISCONTIGMEM is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/ram initrd=0xc0800000,4M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++
++#
++# Appletalk devices
++#
++# CONFIG_DEV_APPLETALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++# CONFIG_NETDEVICES is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=y
++
++#
++# IrDA protocols
++#
++# CONFIG_IRLAN is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++
++#
++# IrDA options
++#
++# CONFIG_IRDA_CACHE_LAST_LSAP is not set
++# CONFIG_IRDA_FAST_RR is not set
++# CONFIG_IRDA_DEBUG is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=y
++# CONFIG_IRPORT_SIR is not set
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++
++#
++# ARM Serial drivers
++#
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++CONFIG_SERIAL_ANAKIN=y
++CONFIG_SERIAL_ANAKIN_CONSOLE=y
++CONFIG_ANAKIN_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_TOUCHSCREEN_ANAKIN=y
++# CONFIG_UNIX98_PTYS is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++# CONFIG_QIFACE_COMPAT is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE 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_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_TCP is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_EXPORTFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++CONFIG_FB_ANAKIN=y
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_SA1100 is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++# CONFIG_ZLIB_INFLATE is not set
++# CONFIG_ZLIB_DEFLATE is not set
+Index: linux-2.6.0-test5/arch/arm/configs/assabet_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/assabet_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/assabet_defconfig       2003-09-27 11:38:18.598700952 +0800
+@@ -0,0 +1,966 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++CONFIG_SA1100_ASSABET=y
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=32M console=ttySA0,38400n8 initrd=0xc0800000,3M root=/dev/ram"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE 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
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++# CONFIG_IRNET is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=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 is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++CONFIG_PCMCIA_SERIAL_CS=m
++# CONFIG_MWAVE is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++CONFIG_TMPFS=y
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++CONFIG_SOUND_SA1100=y
++CONFIG_SOUND_UDA1341=y
++CONFIG_SOUND_ASSABET_UDA1341=y
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++CONFIG_MCP_UCB1200=y
++CONFIG_MCP_UCB1200_AUDIO=m
++CONFIG_MCP_UCB1200_TS=y
++
++#
++# Console Switches
++#
++CONFIG_SWITCHES=y
++CONFIG_SWITCHES_SA1100=y
++CONFIG_SWITCHES_UCB1X00=y
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/badge4_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/badge4_defconfig   2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/badge4_defconfig        2003-09-27 11:38:18.601700496 +0800
+@@ -0,0 +1,1162 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODVERSIONS=y
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++CONFIG_SA1100_BADGE4=y
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_XSCALE_PMU is not set
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++CONFIG_PCMCIA_PROBE=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=m
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=m
++CONFIG_BINFMT_ELF=y
++CONFIG_BINFMT_MISC=m
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++CONFIG_ARTHUR=m
++CONFIG_CMDLINE="init=/linuxrc root=/dev/mtdblock3"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=m
++# CONFIG_PARPORT_PC is not set
++# CONFIG_PARPORT_ARC is not set
++# 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 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=0
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++CONFIG_MTD_CFI_B2=y
++# CONFIG_MTD_CFI_B4 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_RAM=y
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_2PARTS_IPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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=y
++# CONFIG_STRIP is not set
++# CONFIG_ARLAN is not set
++# CONFIG_AIRONET4500 is not set
++# CONFIG_AIRONET4500_NONCS is not set
++# CONFIG_AIRONET4500_PROC is not set
++
++#
++# Wireless ISA/PCI cards support
++#
++# CONFIG_WAVELAN is not set
++# CONFIG_AIRO is not set
++CONFIG_HERMES=y
++
++#
++# Wireless Pcmcia/Cardbus cards support
++#
++CONFIG_PCMCIA_NETWAVE=m
++CONFIG_PCMCIA_WAVELAN=m
++CONFIG_PCMCIA_HERMES=y
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++CONFIG_PCMCIA_3C589=y
++CONFIG_PCMCIA_3C574=m
++CONFIG_PCMCIA_FMVJ18X=m
++CONFIG_PCMCIA_PCNET=y
++CONFIG_PCMCIA_NMCLAN=m
++CONFIG_PCMCIA_SMC91C92=m
++CONFIG_PCMCIA_XIRC2PS=m
++CONFIG_PCMCIA_AXNET=m
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++CONFIG_PCMCIA_RAYCS=m
++# CONFIG_AIRONET4500_CS is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=y
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=y
++# CONFIG_IRNET is not set
++CONFIG_IRCOMM=y
++CONFIG_IRDA_ULTRA=y
++
++#
++# IrDA options
++#
++# CONFIG_IRDA_CACHE_LAST_LSAP is not set
++# CONFIG_IRDA_FAST_RR is not set
++# CONFIG_IRDA_DEBUG is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=y
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++# CONFIG_BLK_DEV_IDECS is not set
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++CONFIG_BLK_DEV_IDEFLOPPY=m
++CONFIG_BLK_DEV_IDESCSI=m
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++CONFIG_SCSI=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++CONFIG_SD_EXTRA_DEVS=40
++CONFIG_CHR_DEV_ST=m
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=m
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++CONFIG_SR_EXTRA_DEVS=2
++CONFIG_CHR_DEV_SG=y
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++
++#
++# SCSI low-level drivers
++#
++# 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_AHA1740 is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_IN2000 is not set
++# CONFIG_SCSI_AM53C974 is not set
++# CONFIG_SCSI_MEGARAID is not set
++# CONFIG_SCSI_BUSLOGIC is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_DTC3280 is not set
++# CONFIG_SCSI_EATA is not set
++# CONFIG_SCSI_EATA_DMA 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_INITIO 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_NCR53C7xx is not set
++# CONFIG_SCSI_PAS16 is not set
++# CONFIG_SCSI_PCI2000 is not set
++# CONFIG_SCSI_PCI2220I is not set
++# CONFIG_SCSI_PSI240I is not set
++# CONFIG_SCSI_QLOGIC_FAS is not set
++# CONFIG_SCSI_SIM710 is not set
++# CONFIG_SCSI_SYM53C416 is not set
++# CONFIG_SCSI_T128 is not set
++# CONFIG_SCSI_U14_34F is not set
++# CONFIG_SCSI_DEBUG is not set
++
++#
++# PCMCIA SCSI adapter support
++#
++# CONFIG_SCSI_PCMCIA is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++# CONFIG_PRINTER is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_PHILIPSPAR is not set
++CONFIG_I2C_ELV=m
++CONFIG_I2C_VELLEMAN=m
++# CONFIG_I2C_BIT_SA1100_GPIO is not set
++CONFIG_I2C_ALGOPCF=m
++CONFIG_I2C_ELEKTOR=m
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_PROC=m
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++CONFIG_L3_SA1111=y
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++CONFIG_SOFT_WATCHDOG=m
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++# CONFIG_21285_WATCHDOG is not set
++# CONFIG_977_WATCHDOG is not set
++CONFIG_SA1100_WATCHDOG=m
++# CONFIG_EUROTECH_WDT is not set
++# CONFIG_IB700_WDT is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_W83877F_WDT is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++CONFIG_RTC=m
++CONFIG_SA1100_RTC=m
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++
++#
++# Video For Linux
++#
++CONFIG_VIDEO_PROC_FS=y
++# CONFIG_I2C_PARPORT is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_BT848 is not set
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_BWQCAM is not set
++# CONFIG_VIDEO_CQCAM is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_SAA5249 is not set
++# CONFIG_TUNER_3036 is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_ZORAN is not set
++# CONFIG_VIDEO_ZORAN_BUZ is not set
++# CONFIG_VIDEO_ZORAN_DC10 is not set
++# CONFIG_VIDEO_ZORAN_LML33 is not set
++# CONFIG_VIDEO_ZR36120 is not set
++# CONFIG_VIDEO_MEYE is not set
++# CONFIG_VIDEO_CYBERPRO is not set
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_CADET is not set
++# CONFIG_RADIO_RTRACK is not set
++# CONFIG_RADIO_RTRACK2 is not set
++# CONFIG_RADIO_AZTECH is not set
++# CONFIG_RADIO_GEMTEK is not set
++# CONFIG_RADIO_GEMTEK_PCI is not set
++# CONFIG_RADIO_MAXIRADIO is not set
++# CONFIG_RADIO_MAESTRO is not set
++# CONFIG_RADIO_MIROPCM20 is not set
++# CONFIG_RADIO_MIROPCM20_RDS is not set
++# CONFIG_RADIO_SF16FMI is not set
++# CONFIG_RADIO_TERRATEC is not set
++# CONFIG_RADIO_TRUST is not set
++# CONFIG_RADIO_TYPHOON is not set
++# CONFIG_RADIO_ZOLTRIX is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_EXT3_FS=m
++CONFIG_JBD=m
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=m
++CONFIG_TMPFS=y
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++CONFIG_MINIX_FS=m
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW 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 is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=m
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 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 is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++CONFIG_SMB_NLS=y
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++CONFIG_SOUND_SA1100=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++CONFIG_SOUND_SA1111_UDA1341=y
++# CONFIG_SOUND_STORK_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_STORK_AC97 is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_LONG_TIMEOUT is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++CONFIG_USB_OHCI_SA1111=y
++
++#
++# USB Device Class drivers
++#
++CONFIG_USB_AUDIO=y
++CONFIG_USB_BLUETOOTH=m
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# 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_JUMPSHOT is not set
++CONFIG_USB_ACM=m
++CONFIG_USB_PRINTER=m
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++CONFIG_USB_DC2XX=m
++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_OV511=m
++CONFIG_USB_PWC=m
++CONFIG_USB_SE401=m
++# CONFIG_USB_STV680 is not set
++CONFIG_USB_VICAM=m
++CONFIG_USB_DSBR=m
++CONFIG_USB_DABUSB=m
++CONFIG_USB_KONICAWC=m
++
++#
++# USB Network adaptors
++#
++CONFIG_USB_PEGASUS=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_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 is not set
++CONFIG_USB_SERIAL_IR=m
++CONFIG_USB_SERIAL_EDGEPORT=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 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++CONFIG_USB_SERIAL_MCT_U232=m
++# CONFIG_USB_SERIAL_KLSI is not set
++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 is not set
++
++#
++# Bluetooth support
++#
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIUSB=m
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIVHCI=m
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/brutus_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/brutus_defconfig   2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/brutus_defconfig        2003-09-27 11:38:18.601700496 +0800
+@@ -0,0 +1,296 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_SBUS is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++CONFIG_SA1100_BRUTUS=y
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_THINCLIENT is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++CONFIG_ANGELBOOT=y
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_PC_KEYMAP=y
++
++#
++# General setup
++#
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++# CONFIG_NET is not set
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=4M@0xc0000000 mem=4M@0xc8000000 mem=4M@0xd0000000 mem=4M@0xd8000000 keepinitrd root=/dev/ram ramdisk=8192 initrd=0xd8000000,3M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_PARIDE is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_LVM is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_BLK_DEV_FLASH is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++# CONFIG_NCPFS_NLS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_LL is not set
+Index: linux-2.6.0-test5/arch/arm/configs/cerfcube_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/cerfcube_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/cerfcube_defconfig      2003-09-27 11:38:18.603700192 +0800
+@@ -0,0 +1,873 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_CERF=y
++# CONFIG_SA1100_CERF_FLASH_8MB is not set
++CONFIG_SA1100_CERF_FLASH_16MB=y
++# CONFIG_SA1100_CERF_FLASH_32MB is not set
++# CONFIG_SA1100_CERF_CPLD is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++CONFIG_SA1100_USB_CHAR=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0 root=/dev/mtdblock3 rw mem=32M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++CONFIG_FILTER=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++CONFIG_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_CERF_CS8900A=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# 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 is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++# CONFIG_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_H3600 is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_UCB1200 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++CONFIG_AUTOFS_FS=y
++CONFIG_AUTOFS4_FS=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_UMSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT 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_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/cerfpda_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/cerfpda_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/cerfpda_defconfig       2003-09-27 11:38:18.605699888 +0800
+@@ -0,0 +1,967 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_CERF=y
++# CONFIG_SA1100_CERF_FLASH_8MB is not set
++# CONFIG_SA1100_CERF_FLASH_16MB is not set
++CONFIG_SA1100_CERF_FLASH_32MB=y
++CONFIG_SA1100_CERF_CPLD=y
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++CONFIG_SA1100_USB_CHAR=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0 cpufreq_max=221200 root=/dev/mtdblock3 rw mem=64M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++CONFIG_FILTER=y
++CONFIG_UNIX=y
++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_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++CONFIG_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_CERF_CS8900A=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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=y
++CONFIG_STRIP=m
++CONFIG_WAVELAN=m
++CONFIG_ARLAN=m
++CONFIG_AIRONET4500=m
++CONFIG_AIRONET4500_NONCS=m
++# CONFIG_AIRONET4500_PNP is not set
++# CONFIG_AIRONET4500_PCI is not set
++# CONFIG_AIRONET4500_ISA is not set
++# CONFIG_AIRONET4500_I365 is not set
++CONFIG_AIRONET4500_PROC=m
++
++#
++# Wireless Pcmcia cards support
++#
++CONFIG_PCMCIA_HERMES=m
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# 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_NMCLAN=m
++CONFIG_PCMCIA_SMC91C92=m
++CONFIG_PCMCIA_XIRC2PS=m
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++CONFIG_PCMCIA_RAYCS=m
++CONFIG_PCMCIA_NETWAVE=m
++CONFIG_PCMCIA_WAVELAN=m
++CONFIG_AIRONET4500_CS=m
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# 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 is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=y
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_CERF_TS_MANUAL=y
++CONFIG_CERF_TS_MAXX="924"
++CONFIG_CERF_TS_MAXY="920"
++CONFIG_CERF_TS_MINX="57"
++CONFIG_CERF_TS_MINY="52"
++CONFIG_CERF_TS_RESX="240"
++CONFIG_CERF_TS_RESY="320"
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_H3600 is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++CONFIG_SA1100_CERF_KEYPAD=y
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_UCB1200 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_UMSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++CONFIG_CERF_LCD_38_A=y
++# CONFIG_CERF_LCD_57_A is not set
++# CONFIG_CERF_LCD_72_A is not set
++CONFIG_SA1100_CERF_LCD_BACKLIGHT=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++CONFIG_SOUND_CERF_UDA1341=y
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT 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_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++CONFIG_BT=y
++CONFIG_BT_L2CAP=y
++
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIUSB is not set
++CONFIG_BT_HCIUART=y
++# CONFIG_BT_HCIVHCI is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/cerfpod_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/cerfpod_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/cerfpod_defconfig       2003-09-27 11:38:18.607699584 +0800
+@@ -0,0 +1,894 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_CERF=y
++# CONFIG_SA1100_CERF_FLASH_8MB is not set
++CONFIG_SA1100_CERF_FLASH_16MB=y
++# CONFIG_SA1100_CERF_FLASH_32MB is not set
++# CONFIG_SA1100_CERF_CPLD is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++CONFIG_SA1100_USB_CHAR=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0 root=/dev/mtdblock3 rw mem=32M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++CONFIG_FILTER=y
++CONFIG_UNIX=y
++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_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++CONFIG_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_CERF_CS8900A=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# 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 is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_CERF_TS_MANUAL is not set
++CONFIG_AUDIO_UCB1200=y
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_H3600 is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_UCB1200 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# 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_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_UMSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_CERF_LCD_38_A is not set
++CONFIG_CERF_LCD_57_A=y
++# CONFIG_CERF_LCD_72_A is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT 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_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/clps7500_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/clps7500_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/clps7500_defconfig      2003-09-27 11:38:18.608699432 +0800
+@@ -0,0 +1,520 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_OBSOLETE=y
++
++#
++# Loadable module support
++#
++# CONFIG_MODULES is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++CONFIG_ARCH_CLPS7500=y
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FTVPCI is not set
++# CONFIG_ARCH_TBOX is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32v3=y
++# CONFIG_CPU_32v4 is not set
++# CONFIG_CPU_ARM610 is not set
++CONFIG_CPU_ARM710=y
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++CONFIG_ANGELBOOT=y
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=16M root=nfs"
++# CONFIG_ALIGNMENT_TRAP is not set
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_FIFO=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++CONFIG_PARPORT_1284=y
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PMC551_BUGFIX is not set
++# CONFIG_MTD_PMC551_DEBUG is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Drivers for chip mappings
++#
++
++#
++# User modules and translation layers for MTD devices
++#
++# CONFIG_MTD_CHAR is not set
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_PARIDE is not set
++# CONFIG_BLK_DEV_LOOP is not set
++CONFIG_BLK_DEV_NBD=y
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_BLK_DEV_FLD7500 is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++CONFIG_DUMMY=y
++# 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_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
++# 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_AC3200 is not set
++# CONFIG_APRICOT is not set
++CONFIG_CS89x0=y
++# CONFIG_ZNET is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP 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=y
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++# CONFIG_ASH is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=y
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# Mice
++#
++CONFIG_BUSMOUSE=y
++# CONFIG_ATIXL_BUSMOUSE is not set
++# CONFIG_LOGIBUSMOUSE is not set
++# CONFIG_MS_BUSMOUSE is not set
++CONFIG_MOUSE=y
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++
++#
++# Game port support
++#
++
++#
++# Gameport joysticks
++#
++
++#
++# Serial port support
++#
++
++#
++# Serial port joysticks
++#
++
++#
++# Parallel port joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++CONFIG_CLPS7500_FLASH=y
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++CONFIG_MINIX_FS=y
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYB=y
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_ACORN=y
++# CONFIG_CHRONTEL_7003 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++CONFIG_FBCON_MFB=y
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_FRAME_POINTER is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/ebsa110_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/ebsa110_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/ebsa110_defconfig       2003-09-27 11:38:18.609699280 +0800
+@@ -0,0 +1,605 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++CONFIG_ARCH_EBSA110=y
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_ANAKIN is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++CONFIG_CPU_SA110=y
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++CONFIG_I82365=y
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++# CONFIG_PCMCIA_SA1100 is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_FIFO=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_PC_PCMCIA is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI 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 is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_RTNETLINK=y
++CONFIG_NETLINK=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_ROUTE_FWMARK=y
++CONFIG_IP_ROUTE_NAT=y
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_TOS is not set
++CONFIG_IP_ROUTE_VERBOSE=y
++# CONFIG_IP_ROUTE_LARGE_TABLES is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_INET_ECN=y
++CONFIG_SYN_COOKIES=y
++
++#
++#   IP: Netfilter Configuration
++#
++CONFIG_IP_NF_CONNTRACK=y
++CONFIG_IP_NF_FTP=y
++CONFIG_IP_NF_IRC=y
++# CONFIG_IP_NF_QUEUE is not set
++CONFIG_IP_NF_IPTABLES=y
++CONFIG_IP_NF_MATCH_LIMIT=y
++# CONFIG_IP_NF_MATCH_MAC is not set
++CONFIG_IP_NF_MATCH_MARK=y
++CONFIG_IP_NF_MATCH_MULTIPORT=y
++CONFIG_IP_NF_MATCH_TOS=y
++# CONFIG_IP_NF_MATCH_TCPMSS is not set
++CONFIG_IP_NF_MATCH_STATE=y
++CONFIG_IP_NF_MATCH_UNCLEAN=y
++# CONFIG_IP_NF_MATCH_OWNER is not set
++CONFIG_IP_NF_FILTER=y
++CONFIG_IP_NF_TARGET_REJECT=y
++# CONFIG_IP_NF_TARGET_MIRROR is not set
++CONFIG_IP_NF_NAT=y
++CONFIG_IP_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=y
++CONFIG_IP_NF_TARGET_REDIRECT=y
++CONFIG_IP_NF_NAT_IRC=y
++CONFIG_IP_NF_NAT_FTP=y
++CONFIG_IP_NF_MANGLE=y
++CONFIG_IP_NF_TARGET_TOS=y
++CONFIG_IP_NF_TARGET_MARK=y
++CONFIG_IP_NF_TARGET_LOG=y
++# CONFIG_IP_NF_TARGET_TCPMSS is not set
++CONFIG_IPV6=y
++
++#
++#   IPv6: Netfilter Configuration
++#
++CONFIG_IP6_NF_IPTABLES=y
++CONFIG_IP6_NF_MATCH_LIMIT=y
++CONFIG_IP6_NF_MATCH_MARK=y
++CONFIG_IP6_NF_FILTER=y
++CONFIG_IP6_NF_MANGLE=y
++CONFIG_IP6_NF_TARGET_MARK=y
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++# CONFIG_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_ARM_AM79C961A=y
++# 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
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++CONFIG_SERIAL_EXTENDED=y
++# CONFIG_SERIAL_MANY_PORTS is not set
++# CONFIG_SERIAL_SHARE_IRQ is not set
++# CONFIG_SERIAL_DETECT_IRQ is not set
++# CONFIG_SERIAL_MULTIPORT is not set
++# CONFIG_HUB6 is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++CONFIG_SOFT_WATCHDOG=y
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++CONFIG_MINIX_FS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# CONFIG_EXT2_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/edb7211_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/edb7211_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/edb7211_defconfig       2003-09-27 11:38:18.610699128 +0800
+@@ -0,0 +1,401 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++# CONFIG_MODULES is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++CONFIG_ARCH_CLPS711X=y
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++CONFIG_ARCH_EDB7211=y
++CONFIG_EP7211_BOOT_MODE=y
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++CONFIG_ARCH_EP7211=y
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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 is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_CLPS711X=y
++CONFIG_SERIAL_CLPS711X_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++CONFIG_MINIX_FS=y
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/empeg_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/empeg_defconfig    2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/empeg_defconfig 2003-09-27 11:38:18.611698976 +0800
+@@ -0,0 +1,265 @@
++#
++#
++# Example empeg-car kernel configuration file.
++#
++CONFIG_ARM=y
++
++#
++# System and processor type
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_FOOTBRIDGE is not set
++CONFIG_ARCH_SA1100=y
++CONFIG_CPU_SA1100=y
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_EMPEG=y
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_EMPEG_HENRY is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_ARM2 is not set
++# CONFIG_CPU_ARM3 is not set
++# CONFIG_CPU_ARM6 is not set
++# CONFIG_CPU_ARM7 is not set
++CONFIG_CPU_SA110=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_ALIGNMENT_TRAP is not set
++# CONFIG_TEXT_SECTIONS is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODVERSIONS=y
++# CONFIG_KMOD is not set
++
++#
++# General setup
++#
++CONFIG_NET=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++CONFIG_NWFPE=y
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++# CONFIG_PARPORT is not set
++CONFIG_CMDLINE="mem=4M@0xc0000000 mem=4M@0xc8000000 root=/dev/hda1 initrd=0xd00b0000,320K"
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_MD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_BLK_DEV_XD is not set
++CONFIG_PARIDE_PARPORT=y
++# CONFIG_PARIDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_UNIX98_PTYS is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_EMPEG_IR=y
++CONFIG_EMPEG_USB=y
++
++#
++# Video For Linux
++#
++CONFIG_VIDEO_DEV=y
++# CONFIG_RADIO_RTRACK is not set
++# CONFIG_RADIO_RTRACK2 is not set
++# CONFIG_RADIO_AZTECH is not set
++# CONFIG_RADIO_CADET is not set
++# CONFIG_RADIO_MIROPCM20 is not set
++# CONFIG_RADIO_GEMTEK is not set
++CONFIG_RADIO_EMPEG=y
++# CONFIG_VIDEO_BT848 is not set
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_SAA5249 is not set
++# CONFIG_RADIO_SF16FMI is not set
++# CONFIG_RADIO_TYPHOON is not set
++# CONFIG_RADIO_ZOLTRIX is not set
++
++#
++# Joystick support
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_DTLK is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_FIREWALL is not set
++# CONFIG_FILTER is not set
++# CONFIG_UNIX is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP is not set
++# CONFIG_IP_ROUTER is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_ALIAS is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_RARP is not set
++# CONFIG_SKB_LARGE is not set
++# CONFIG_IPV6 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_LLC 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
++# CONFIG_CPU_IS_SLOW is not set
++
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA subsystem support
++#
++# CONFIG_IRDA is not set
++
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_NET_ETHERNET is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_DLCI is not set
++CONFIG_PPP=y
++# CONFIG_SLIP is not set
++# CONFIG_NET_RADIO is not set
++# CONFIG_TR is not set
++# CONFIG_SHAPER is not set
++# CONFIG_HOSTESS_SV11 is not set
++# CONFIG_COSA is not set
++# CONFIG_RCPCI is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# Filesystems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFSD is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_NLS is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_USER_BACKTRACE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_LL is not set
+Index: linux-2.6.0-test5/arch/arm/configs/epxa10db_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/epxa10db_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/epxa10db_defconfig      2003-09-27 11:38:18.612698824 +0800
+@@ -0,0 +1,566 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++CONFIG_ARCH_CAMELOT=y
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# PLD hotswap support
++#
++CONFIG_PLD=y
++# CONFIG_PLD_HOTSWAP is not set
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM922T=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++
++#
++# General setup
++#
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=32M console=ttyUA0,38400 root=/dev/mtdblock0 rw"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=0
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_CONCAT is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_EPXA10DB=y
++# CONFIG_MTD_EDB7312 is not set
++# CONFIG_MTD_UCLINUX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD 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_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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_XFRM_USER is not set
++# CONFIG_IPV6 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_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
++# 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
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_ETHER00=m
++
++#
++# Ethernet (1000 Mbit)
++#
++CONFIG_PPP=y
++CONFIG_PPP_MULTILINK=y
++CONFIG_PPP_ASYNC=y
++CONFIG_PPP_SYNC_TTY=y
++# CONFIG_PPP_DEFLATE is not set
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Token Ring devices (depends on LLC=y)
++#
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Userland interfaces
++#
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_SERIO is not set
++
++#
++# Input Device Drivers
++#
++
++#
++# Character devices
++#
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_UART00=y
++CONFIG_SERIAL_UART00_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 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_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
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# 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 is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++CONFIG_TMPFS=y
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# 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 is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++CONFIG_ROMFS_FS=y
++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=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_GSS is not set
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++# CONFIG_MDA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_KERNEL is not set
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/flexanet_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/flexanet_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/flexanet_defconfig      2003-09-27 11:38:18.614698520 +0800
+@@ -0,0 +1,900 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++CONFIG_SA1100_FLEXANET=y
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=y
++CONFIG_SA1100_USB_NETLINK=y
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=64M root=/dev/ram initrd=0xc0800000,3M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++# CONFIG_MTD_CHAR is not set
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL 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 is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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=y
++# CONFIG_STRIP is not set
++# CONFIG_WAVELAN is not set
++# CONFIG_ARLAN is not set
++# CONFIG_AIRONET4500 is not set
++# CONFIG_AIRONET4500_NONCS is not set
++# CONFIG_AIRONET4500_PROC is not set
++# CONFIG_AIRO is not set
++CONFIG_HERMES=m
++
++#
++# Wireless Pcmcia cards support
++#
++CONFIG_PCMCIA_HERMES=m
++# CONFIG_AIRO_CS is not set
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# 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 is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=57600
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++# CONFIG_SOUND_SA1100 is not set
++# CONFIG_SOUND_UDA1341 is not set
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/footbridge_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/footbridge_defconfig       2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/footbridge_defconfig    2003-09-27 11:38:18.615698368 +0800
+@@ -0,0 +1,880 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++CONFIG_ARCH_FOOTBRIDGE=y
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++CONFIG_ARCH_EBSA285_HOST=y
++CONFIG_ARCH_NETWINDER=y
++
++#
++# SA11x0 Implementations
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++CONFIG_FOOTBRIDGE=y
++CONFIG_FOOTBRIDGE_HOST=y
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_ARCH_EBSA285=y
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA110=y
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++CONFIG_PCI=y
++CONFIG_ISA=y
++CONFIG_ISA_DMA=y
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++# CONFIG_LEDS_CPU is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++CONFIG_PARPORT=y
++CONFIG_PARPORT_PC=y
++CONFIG_PARPORT_PC_FIFO=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_AMIGA is not set
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_ATARI is not set
++# CONFIG_PARPORT_SUNBPP is not set
++# CONFIG_PARPORT_OTHER is not set
++CONFIG_PARPORT_1284=y
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++CONFIG_PNP=y
++CONFIG_ISAPNP=y
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++CONFIG_PARIDE=m
++CONFIG_PARIDE_PARPORT=y
++
++#
++# 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_COMM=m
++CONFIG_PARIDE_DSTR=m
++CONFIG_PARIDE_FIT2=m
++CONFIG_PARIDE_FIT3=m
++CONFIG_PARIDE_EPAT=m
++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 is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++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
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_INET_ECN is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++CONFIG_ATM=y
++# CONFIG_ATM_CLIP is not set
++# CONFIG_ATM_LANE is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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_NET_VENDOR_3COM=y
++# CONFIG_EL1 is not set
++# CONFIG_EL2 is not set
++# CONFIG_ELPLUS is not set
++# CONFIG_EL16 is not set
++# CONFIG_EL3 is not set
++# CONFIG_3C515 is not set
++# CONFIG_ELMC is not set
++# CONFIG_ELMC_II is not set
++CONFIG_VORTEX=y
++# CONFIG_LANCE is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL 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_ADAPTEC_STARFIRE is not set
++# CONFIG_AC3200 is not set
++# CONFIG_APRICOT is not set
++# CONFIG_CS89x0 is not set
++CONFIG_TULIP=m
++# CONFIG_DE4X5 is not set
++# CONFIG_DGRS is not set
++# CONFIG_DM9102 is not set
++# CONFIG_EEPRO100 is not set
++# CONFIG_EEPRO100_PM is not set
++# CONFIG_LNE390 is not set
++# CONFIG_NATSEMI is not set
++CONFIG_NE2K_PCI=y
++# CONFIG_NE3210 is not set
++# CONFIG_ES3210 is not set
++# CONFIG_8139TOO is not set
++# CONFIG_RTL8129 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_WINBOND_840 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++CONFIG_PPPOE=m
++CONFIG_SLIP=m
++CONFIG_SLIP_COMPRESSED=y
++CONFIG_SLIP_SMART=y
++CONFIG_SLIP_MODE_SLIP6=y
++
++#
++# 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++CONFIG_IRDA_OPTIONS=y
++
++#
++#   IrDA options
++#
++CONFIG_IRDA_CACHE_LAST_LSAP=y
++CONFIG_IRDA_FAST_RR=y
++CONFIG_IRDA_DEBUG=y
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++CONFIG_WINBOND_FIR=m
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# 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_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_BLK_DEV_RZ1000 is not set
++CONFIG_IDEPCI_SHARE_IRQ=y
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++CONFIG_BLK_DEV_OFFBOARD=y
++CONFIG_IDEDMA_PCI_AUTO=y
++CONFIG_BLK_DEV_IDEDMA=y
++# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_AEC62XX_TUNING is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++# CONFIG_WDC_ALI15X3 is not set
++# CONFIG_BLK_DEV_AMD7409 is not set
++# CONFIG_AMD7409_OVERRIDE is not set
++# CONFIG_BLK_DEV_CMD64X is not set
++CONFIG_BLK_DEV_CY82C693=y
++# CONFIG_BLK_DEV_CS5530 is not set
++# CONFIG_BLK_DEV_HPT34X is not set
++# CONFIG_HPT34X_AUTODMA is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_NS87415 is not set
++# CONFIG_BLK_DEV_OPTI621 is not set
++# CONFIG_PDC202XX_BURST is not set
++# CONFIG_BLK_DEV_OSB4 is not set
++# CONFIG_BLK_DEV_SIS5513 is not set
++# CONFIG_BLK_DEV_TRM290 is not set
++# CONFIG_BLK_DEV_VIA82CXXX is not set
++CONFIG_BLK_DEV_SL82C105=y
++# CONFIG_IDE_CHIPSETS is not set
++CONFIG_IDEDMA_AUTO=y
++# CONFIG_IDEDMA_IVB is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_PCI is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_SERIAL_EXTENDED is not set
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_COMPUTONE is not set
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
++# CONFIG_DIGI is not set
++# CONFIG_ESPSERIAL is not set
++# CONFIG_MOXA_INTELLIO is not set
++# CONFIG_MOXA_SMARTIO is not set
++# CONFIG_ISI is not set
++# CONFIG_SYNCLINK is not set
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_SX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++CONFIG_SERIAL_21285=y
++CONFIG_SERIAL_21285_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++CONFIG_SOFT_WATCHDOG=y
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_I810_TCO is not set
++CONFIG_21285_WATCHDOG=m
++CONFIG_977_WATCHDOG=m
++CONFIG_DS1620=y
++CONFIG_NWBUTTON=y
++CONFIG_NWBUTTON_REBOOT=y
++CONFIG_NWFLASH=m
++# CONFIG_INTEL_RNG is not set
++CONFIG_NVRAM=m
++CONFIG_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=m
++
++#
++# Video For Linux
++#
++CONFIG_VIDEO_PROC_FS=y
++# CONFIG_I2C_PARPORT is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_BWQCAM is not set
++# CONFIG_VIDEO_CQCAM is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_SAA5249 is not set
++# CONFIG_TUNER_3036 is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_ZORAN is not set
++# CONFIG_VIDEO_BUZ is not set
++# CONFIG_VIDEO_ZR36120 is not set
++CONFIG_VIDEO_CYBERPRO=m
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_CADET is not set
++# CONFIG_RADIO_RTRACK is not set
++# CONFIG_RADIO_RTRACK2 is not set
++# CONFIG_RADIO_AZTECH is not set
++# CONFIG_RADIO_GEMTEK is not set
++# CONFIG_RADIO_MAESTRO is not set
++# CONFIG_RADIO_MIROPCM20 is not set
++# CONFIG_RADIO_SF16FMI is not set
++# CONFIG_RADIO_TERRATEC is not set
++# CONFIG_RADIO_TRUST is not set
++# CONFIG_RADIO_TYPHOON is not set
++# CONFIG_RADIO_ZOLTRIX is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++CONFIG_ADFS_FS=m
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=m
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++CONFIG_ACORN_PARTITION=y
++# CONFIG_ACORN_PARTITION_ICS is not set
++CONFIG_ACORN_PARTITION_ADFS=y
++# CONFIG_ACORN_PARTITION_POWERTEC is not set
++# CONFIG_ACORN_PARTITION_RISCIX is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=m
++CONFIG_NLS_CODEPAGE_852=m
++# CONFIG_NLS_CODEPAGE_855 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_874 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++CONFIG_NLS_ISO8859_1=m
++CONFIG_NLS_ISO8859_2=m
++# 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_8 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++CONFIG_NLS_ISO8859_15=m
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_UTF8 is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYB=y
++CONFIG_PC_KEYMAP=y
++CONFIG_VGA_CONSOLE=y
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_CLGEN is not set
++# CONFIG_FB_PM2 is not set
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_CYBER2000=y
++# CONFIG_FB_SA1100 is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_SIS is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++CONFIG_FBCON_VGA=y
++# CONFIG_FBCON_HGA is not set
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++CONFIG_SOUND_OSS=m
++# CONFIG_SOUND_TRACEINIT is not set
++# CONFIG_SOUND_DMAP is not set
++# CONFIG_SOUND_AD1816 is not set
++# CONFIG_SOUND_SGALAXY is not set
++CONFIG_SOUND_ADLIB=m
++# CONFIG_SOUND_ACI_MIXER is not set
++# CONFIG_SOUND_CS4232 is not set
++# CONFIG_SOUND_SSCAPE is not set
++# CONFIG_SOUND_GUS is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_VMIDI is not set
++# CONFIG_SOUND_TRIX is not set
++# CONFIG_SOUND_MSS is not set
++# CONFIG_SOUND_MPU401 is not set
++# CONFIG_SOUND_NM256 is not set
++# CONFIG_SOUND_MAD16 is not set
++# CONFIG_SOUND_PAS is not set
++# CONFIG_PAS_JOYSTICK is not set
++# CONFIG_SOUND_PSS is not set
++CONFIG_SOUND_SB=m
++# CONFIG_SOUND_AWE32_SYNTH is not set
++# CONFIG_SOUND_WAVEFRONT is not set
++# CONFIG_SOUND_MAUI is not set
++# CONFIG_SOUND_YM3812 is not set
++# CONFIG_SOUND_OPL3SA1 is not set
++# CONFIG_SOUND_OPL3SA2 is not set
++# CONFIG_SOUND_YMPCI is not set
++# CONFIG_SOUND_UART6850 is not set
++# CONFIG_SOUND_AEDSP16 is not set
++CONFIG_SOUND_WAVEARTIST=m
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++CONFIG_USB_DEBUG=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Devices
++#
++CONFIG_USB_PRINTER=m
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_AUDIO=m
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_USS720 is not set
++# CONFIG_USB_DABUSB is not set
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/fortunet_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/fortunet_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/fortunet_defconfig      2003-09-27 11:38:18.617698064 +0800
+@@ -0,0 +1,593 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++# CONFIG_MODULES is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++CONFIG_ARCH_CLPS711X=y
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++CONFIG_ARCH_FORTUNET=y
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_ARM_THUMB is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_PARTITIONS is not set
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++CONFIG_MTD_FORTUNET=y
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++# CONFIG_INET is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC is not set
++# CONFIG_NET_DIVERT is not set
++# CONFIG_ECONET_AUNUDP is not set
++# CONFIG_ECONET_NATIVE 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 device support
++#
++# CONFIG_NETDEVICES is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# Synchronous Serial Interface
++#
++# CONFIG_SSI is not set
++# CONFIG_SSI_CLPS711X is not set
++# CONFIG_SSI_JUNO is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++CONFIG_SERIAL_CLPS711X=y
++CONFIG_SERIAL_CLPS711X_CONSOLE=y
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS_PROC_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE 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_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_HPUSBSCSI is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++# CONFIG_DEBUG_LL_SER3 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/freebird_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/freebird_defconfig 2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/freebird_defconfig      2003-09-27 11:38:18.618697912 +0800
+@@ -0,0 +1,615 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++CONFIG_SA1100_FREEBIRD=y
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_PFS168 is not set
++CONFIG_SA1100_FREEBIRD_OLD=y
++# CONFIG_SA1100_FREEBIRD_NEW is not set
++CONFIG_SA1100_FL=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++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_APM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="mem=32M root=/dev/ram initrd=0xc0800000,3M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UCB1200 is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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 is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++# CONFIG_IRLAN is not set
++# CONFIG_IRNET is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++CONFIG_IRTTY_SIR=m
++# CONFIG_IRPORT_SIR is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_FB_TS_BT=y
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_PCMCIA_SERIAL is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_UDA1341_GSM is not set
++# CONFIG_SOUND_SA1100_SSP is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/freebird_new_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/freebird_new_defconfig     2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/freebird_new_defconfig  2003-09-27 11:38:18.619697760 +0800
+@@ -0,0 +1,635 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++CONFIG_SA1100_FREEBIRD=y
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_FREEBIRD_OLD is not set
++CONFIG_SA1100_FREEBIRD_NEW=y
++CONFIG_SA1100_FL=m
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=y
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++CONFIG_APM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="noinitrd console=ttySA0 init=/linuxrc root=/dev/mtdblock4 mem=32m"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UCB1200 is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++
++#
++#   IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++# CONFIG_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++# CONFIG_IRLAN is not set
++# CONFIG_IRNET is not set
++# CONFIG_IRCOMM is not set
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=m
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_FB_TS_BT=y
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++CONFIG_PCMCIA_SERIAL_CS=m
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++CONFIG_AUTOFS_FS=m
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=m
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=m
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=m
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=m
++CONFIG_LOCKD=m
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_UDA1341_GSM is not set
++# CONFIG_SOUND_SA1100_SSP is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/graphicsclient_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/graphicsclient_defconfig   2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/graphicsclient_defconfig        2003-09-27 11:38:18.621697456 +0800
+@@ -0,0 +1,732 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++CONFIG_SA1100_GRAPHICSCLIENT=y
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=off mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0800000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=800000
++CONFIG_MTD_PHYSMAP_LEN=1000000
++CONFIG_MTD_PHYSMAP_BUSWIDTH=4
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# 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 is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_AUDIO_UCB1200=y
++CONFIG_ADC_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/graphicsmaster_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/graphicsmaster_defconfig   2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/graphicsmaster_defconfig        2003-09-27 11:38:18.622697304 +0800
+@@ -0,0 +1,745 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_GRAPHICSMASTER=y
++# CONFIG_SA1100_ADSBITSY is not set
++CONFIG_SA1111=y
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=off mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0800000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=800000
++CONFIG_MTD_PHYSMAP_LEN=1000000
++CONFIG_MTD_PHYSMAP_BUSWIDTH=4
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++CONFIG_UCB1200=y
++CONFIG_TOUCHSCREEN_UCB1200=y
++CONFIG_AUDIO_UCB1200=y
++CONFIG_ADC_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=y
++CONFIG_USB_OHCI_NOPCI=y
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_HID is not set
++# CONFIG_USB_KBD is not set
++CONFIG_USB_MOUSE=y
++# CONFIG_USB_WACOM is not set
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_PWC is not set
++# CONFIG_USB_SE401 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_NET1080 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/h3600_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/h3600_defconfig    2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/h3600_defconfig 2003-09-27 11:38:18.624697000 +0800
+@@ -0,0 +1,951 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++CONFIG_SA1100_H3600=y
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE=""
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++CONFIG_MTD_BOOTLDR_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECS is not set
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=m
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++# CONFIG_MWAVE is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=m
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++CONFIG_NFSD=m
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_SMB_FS=m
++# CONFIG_SMB_NLS_DEFAULT is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++CONFIG_ZLIB_FS_INFLATE=m
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_SMB_NLS=y
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++# CONFIG_FBCON_CFB8 is not set
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_CFB24 is not set
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++CONFIG_SOUND_SA1100=y
++CONFIG_SOUND_UDA1341=y
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++CONFIG_SOUND_H3600_UDA1341=y
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/hackkit_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/hackkit_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/hackkit_defconfig       2003-09-27 11:38:18.625696848 +0800
+@@ -0,0 +1,654 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++CONFIG_SA1100_HACKKIT=y
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_SA1100=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_DISCONTIGMEM=y
++CONFIG_ISA=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_24_API=y
++CONFIG_CPU_FREQ_26_API=y
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=3
++# CONFIG_MTD_PARTITIONS is not set
++# CONFIG_MTD_CONCAT is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_EDB7312 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# 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
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++CONFIG_INET_ECN=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_XFRM_USER is not set
++# CONFIG_IPV6 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_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
++# 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
++
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++CONFIG_DUMMY=y
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP is not set
++# CONFIG_ARLAN is not set
++# CONFIG_AIRONET4500 is not set
++
++#
++# Wireless ISA/PCI cards support
++#
++# CONFIG_WAVELAN is not set
++# CONFIG_AIRO is not set
++# CONFIG_HERMES is not set
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices (depends on LLC=y)
++#
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL 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_TSLIBDEV 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 is not set
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_CT82C710 is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE 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 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# 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=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++CONFIG_TMPFS=y
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# 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 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_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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 is not set
++# 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
++
++#
++# Console drivers
++#
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_WAITQ=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_KALLSYMS=y
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/huw_webpanel_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/huw_webpanel_defconfig     2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/huw_webpanel_defconfig  2003-09-27 11:38:18.626696696 +0800
+@@ -0,0 +1,435 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++CONFIG_SA1100_HUW_WEBPANEL=y
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=32480K root=/dev/ram initrd=0xc0800000,8M"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++CONFIG_MTD_CFI=y
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_BLK_DEV_FLASH is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++# CONFIG_NETDEVICES is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_LL is not set
+Index: linux-2.6.0-test5/arch/arm/configs/integrator_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/integrator_defconfig       2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/integrator_defconfig    2003-09-27 11:38:18.628696392 +0800
+@@ -0,0 +1,663 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++CONFIG_ARCH_INTEGRATOR=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_ANAKIN is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++CONFIG_CPU_ARM920T=y
++CONFIG_CPU_ARM920_CPU_IDLE=y
++CONFIG_CPU_ARM920_I_CACHE_ON=y
++CONFIG_CPU_ARM920_D_CACHE_ON=y
++# CONFIG_CPU_ARM920_WRITETHROUGH is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_DISCONTIGMEM is not set
++
++#
++# General setup
++#
++CONFIG_PCI_INTEGRATOR=y
++CONFIG_PCI=y
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_CLOCK=y
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=1f03 mem=32M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++CONFIG_MTD_AFS_PARTS=y
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_VIRTUAL_ER is not set
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LART_BIT_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++CONFIG_MTD_ARMFLASH=y
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++# CONFIG_RTNETLINK is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++CONFIG_INET_ECN=y
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++# CONFIG_NET_SB1000 is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# 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
++# 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_ADAPTEC_STARFIRE is not set
++# CONFIG_APRICOT is not set
++# CONFIG_CS89x0 is not set
++# CONFIG_TULIP is not set
++# CONFIG_DE4X5 is not set
++# CONFIG_DGRS is not set
++# CONFIG_DM9102 is not set
++CONFIG_EEPRO100=y
++CONFIG_EEPRO100_PM=y
++# CONFIG_LNE390 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_NE3210 is not set
++# CONFIG_ES3210 is not set
++# CONFIG_8139TOO is not set
++# CONFIG_8139TOO_PIO is not set
++# CONFIG_8139TOO_TUNE_TWISTER is not set
++# CONFIG_8139TOO_8129 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_WINBOND_840 is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_PCI is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++CONFIG_SERIAL_AMBA=y
++CONFIG_SERIAL_AMBA_CONSOLE=y
++CONFIG_SERIAL_INTEGRATOR=y
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++CONFIG_MINIX_FS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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=y
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_ROOT_NFS=y
++CONFIG_NFSD=y
++CONFIG_NFSD_V3=y
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_KMI_KEYB=y
++CONFIG_KMI_MOUSE=y
++CONFIG_PC_KEYMAP=y
++CONFIG_VGA_CONSOLE=y
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_CLGEN is not set
++# CONFIG_FB_PM2 is not set
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_SIS is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/iq80310_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/iq80310_defconfig  2003-09-27 11:38:18.427726944 +0800
++++ linux-2.6.0-test5/arch/arm/configs/iq80310_defconfig       2003-09-27 11:38:18.629696240 +0800
+@@ -0,0 +1,770 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++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
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++CONFIG_ARCH_IOP3XX=y
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP3xx Implementation Options
++#
++CONFIG_ARCH_IQ80310=y
++# CONFIG_ARCH_IQ80321 is not set
++CONFIG_ARCH_IOP310=y
++# CONFIG_ARCH_IOP321 is not set
++
++#
++# IOP3xx Chipset Features
++#
++# CONFIG_IOP3XX_AAU is not set
++# CONFIG_IOP3XX_DMA is not set
++# CONFIG_IOP3XX_MU is not set
++# CONFIG_IOP3XX_PMON is not set
++
++#
++# ADIFCC Implementation Options
++#
++
++#
++# ADI Board Types
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_XS80200=y
++CONFIG_CPU_32v5=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++CONFIG_XSCALE_PMU=y
++
++#
++# General setup
++#
++CONFIG_PCI=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x00060000
++CONFIG_ZBOOT_ROM_BSS=0xa1008000
++# CONFIG_PCI_LEGACY_PROC is not set
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp mem=32M root=/dev/nfs initrd=0xc0800000,4M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_REDBOOT_PARTS=y
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++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
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_IQ80310=y
++# CONFIG_MTD_EDB7312 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD 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 is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking support
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++
++#
++# IP: Virtual Server Configuration
++#
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_XFRM_USER 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_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
++# 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 is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_SMC91X is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 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_B44 is not set
++# CONFIG_DGRS is not set
++CONFIG_EEPRO100=y
++# CONFIG_EEPRO100_PIO 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 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
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_TIGON3 is not set
++
++#
++# Ethernet (10000 Mbit)
++#
++# CONFIG_IXGB is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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 (depends on LLC=y)
++#
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECD=y
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++# CONFIG_IDE_TASKFILE_IO is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_IDEPCI is not set
++
++#
++# SCSI device support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support (EXPERIMENTAL)
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Userland interfaces
++#
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_SERIO is not set
++
++#
++# Input Device Drivers
++#
++
++#
++# Character devices
++#
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++# CONFIG_I2C_SENSOR is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 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_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
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_PROC_FS is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_HEXIUM_ORION is not set
++# CONFIG_VIDEO_HEXIUM_GEMINI is not set
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_GEMTEK_PCI is not set
++# CONFIG_RADIO_MAXIRADIO is not set
++# CONFIG_RADIO_MAESTRO is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++CONFIG_DVB=y
++CONFIG_DVB_CORE=y
++
++#
++# Supported Frontend Modules
++#
++# CONFIG_DVB_STV0299 is not set
++# CONFIG_DVB_ALPS_BSRV2 is not set
++# CONFIG_DVB_ALPS_TDLB7 is not set
++# CONFIG_DVB_ALPS_TDMB7 is not set
++# CONFIG_DVB_ATMEL_AT76C651 is not set
++# CONFIG_DVB_CX24110 is not set
++# CONFIG_DVB_GRUNDIG_29504_491 is not set
++# CONFIG_DVB_GRUNDIG_29504_401 is not set
++# CONFIG_DVB_MT312 is not set
++# CONFIG_DVB_VES1820 is not set
++# CONFIG_DVB_TDA1004X is not set
++
++#
++# Supported SAA7146 based PCI Adapters
++#
++# CONFIG_DVB_AV7110 is not set
++# CONFIG_DVB_BUDGET is not set
++
++#
++# Supported FlexCopII (B2C2) Adapters
++#
++# CONFIG_DVB_B2C2_SKYSTAR is not set
++# CONFIG_VIDEO_BTCX is not set
++
++#
++# 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 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 is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_FAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_DEVPTS_FS_XATTR is not set
++CONFIG_TMPFS=y
++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_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND 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_NFSD is not set
++CONFIG_ROOT_NFS=y
++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_INTERMEZZO_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_NEC98_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_GADGET is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/iq80321_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/iq80321_defconfig  2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/iq80321_defconfig       2003-09-27 11:38:18.631695936 +0800
+@@ -0,0 +1,776 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++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
++#
++CONFIG_MODULES=y
++# CONFIG_MODULE_UNLOAD is not set
++CONFIG_OBSOLETE_MODPARM=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++CONFIG_ARCH_IOP3XX=y
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP3xx Implementation Options
++#
++# CONFIG_ARCH_IQ80310 is not set
++CONFIG_ARCH_IQ80321=y
++# CONFIG_ARCH_IOP310 is not set
++CONFIG_ARCH_IOP321=y
++
++#
++# IOP3xx Chipset Features
++#
++# CONFIG_IOP3XX_AAU is not set
++# CONFIG_IOP3XX_DMA is not set
++# CONFIG_IOP3XX_MU is not set
++# CONFIG_IOP3XX_PMON is not set
++
++#
++# ADIFCC Implementation Options
++#
++
++#
++# ADI Board Types
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++CONFIG_XSCALE_PMU=y
++
++#
++# General setup
++#
++CONFIG_PCI=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++# CONFIG_PCI_LEGACY_PROC is not set
++CONFIG_PCI_NAMES=y
++# CONFIG_HOTPLUG is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=128M@0xa0000000"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_REDBOOT_PARTS=y
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++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
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_EDB7312 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD 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 is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking support
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE 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
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++
++#
++# IP: Virtual Server Configuration
++#
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_XFRM_USER 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_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
++# 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 is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_SMC91X is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 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_B44 is not set
++# CONFIG_DGRS is not set
++CONFIG_EEPRO100=y
++# CONFIG_EEPRO100_PIO 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 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
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++CONFIG_E1000=y
++CONFIG_E1000_NAPI=y
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_TIGON3 is not set
++
++#
++# Ethernet (10000 Mbit)
++#
++# CONFIG_IXGB is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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 (depends on LLC=y)
++#
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECD=y
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++# CONFIG_IDE_TASKFILE_IO is not set
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_BLK_DEV_IDEPCI=y
++# CONFIG_BLK_DEV_GENERIC is not set
++# CONFIG_IDEPCI_SHARE_IRQ is not set
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++# CONFIG_BLK_DEV_IDE_TCQ is not set
++# 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_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=y
++# CONFIG_BLK_DEV_TRIFLEX is not set
++# CONFIG_BLK_DEV_CY82C693 is not set
++# CONFIG_BLK_DEV_CS5520 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 is not set
++# CONFIG_BLK_DEV_NS87415 is not set
++# CONFIG_BLK_DEV_OPTI621 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_SIIMAGE 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_BLK_DEV_SL82C105 is not set
++CONFIG_IDEDMA_AUTO=y
++# CONFIG_IDEDMA_IVB is not set
++
++#
++# SCSI device support
++#
++# CONFIG_SCSI is not set
++
++#
++# IEEE 1394 (FireWire) support (EXPERIMENTAL)
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Userland interfaces
++#
++
++#
++# Input I/O drivers
++#
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_SERIO is not set
++
++#
++# Input Device Drivers
++#
++
++#
++# Character devices
++#
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++# CONFIG_I2C_SENSOR is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 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_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
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_PROC_FS is not set
++
++#
++# Video Adapters
++#
++# CONFIG_VIDEO_PMS is not set
++# CONFIG_VIDEO_CPIA is not set
++# CONFIG_VIDEO_STRADIS is not set
++# CONFIG_VIDEO_HEXIUM_ORION is not set
++# CONFIG_VIDEO_HEXIUM_GEMINI is not set
++
++#
++# Radio Adapters
++#
++# CONFIG_RADIO_GEMTEK_PCI is not set
++# CONFIG_RADIO_MAXIRADIO is not set
++# CONFIG_RADIO_MAESTRO is not set
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++# CONFIG_VIDEO_BTCX is not set
++
++#
++# 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 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 is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_FAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_DEVFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_DEVPTS_FS_XATTR is not set
++CONFIG_TMPFS=y
++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_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND 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_NFSD is not set
++CONFIG_ROOT_NFS=y
++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_INTERMEZZO_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_NEC98_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++
++#
++# Graphics support
++#
++# CONFIG_FB is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_GADGET is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/jornada720_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/jornada720_defconfig       2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/jornada720_defconfig    2003-09-27 11:38:18.632695784 +0800
+@@ -0,0 +1,897 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++CONFIG_SA1100_JORNADA720=y
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_REGISTERS is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++# CONFIG_MERCURY_BACKPAQ is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=m
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=32M"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=1
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_BOOTLDR_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_CHAR=m
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++CONFIG_MTD_CFI_B2=y
++CONFIG_MTD_CFI_B4=y
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_H3600_BACKPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_FILTER=y
++CONFIG_UNIX=y
++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
++
++#
++#   IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP is not set
++CONFIG_WAVELAN=m
++CONFIG_ARLAN=m
++CONFIG_AIRONET4500=m
++CONFIG_AIRONET4500_NONCS=m
++# CONFIG_AIRONET4500_PNP is not set
++# CONFIG_AIRONET4500_PCI is not set
++# CONFIG_AIRONET4500_ISA is not set
++# CONFIG_AIRONET4500_I365 is not set
++# CONFIG_AIRONET4500_PROC is not set
++# CONFIG_AIRO is not set
++CONFIG_HERMES=m
++CONFIG_PCMCIA_HERMES=m
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# 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_NMCLAN=m
++CONFIG_PCMCIA_SMC91C92=m
++CONFIG_PCMCIA_XIRC2PS=m
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++CONFIG_PCMCIA_WAVELAN=m
++CONFIG_AIRONET4500_CS=m
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++CONFIG_IRLAN=m
++# CONFIG_IRNET is not set
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++# CONFIG_DONGLE is not set
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL=m
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++# CONFIG_NEWTONKBD is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_INPUT_NS558 is not set
++# CONFIG_INPUT_LIGHTNING is not set
++# CONFIG_INPUT_PCIGAME is not set
++# CONFIG_INPUT_CS461X is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_INPUT_SERIO is not set
++# CONFIG_INPUT_SERPORT is not set
++# CONFIG_INPUT_ANALOG is not set
++# CONFIG_INPUT_A3D is not set
++# CONFIG_INPUT_ADI is not set
++# CONFIG_INPUT_COBRA is not set
++# CONFIG_INPUT_GF2K is not set
++# CONFIG_INPUT_GRIP is not set
++# CONFIG_INPUT_INTERACT is not set
++# CONFIG_INPUT_TMDC is not set
++# CONFIG_INPUT_SIDEWINDER is not set
++# CONFIG_INPUT_IFORCE_USB is not set
++# CONFIG_INPUT_IFORCE_232 is not set
++# CONFIG_INPUT_WARRIOR is not set
++# CONFIG_INPUT_MAGELLAN is not set
++# CONFIG_INPUT_SPACEORB is not set
++# CONFIG_INPUT_SPACEBALL is not set
++# CONFIG_INPUT_STINGER is not set
++# CONFIG_INPUT_DB9 is not set
++# CONFIG_INPUT_GAMECON is not set
++# CONFIG_INPUT_TURBOGRAFX is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_V4L2_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=2
++# 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_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++CONFIG_DEVFS_DEBUG=y
++# CONFIG_DRIVERFS_FS is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=m
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_EPSON1356=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++# CONFIG_FBCON_CFB8 is not set
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_CFB24 is not set
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++CONFIG_SOUND_SA1100=m
++# CONFIG_SOUND_UDA1341 is not set
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_HID is not set
++# CONFIG_USB_HIDDEV is not set
++# CONFIG_USB_KBD is not set
++# CONFIG_USB_MOUSE is not set
++# CONFIG_USB_WACOM is not set
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_HPUSBSCSI is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++# CONFIG_DEBUG_LL_SER3 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/lart_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/lart_defconfig     2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/lart_defconfig  2003-09-27 11:38:18.634695480 +0800
+@@ -0,0 +1,893 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++CONFIG_SA1100_LART=y
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++CONFIG_APM=m
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram"
++# CONFIG_PFS168_CMDLINE is not set
++CONFIG_LEDS=y
++# CONFIG_LEDS_TIMER is not set
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++CONFIG_MTD_DEBUG=y
++CONFIG_MTD_DEBUG_VERBOSE=1
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++CONFIG_MTD_LART=y
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE 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
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++CONFIG_SLIP=m
++CONFIG_SLIP_COMPRESSED=y
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++CONFIG_IRDA_OPTIONS=y
++
++#
++#   IrDA options
++#
++CONFIG_IRDA_CACHE_LAST_LSAP=y
++# CONFIG_IRDA_FAST_RR is not set
++CONFIG_IRDA_DEBUG=y
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++# CONFIG_IRTTY_SIR is not set
++# CONFIG_IRPORT_SIR is not set
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECS is not set
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_UCB1200=m
++CONFIG_TOUCHSCREEN_UCB1200=m
++CONFIG_AUDIO_UCB1200=m
++CONFIG_ADC_UCB1200=m
++# CONFIG_TOUCHSCREEN_H3600 is not set
++CONFIG_PROFILER=m
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++
++#
++# L3 driver support
++#
++# CONFIG_L3_DRV_UDA1341 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# 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_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_REISERFS_FS=m
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++CONFIG_EXT3_FS=m
++CONFIG_JBD=m
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=m
++CONFIG_JFFS2_FS_DEBUG=1
++CONFIG_CRAMFS=m
++CONFIG_TMPFS=y
++CONFIG_RAMFS=m
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++# CONFIG_MINIX_FS is not set
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++CONFIG_UDF_FS=m
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++CONFIG_SUNRPC=m
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=m
++# CONFIG_NLS_CODEPAGE_852 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_1251 is not set
++CONFIG_NLS_ISO8859_1=m
++# 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=m
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=m
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++# CONFIG_SOUND_H3600_UDA1341 is not set
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++CONFIG_SOUND_SA1100SSP=m
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# Miscellaneous USB drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_ID75 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/lubbock_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/lubbock_defconfig  2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/lubbock_defconfig       2003-09-27 11:38:18.636695176 +0800
+@@ -0,0 +1,882 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# Intel PXA250/210 Implementations
++#
++CONFIG_ARCH_LUBBOCK=y
++# CONFIG_ARCH_PXA_IDP is not set
++CONFIG_SA1111=y
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++
++#
++# IOP310 Implementation Options
++#
++# CONFIG_ARCH_IQ80310 is not set
++
++#
++# IOP310 Chipset Features
++#
++# CONFIG_IOP310_AAU is not set
++# CONFIG_IOP310_DMA is not set
++# CONFIG_IOP310_MU is not set
++# CONFIG_IOP310_PMON is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++# CONFIG_CPU_32v4 is not set
++CONFIG_CPU_32v5=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++CONFIG_CPU_XSCALE=y
++CONFIG_XSCALE_CACHE_ERRATA=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++
++#
++# General setup
++#
++# CONFIG_DISCONTIGMEM is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++CONFIG_PCMCIA_PROBE=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++# CONFIG_PCMCIA_SA1100 is not set
++CONFIG_PCMCIA_PXA=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_REDBOOT_PARTS=y
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_2PARTS_IPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++CONFIG_MTD_LUBBOCK=y
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_FORTUNET is not set
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++
++#
++# Appletalk devices
++#
++# CONFIG_DEV_APPLETALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_TIGON3 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_JOYSTICK_ANALOG is not set
++# CONFIG_JOYSTICK_A3D is not set
++# CONFIG_JOYSTICK_ADI is not set
++# CONFIG_JOYSTICK_COBRA is not set
++# CONFIG_JOYSTICK_GF2K is not set
++# CONFIG_JOYSTICK_GRIP is not set
++# CONFIG_JOYSTICK_INTERACT is not set
++# CONFIG_JOYSTICK_SIDEWINDER is not set
++# CONFIG_JOYSTICK_TMDC is not set
++# CONFIG_JOYSTICK_IFORCE_USB is not set
++# CONFIG_JOYSTICK_IFORCE_232 is not set
++# CONFIG_JOYSTICK_WARRIOR is not set
++# CONFIG_JOYSTICK_MAGELLAN is not set
++# CONFIG_JOYSTICK_SPACEORB is not set
++# CONFIG_JOYSTICK_SPACEBALL is not set
++# CONFIG_JOYSTICK_STINGER is not set
++# CONFIG_JOYSTICK_DB9 is not set
++# CONFIG_JOYSTICK_GAMECON is not set
++# CONFIG_JOYSTICK_TURBOGRAFX is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_CS is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++CONFIG_BUSMOUSE=y
++# CONFIG_ATIXL_BUSMOUSE is not set
++# CONFIG_LOGIBUSMOUSE is not set
++# CONFIG_MS_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_TCP is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_PXA_AC97 is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++# CONFIG_MCP_UCB1400_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++CONFIG_CRC32=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/lusl7200_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/lusl7200_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/lusl7200_defconfig      2003-09-27 11:38:18.637695024 +0800
+@@ -0,0 +1,488 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++# CONFIG_NET is not set
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++CONFIG_ARCH_L7200=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_32v5 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++CONFIG_CPU_ARM720T=y
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++# CONFIG_CPU_SA1100 is not set
++# CONFIG_CPU_XSCALE is not set
++# CONFIG_XSCALE_PMU is not set
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++
++#
++# General setup
++#
++# CONFIG_DISCONTIGMEM is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_FIQ=y
++CONFIG_ZBOOT_ROM=y
++CONFIG_ZBOOT_ROM_TEXT=00010000
++CONFIG_ZBOOT_ROM_BSS=f03e0000
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++
++#
++# At least one math emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=tty0 console=ttyLU1,115200 root=/dev/ram initrd=0xf1000000,0x005dac7b mem=32M"
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_GAMEPORT_PCIGAME is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_SERPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_EXTENDED is not set
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_COMPUTONE is not set
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
++# CONFIG_DIGI is not set
++# CONFIG_ESPSERIAL is not set
++# CONFIG_MOXA_INTELLIO is not set
++# CONFIG_MOXA_SMARTIO is not set
++# CONFIG_ISI is not set
++# CONFIG_SYNCLINK is not set
++# CONFIG_SYNCLINKMP is not set
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_SX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++
++#
++# ARM Serial drivers
++#
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++# CONFIG_SERIAL_SA1100 is not set
++# CONFIG_SERIAL_SA1100_CONSOLE is not set
++# CONFIG_UNIX98_PTYS is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++# CONFIG_QIFACE_COMPAT is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_ZISOFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++# CONFIG_ZLIB_INFLATE is not set
++# CONFIG_ZLIB_DEFLATE is not set
+Index: linux-2.6.0-test5/arch/arm/configs/neponset_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/neponset_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/neponset_defconfig      2003-09-27 11:38:18.639694720 +0800
+@@ -0,0 +1,895 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++CONFIG_SA1100_ASSABET=y
++CONFIG_ASSABET_NEPONSET=y
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_SA1100=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_DISCONTIGMEM=y
++CONFIG_ISA=y
++CONFIG_ZBOOT_ROM=y
++CONFIG_ZBOOT_ROM_TEXT=0x80000
++CONFIG_ZBOOT_ROM_BSS=0xc1000000
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_24_API=y
++CONFIG_CPU_FREQ_26_API=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_PCMCIA_SA1111=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_PREEMPT is not set
++CONFIG_APM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_REDBOOT_PARTS=y
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++# CONFIG_MTD_CHAR is not set
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_RAM=y
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_EDB7312 is not set
++CONFIG_MTD_PCMCIA=y
++# CONFIG_MTD_UCLINUX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking options
++#
++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_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 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_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
++# 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL 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 is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_TSDEV=y
++CONFIG_INPUT_TSDEV_SCREEN_X=240
++CONFIG_INPUT_TSDEV_SCREEN_Y=320
++CONFIG_INPUT_TSLIBDEV=y
++# 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 is not set
++CONFIG_SERIO_SERPORT=m
++# CONFIG_SERIO_CT82C710 is not set
++CONFIG_SERIO_SA1111=y
++
++#
++# 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 is not set
++# CONFIG_INPUT_JOYSTICK is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_GUNZE 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=y
++# CONFIG_COMPUTONE is not set
++# CONFIG_ROCKETPORT is not set
++# CONFIG_CYCLADES is not set
++# CONFIG_DIGIEPCA is not set
++# CONFIG_DIGI is not set
++# CONFIG_ESPSERIAL is not set
++# CONFIG_MOXA_INTELLIO is not set
++# CONFIG_MOXA_SMARTIO is not set
++# CONFIG_ISI is not set
++# CONFIG_SYNCLINK is not set
++# CONFIG_SYNCLINKMP is not set
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_SX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_8250_CS=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_SCx200_ACB is not set
++CONFIG_I2C_BIT_SA1100_GPIO=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_PROC=y
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++CONFIG_SA1100_WATCHDOG=m
++# CONFIG_EUROTECH_WDT is not set
++# CONFIG_IB700_WDT is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_SCx200_WDT is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_W83877F_WDT is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# 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 is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_NAND is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# 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 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=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=m
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 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=m
++# 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
++
++#
++# Console drivers
++#
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++# CONFIG_FONT_SUN8x16 is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++# CONFIG_FONT_MINI_4x6 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++CONFIG_SOUND_SA1100=y
++CONFIG_SOUND_UDA1341=y
++CONFIG_SOUND_ASSABET_UDA1341=y
++CONFIG_SOUND_SA1111_UDA1341=y
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++CONFIG_MCP_UCB1200=y
++CONFIG_MCP_UCB1200_AUDIO=m
++CONFIG_MCP_UCB1200_TS=y
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++CONFIG_USB_DEBUG=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_LONG_TIMEOUT is not set
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++# CONFIG_USB_UHCI_HCD_ALT is not set
++# CONFIG_USB_SL811HS is not set
++
++#
++# 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 is not set
++
++#
++# SCSI support is needed for USB Storage
++#
++
++#
++# USB Human Interface Devices (HID)
++#
++# CONFIG_USB_HID is not set
++
++#
++# USB HID Boot Protocol drivers
++#
++# CONFIG_USB_KBD is not set
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_AIPTEK is not set
++# CONFIG_USB_WACOM 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
++
++#
++# 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_CDCETHER 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
++#
++
++#
++# 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
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_KALLSYMS is not set
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+Index: linux-2.6.0-test5/arch/arm/configs/omnimeter_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/omnimeter_defconfig        2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/omnimeter_defconfig     2003-09-27 11:38:18.640694568 +0800
+@@ -0,0 +1,571 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_SBUS is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_SA1100_BRUTUS is not set
++CONFIG_SA1100_OMNIMETER=y
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_FREQUENCY_SCALE is not set
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++CONFIG_CPU_32v4=y
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++CONFIG_I82365=y
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_SA1100_PCMCIA=y
++# CONFIG_H3600_SLEEVE is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M"
++# CONFIG_LEDS is not set
++# CONFIG_ALIGNMENT_TRAP is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=m
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_BLK_DEV_FLASH is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++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
++
++#
++#   IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_CONNTRACK is not set
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
++# CONFIG_IP_NF_COMPAT_IPFWADM is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++# CONFIG_NET_SB1000 is not set
++# CONFIG_NET_SA1100_USB_HOST is not set
++# CONFIG_NET_SA1100_USB_CLIENT is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# 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
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++CONFIG_PCMCIA_3C589=y
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++CONFIG_PCMCIA_WAVELAN=y
++CONFIG_AIRONET4500_CS=y
++CONFIG_PCMCIA_WVLAN=y
++CONFIG_PCMCIA_NETCARD=y
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_TOUCHSCREEN_BITSY_KEYBOARD is not set
++# CONFIG_H3600_SLEEVE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=y
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_MOUNT_SUBDIR is not set
++# CONFIG_NCPFS_NDS_DOMAINS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS 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 is not set
++# 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_874 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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_8 is not set
++# CONFIG_NLS_ISO8859_9 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_UTF8 is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++CONFIG_FBCON_CFB4=y
++# CONFIG_FBCON_CFB8 is not set
++# CONFIG_FBCON_CFB16 is not set
++# CONFIG_FBCON_CFB24 is not set
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/pangolin_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pangolin_defconfig 2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pangolin_defconfig      2003-09-27 11:38:18.642694264 +0800
+@@ -0,0 +1,742 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++CONFIG_SA1100_PANGOLIN=y
++CONFIG_SA1100_PANGOLIN_PCMCIA_IDE=y
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=128M root=/dev/ram initrd=0xc0800000,3M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_CFI_B1 is not set
++# CONFIG_MTD_CFI_B2 is not set
++CONFIG_MTD_CFI_B4=y
++# CONFIG_MTD_CFI_I1 is not set
++# CONFIG_MTD_CFI_I2 is not set
++CONFIG_MTD_CFI_I4=y
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_TQM8XXL is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SOLUTIONENGINE is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++# CONFIG_MTD_L440GX is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_LART is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=y
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=16384
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++# CONFIG_PCMCIA_WAVELAN is not set
++# CONFIG_AIRONET4500_CS is not set
++CONFIG_PCMCIA_WVLAN=y
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_PANGOLIN is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++# CONFIG_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_PROFILER=y
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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=y
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_MQ200=y
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_E1355 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_CFB24 is not set
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++CONFIG_SOUND_PANGOLIN_UDA1341=y
++# CONFIG_SOUND_BITSY_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_mqtft_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_mqtft_defconfig     2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_mqtft_defconfig  2003-09-27 11:38:18.643694112 +0800
+@@ -0,0 +1,782 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++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 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++CONFIG_INPUT_KEYBDEV=y
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_I2C_ASSABET is not set
++CONFIG_I2C_PFS168=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_SENSORS=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_M41T11=y
++CONFIG_I2C_X9221=y
++CONFIG_I2C_PCF8574=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_MQ200=y
++# CONFIG_PFS168_MQVGA is not set
++CONFIG_PFS168_MQTFT=y
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# 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 Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_mqvga_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_mqvga_defconfig     2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_mqvga_defconfig  2003-09-27 11:38:18.644693960 +0800
+@@ -0,0 +1,782 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++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 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++CONFIG_INPUT_KEYBDEV=y
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_I2C_ASSABET is not set
++CONFIG_I2C_PFS168=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_SENSORS=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_M41T11=y
++CONFIG_I2C_X9221=y
++CONFIG_I2C_PCF8574=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_SA1100 is not set
++CONFIG_FB_MQ200=y
++CONFIG_PFS168_MQVGA=y
++# CONFIG_PFS168_MQTFT is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# 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 Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_sastn_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_sastn_defconfig     2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_sastn_defconfig  2003-09-27 11:38:18.646693656 +0800
+@@ -0,0 +1,774 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++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 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++CONFIG_INPUT_KEYBDEV=y
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_I2C_ASSABET is not set
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# 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 Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 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 misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pfs168_satft_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pfs168_satft_defconfig     2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pfs168_satft_defconfig  2003-09-27 11:38:18.647693504 +0800
+@@ -0,0 +1,782 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PFS168=y
++CONFIG_SA1111=y
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++CONFIG_SA1100_FREQUENCY_SCALE=m
++# CONFIG_SA1100_VOLTAGE_SCALE is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++
++#
++# Please ensure that you have read the help on the next option
++#
++# CONFIG_ANGELBOOT is not set
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="root=/dev/nfs mem=16M"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++CONFIG_UCB1200=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# RAM/ROM Device Drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_MTDRAM is not set
++
++#
++# Linearly Mapped Flash Device Drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_SBC_MEDIAGX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_CSTM_CFI_JEDEC is not set
++# CONFIG_MTD_JEDEC is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_NAND_SPIA is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# 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_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=y
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++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 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++CONFIG_IRDA_ULTRA=y
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# FIR device drivers
++#
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++CONFIG_SA1100_FIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++CONFIG_INPUT_KEYBDEV=y
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++# CONFIG_SERIAL_CONSOLE is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_TOUCHSCREEN_UCB1200=y
++# CONFIG_TOUCHSCREEN_BITSY is not set
++# CONFIG_PROFILER is not set
++# CONFIG_PFS168_SPI is not set
++CONFIG_PFS168_DTMF=y
++CONFIG_PFS168_MISC=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_I2C_ASSABET is not set
++CONFIG_I2C_PFS168=y
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_SENSORS=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_EEPROM=y
++CONFIG_I2C_M41T11=y
++CONFIG_I2C_X9221=y
++CONFIG_I2C_PCF8574=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=y
++CONFIG_PSMOUSE=y
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++CONFIG_PCMCIA_SERIAL=m
++
++#
++# PCMCIA character device support
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS_FS=y
++CONFIG_JFFS_FS_VERBOSE=0
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_SYSV_FS_WRITE is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_FB=y
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_CLPS711X is not set
++# CONFIG_FB_CYBER2000 is not set
++CONFIG_FB_SA1100=y
++# CONFIG_PFS168_SASTN is not set
++CONFIG_PFS168_SATFT=y
++# CONFIG_FB_MQ200 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# 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 Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++CONFIG_USB_OHCI=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_SCANNER is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB Multimedia devices
++#
++# CONFIG_USB_IBMCAM is not set
++# CONFIG_USB_OV511 is not set
++# CONFIG_USB_DSBR is not set
++# CONFIG_USB_DABUSB is not set
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PLUSB is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_NET1080 is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB misc drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
+Index: linux-2.6.0-test5/arch/arm/configs/pleb_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/pleb_defconfig     2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/pleb_defconfig  2003-09-27 11:38:18.649693200 +0800
+@@ -0,0 +1,535 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_ANAKIN is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_BITSY is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++CONFIG_SA1100_PLEB=y
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++CONFIG_DISCONTIGMEM=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++# CONFIG_ISA is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++# CONFIG_HOTPLUG is not set
++# CONFIG_PCMCIA is not set
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,9600 mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0400000,4M"
++# CONFIG_PFS168_CMDLINE is not set
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_SUN_UFLASH is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_PNC2000 is not set
++# CONFIG_MTD_RPXLITE is not set
++# CONFIG_MTD_SC520CDP is not set
++# CONFIG_MTD_NETSC520 is not set
++# CONFIG_MTD_SBC_GXX is not set
++# CONFIG_MTD_ELAN_104NC is not set
++# CONFIG_MTD_SA1100 is not set
++# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
++# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_DBOX2 is not set
++# CONFIG_MTD_CSTM_MIPS_IXX is not set
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_MIXMEM is not set
++# CONFIG_MTD_OCTAGON is not set
++# CONFIG_MTD_VMAX is not set
++# CONFIG_MTD_OCELOT is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++# CONFIG_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++# CONFIG_SERIAL_SA1100_OLD is not set
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++# CONFIG_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_UCB1200 is not set
++# CONFIG_AUDIO_UCB1200 is not set
++# CONFIG_ADC_UCB1200 is not set
++# CONFIG_TOUCHSCREEN_BITSY is not set
++CONFIG_PROFILER=y
++# CONFIG_PFS168_SPI is not set
++# CONFIG_PFS168_DTMF is not set
++# CONFIG_PFS168_MISC is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_TMPFS=y
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_NFS_FS is not set
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/rpc_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/rpc_defconfig      2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/rpc_defconfig   2003-09-27 11:38:18.650693048 +0800
+@@ -0,0 +1,781 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_SWAP=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++CONFIG_ARCH_RPC=y
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++CONFIG_ARCH_ACORN=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM610=y
++CONFIG_CPU_ARM710=y
++CONFIG_CPU_SA110=y
++CONFIG_CPU_32v3=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_FIQ=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE=""
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# 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=y
++# CONFIG_PARPORT_PC_SUPERIO is not set
++# CONFIG_PARPORT_ARC is not set
++# CONFIG_PARPORT_OTHER is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++CONFIG_BLK_DEV_FD=y
++# CONFIG_PARIDE is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Acorn-specific block devices
++#
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_NETLINK_DEV=y
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++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_IPV6 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_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
++# 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_ARM_ETHER1=y
++CONFIG_ARM_ETHER3=y
++CONFIG_ARM_ETHERH=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# 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=m
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Token Ring devices
++#
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 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_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_BLK_DEV_IDEDMA=y
++CONFIG_BLK_DEV_IDE_ICSIDE=y
++CONFIG_BLK_DEV_IDEDMA_ICS=y
++CONFIG_IDEDMA_ICS_AUTO=y
++CONFIG_BLK_DEV_IDE_RAPIDE=y
++CONFIG_IDEDMA_AUTO=y
++# CONFIG_IDEDMA_IVB is not set
++
++#
++# SCSI support
++#
++CONFIG_SCSI=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++CONFIG_CHR_DEV_ST=m
++# CONFIG_CHR_DEV_OSST is not set
++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_MULTI_LUN is not set
++# CONFIG_SCSI_REPORT_LUNS is not set
++CONFIG_SCSI_CONSTANTS=y
++CONFIG_SCSI_LOGGING=y
++
++#
++# SCSI low-level drivers
++#
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_DPT_I2O 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_EATA is not set
++# CONFIG_SCSI_EATA_DMA 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_PPA=m
++CONFIG_SCSI_IMM=m
++# CONFIG_SCSI_IZIP_EPP16 is not set
++# CONFIG_SCSI_IZIP_SLOW_CTR is not set
++# CONFIG_SCSI_PCI2000 is not set
++# CONFIG_SCSI_PCI2220I is not set
++# CONFIG_SCSI_U14_34F is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++CONFIG_SCSI_ACORNSCSI_3=m
++CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE=y
++CONFIG_SCSI_ACORNSCSI_SYNC=y
++CONFIG_SCSI_ARXESCSI=m
++CONFIG_SCSI_CUMANA_2=m
++CONFIG_SCSI_EESOXSCSI=m
++CONFIG_SCSI_POWERTECSCSI=y
++
++#
++# The following drivers are not fully supported
++#
++CONFIG_SCSI_CUMANA_1=m
++CONFIG_SCSI_OAK1=m
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL 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_TSLIBDEV is not set
++CONFIG_INPUT_EVDEV=y
++# 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 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_CT82C710 is not set
++# CONFIG_SERIO_PARKBD is not set
++CONFIG_SERIO_RPCKBD=y
++
++#
++# 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 is not set
++# CONFIG_MOUSE_SERIAL is not set
++CONFIG_MOUSE_RISCPC=y
++# 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=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_8250_ACORN=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++# CONFIG_TIPAR is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_SCx200_ACB is not set
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=y
++# CONFIG_I2C_PROC is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG 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
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=m
++# CONFIG_REISERFS_FS is not set
++CONFIG_ADFS_FS=y
++# CONFIG_ADFS_FS_RW 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=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++# CONFIG_ZISOFS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# 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 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=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_FS_MBCACHE=y
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++CONFIG_ACORN_PARTITION=y
++# CONFIG_ACORN_PARTITION_CUMANA is not set
++# CONFIG_ACORN_PARTITION_EESOX is not set
++CONFIG_ACORN_PARTITION_ICS=y
++CONFIG_ACORN_PARTITION_ADFS=y
++CONFIG_ACORN_PARTITION_POWERTEC=y
++CONFIG_ACORN_PARTITION_RISCIX=y
++CONFIG_OSF_PARTITION=y
++CONFIG_AMIGA_PARTITION=y
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++CONFIG_BSD_DISKLABEL=y
++# CONFIG_MINIX_SUBPARTITION is not set
++CONFIG_SOLARIS_X86_PARTITION=y
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# 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_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 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=m
++CONFIG_NLS_ISO8859_8=m
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++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 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++CONFIG_NLS_KOI8_R=m
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++
++#
++# Console drivers
++#
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_ACORN=y
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++CONFIG_FBCON_MFB=y
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_CFB24=y
++CONFIG_FBCON_CFB32=y
++# CONFIG_FBCON_ACCEL is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_HGA is not set
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++CONFIG_FBCON_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++CONFIG_FONT_ACORN_8x8=y
++# CONFIG_FONT_MINI_4x6 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++CONFIG_SOUND_OSS=m
++# CONFIG_SOUND_TRACEINIT is not set
++# CONFIG_SOUND_DMAP is not set
++# CONFIG_SOUND_AD1816 is not set
++# CONFIG_SOUND_SGALAXY is not set
++# CONFIG_SOUND_ADLIB is not set
++# CONFIG_SOUND_ACI_MIXER is not set
++# CONFIG_SOUND_CS4232 is not set
++# CONFIG_SOUND_SSCAPE is not set
++# CONFIG_SOUND_GUS is not set
++# CONFIG_SOUND_VMIDI is not set
++# CONFIG_SOUND_TRIX is not set
++# CONFIG_SOUND_MSS is not set
++# CONFIG_SOUND_MPU401 is not set
++# CONFIG_SOUND_NM256 is not set
++# CONFIG_SOUND_MAD16 is not set
++# CONFIG_SOUND_PAS is not set
++# CONFIG_SOUND_PSS is not set
++# CONFIG_SOUND_SB is not set
++# CONFIG_SOUND_AWE32_SYNTH is not set
++# CONFIG_SOUND_WAVEFRONT is not set
++# CONFIG_SOUND_MAUI is not set
++# CONFIG_SOUND_YM3812 is not set
++# CONFIG_SOUND_OPL3SA1 is not set
++# CONFIG_SOUND_OPL3SA2 is not set
++# CONFIG_SOUND_UART6850 is not set
++# CONFIG_SOUND_AEDSP16 is not set
++CONFIG_SOUND_VIDC=m
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_KALLSYMS is not set
++CONFIG_DEBUG_LL=y
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/shannon_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/shannon_defconfig  2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/shannon_defconfig       2003-09-27 11:38:18.652692744 +0800
+@@ -0,0 +1,735 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_OBSOLETE=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++CONFIG_SA1100_SHANNON=y
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_USB is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++CONFIG_PCMCIA_SA1100=y
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="console=ttySA0,9600 console=tty1 root=/dev/mtdblock2 init=/linuxrc"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_BOOTLDR_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_IQ80310 is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=8192
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++
++#
++#  
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# 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
++# CONFIG_AT1700 is not set
++# CONFIG_DEPCA is not set
++# CONFIG_HP100 is not set
++# CONFIG_NET_ISA is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC_OMIT_TIGON_I is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=y
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=y
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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 is not set
++# CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++CONFIG_INPUT_KEYBDEV=y
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=9600
++# CONFIG_SERIAL_8250 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_INPUT_SERIO is not set
++
++#
++# Joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_WDT is not set
++# CONFIG_WDTPCI is not set
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_ACQUIRE_WDT is not set
++# CONFIG_ADVANTECH_WDT is not set
++CONFIG_SA1100_WATCHDOG=y
++# CONFIG_EUROTECH_WDT is not set
++# CONFIG_IB700_WDT is not set
++# CONFIG_I810_TCO is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_60XX_WDT is not set
++# CONFIG_W83877F_WDT is not set
++# CONFIG_MACHZ_WDT is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_CMS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=y
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++CONFIG_MINIX_FS=y
++# CONFIG_FREEVXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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_DEVPTS_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_EXT2_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFSD is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FB_SA1100=y
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
++# CONFIG_FBCON_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++CONFIG_SOUND_SA1100=y
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++CONFIG_MCP=y
++CONFIG_MCP_SA1100=y
++CONFIG_MCP_UCB1200=y
++CONFIG_MCP_UCB1200_AUDIO=y
++CONFIG_MCP_UCB1200_TS=y
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Controllers
++#
++
++#
++# USB Device Class drivers
++#
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++# USB Imaging devices
++#
++
++#
++# USB Multimedia devices
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++
++#
++# USB Miscellaneous drivers
++#
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_DEBUG_SPINLOCK is not set
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/shark_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/shark_defconfig    2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/shark_defconfig 2003-09-27 11:38:18.653692592 +0800
+@@ -0,0 +1,852 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++CONFIG_MMU=y
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++
++#
++# 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
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++CONFIG_ARCH_SHARK=y
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++
++#
++# CLPS711X/EP721X Implementations
++#
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++
++#
++# IOP310 Implementation Options
++#
++
++#
++# IOP310 Chipset Features
++#
++
++#
++# Intel PXA250/210 Implementations
++#
++
++#
++# SA11x0 Implementations
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_SA110=y
++CONFIG_CPU_32v4=y
++
++#
++# Processor Features
++#
++
++#
++# General setup
++#
++CONFIG_PCI=y
++CONFIG_PCI_HOST_VIA82C505=y
++CONFIG_ISA=y
++CONFIG_ISA_DMA=y
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_PCI_LEGACY_PROC=y
++# CONFIG_PCI_NAMES is not set
++# CONFIG_HOTPLUG is not set
++
++#
++# At least one math emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE=""
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++# CONFIG_LEDS_CPU is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# 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_ARC is not set
++# CONFIG_PARPORT_OTHER is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD 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_NETFILTER is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_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_IPV6 is not set
++# CONFIG_XFRM_USER 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_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
++# 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 is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# 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=y
++# 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 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 is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_TIGON3 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 (depends on LLC=y)
++#
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# ATA/ATAPI/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 is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECD=y
++CONFIG_BLK_DEV_IDEFLOPPY=y
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_IDEPCI is not set
++# CONFIG_IDE_CHIPSETS is not set
++
++#
++# SCSI support
++#
++CONFIG_SCSI=m
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=m
++CONFIG_CHR_DEV_ST=m
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=m
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++CONFIG_CHR_DEV_SG=m
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_REPORT_LUNS is not set
++# 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_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_IN2000 is not set
++# CONFIG_SCSI_AM53C974 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_INITIO 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_NCR53C7xx is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++# CONFIG_SCSI_NCR53C8XX is not set
++# CONFIG_SCSI_SYM53C8XX is not set
++# CONFIG_SCSI_PAS16 is not set
++# CONFIG_SCSI_PCI2000 is not set
++# CONFIG_SCSI_PCI2220I 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_SYM53C416 is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_T128 is not set
++# CONFIG_SCSI_U14_34F is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++
++#
++# IEEE 1394 (FireWire) support (EXPERIMENTAL)
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL 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_TSLIBDEV 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_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 is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_DZ is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_PRINTER=m
++# CONFIG_LP_CONSOLE is not set
++# CONFIG_PPDEV is not set
++# CONFIG_TIPAR is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# I2C Hardware Sensors Mainboard support
++#
++
++#
++# I2C Hardware Sensors Chip support
++#
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 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_NVRAM is not set
++CONFIG_RTC=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV 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_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 is not set
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_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 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_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_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_INTERMEZZO_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_NEC98_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++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=y
++# 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_CIRRUS is not set
++# CONFIG_FB_PM2 is not set
++CONFIG_FB_CYBER2000=y
++# CONFIG_FB_IMSTT is not set
++# CONFIG_FB_RIVA 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_PM3 is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Logo configuration
++#
++# CONFIG_LOGO is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++CONFIG_SOUND_OSS=m
++# CONFIG_SOUND_TRACEINIT is not set
++# CONFIG_SOUND_DMAP is not set
++# CONFIG_SOUND_AD1816 is not set
++# CONFIG_SOUND_SGALAXY is not set
++CONFIG_SOUND_ADLIB=m
++# CONFIG_SOUND_ACI_MIXER is not set
++# CONFIG_SOUND_CS4232 is not set
++# CONFIG_SOUND_SSCAPE is not set
++# CONFIG_SOUND_GUS is not set
++# CONFIG_SOUND_VMIDI is not set
++# CONFIG_SOUND_TRIX is not set
++# CONFIG_SOUND_MSS is not set
++# CONFIG_SOUND_MPU401 is not set
++# CONFIG_SOUND_NM256 is not set
++# CONFIG_SOUND_MAD16 is not set
++# CONFIG_SOUND_PAS is not set
++# CONFIG_SOUND_PSS is not set
++CONFIG_SOUND_SB=m
++# CONFIG_SOUND_AWE32_SYNTH is not set
++# CONFIG_SOUND_WAVEFRONT is not set
++# CONFIG_SOUND_MAUI is not set
++# CONFIG_SOUND_YM3812 is not set
++# CONFIG_SOUND_OPL3SA1 is not set
++# CONFIG_SOUND_OPL3SA2 is not set
++# CONFIG_SOUND_YMFPCI is not set
++# CONFIG_SOUND_UART6850 is not set
++# CONFIG_SOUND_AEDSP16 is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_KERNEL is not set
++
++#
++# Security options
++#
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++CONFIG_CRC32=y
+Index: linux-2.6.0-test5/arch/arm/configs/sherman_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/sherman_defconfig  2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/sherman_defconfig       2003-09-27 11:38:18.654692440 +0800
+@@ -0,0 +1,215 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++
++#
++# System and processor type
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_FOOTBRIDGE is not set
++CONFIG_ARCH_SA1100=y
++CONFIG_CPU_SA1100=y
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_EMPEG is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_VICTOR is not set
++CONFIG_SA1100_SHERMAN=y
++# CONFIG_VICTOR_BOARD1 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_ARM2 is not set
++# CONFIG_CPU_ARM3 is not set
++# CONFIG_CPU_ARM6 is not set
++# CONFIG_CPU_ARM7 is not set
++CONFIG_CPU_SA110=y
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_TEXT_SECTIONS is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# General setup
++#
++CONFIG_ZBOOT_ROM=y
++CONFIG_ZBOOT_ROM_TEXT=0x00050000
++CONFIG_ZBOOT_ROM_BSS=0xc0200000
++# CONFIG_NET is not set
++# CONFIG_SYSVIPC is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_SYSCTL is not set
++CONFIG_NWFPE=y
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++# CONFIG_PARPORT is not set
++CONFIG_CMDLINE="mem=64M@0xc0000000 mem=64M@0xc8000000 root=/dev/mtdblock2"
++
++#
++# Plug and Play support
++#
++# CONFIG_PNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_IDE is not set
++
++#
++# Please see Documentation/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_IDEDISK is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_IDE_CHIPSETS is not set
++
++#
++# Additional Block Devices
++#
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_MD is not set
++CONFIG_BLK_DEV_RAM=y
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_BLK_DEV_XD is not set
++# CONFIG_PARIDE_PARPORT is not set
++# CONFIG_PARIDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_FLASH=y
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_UNIX98_PTYS is not set
++# CONFIG_MOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++
++#
++# Video For Linux
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# Joystick support
++#
++# CONFIG_JOYSTICK is not set
++# CONFIG_DTLK is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# Filesystems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++# CONFIG_HPFS_FS is not set
++CONFIG_PROC_FS=y
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++# CONFIG_MSDOS_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ACORN_PARTITION is not set
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_874 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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_8 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_DEBUG_LL=y
+Index: linux-2.6.0-test5/arch/arm/configs/stork_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/stork_defconfig    2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/stork_defconfig 2003-09-27 11:38:18.656692136 +0800
+@@ -0,0 +1,966 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++CONFIG_SA1100_H3600=y
++# CONFIG_SA1100_H3800 is not set
++CONFIG_SA1100_H3XXX=y
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++# CONFIG_SA1100_USB_CHAR is not set
++CONFIG_H3600_SLEEVE=m
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_XSCALE_PMU is not set
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++CONFIG_PCMCIA_PROBE=y
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=m
++CONFIG_FPE_FASTFPE=y
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="N"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=y
++CONFIG_MTD_BOOTLDR_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_GEOMETRY is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++CONFIG_BLK_DEV_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_NETLINK=y
++CONFIG_RTNETLINK=y
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP is not set
++CONFIG_WAVELAN=m
++# CONFIG_ARLAN is not set
++# CONFIG_AIRONET4500 is not set
++# CONFIG_AIRONET4500_NONCS is not set
++# CONFIG_AIRONET4500_PROC is not set
++# CONFIG_AIRO is not set
++CONFIG_HERMES=m
++
++#
++# Wireless Pcmcia cards support
++#
++CONFIG_PCMCIA_HERMES=m
++# CONFIG_AIRO_CS is not set
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++CONFIG_PCMCIA_3C589=m
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++CONFIG_PCMCIA_XIRC2PS=m
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/IDE/MFM/RLL support
++#
++CONFIG_IDE=m
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=m
++
++#
++# 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=m
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECS=m
++CONFIG_BLK_DEV_IDECD=m
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++# CONFIG_INPUT is not set
++# CONFIG_INPUT_KEYBDEV is not set
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_SERIAL=y
++CONFIG_SERIAL_CONSOLE=y
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=115200
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_ATOMWIDE_SERIAL is not set
++# CONFIG_DUALSP_SERIAL is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++CONFIG_L3=y
++CONFIG_L3_ALGOBIT=y
++CONFIG_L3_BIT_SA1100_GPIO=y
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++CONFIG_BIT_SA1100_GPIO=y
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++CONFIG_MOUSE=m
++# CONFIG_PSMOUSE is not set
++# CONFIG_82C710_MOUSE is not set
++# CONFIG_PC110_PAD is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++
++#
++# Input core support is needed for gameports
++#
++
++#
++# Input core support is needed for joysticks
++#
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++CONFIG_SA1100_RTC=m
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_PCMCIA_SERIAL_CS is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++# CONFIG_UMSDOS_FS is not set
++CONFIG_VFAT_FS=m
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_CRAMFS=y
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW 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_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_ROOT_NFS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V3=y
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_SMB_FS=m
++# CONFIG_SMB_NLS_DEFAULT is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++CONFIG_ZLIB_FS_INFLATE=y
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_SMB_NLS=y
++CONFIG_NLS=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# 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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++CONFIG_FBCON_ADVANCED=y
++# CONFIG_FBCON_MFB is not set
++# CONFIG_FBCON_CFB2 is not set
++# CONFIG_FBCON_CFB4 is not set
++# CONFIG_FBCON_CFB8 is not set
++CONFIG_FBCON_CFB16=y
++# CONFIG_FBCON_CFB24 is not set
++# CONFIG_FBCON_CFB32 is not set
++# CONFIG_FBCON_AFB is not set
++# CONFIG_FBCON_ILBM is not set
++# CONFIG_FBCON_IPLAN2P2 is not set
++# CONFIG_FBCON_IPLAN2P4 is not set
++# CONFIG_FBCON_IPLAN2P8 is not set
++# CONFIG_FBCON_MAC is not set
++# CONFIG_FBCON_VGA_PLANES is not set
++# CONFIG_FBCON_VGA is not set
++# CONFIG_FBCON_HGA is not set
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_MIDI_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++# CONFIG_MIDI_VIA82CXXX is not set
++CONFIG_SOUND_SA1100=y
++CONFIG_SOUND_UDA1341=m
++# CONFIG_SOUND_ASSABET_UDA1341 is not set
++CONFIG_SOUND_H3600_UDA1341=m
++# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
++# CONFIG_SOUND_SA1111_UDA1341 is not set
++# CONFIG_SOUND_SA1100SSP is not set
++# CONFIG_SOUND_OSS is not set
++# CONFIG_SOUND_WAVEARTIST is not set
++# CONFIG_SOUND_TVMIXER is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++# CONFIG_USB_OHCI_SA1111 is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++
++#
++#   SCSI support is needed for USB Storage
++#
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# USB Human Interface Devices (HID)
++#
++
++#
++#   Input core support is needed for USB HID
++#
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER 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
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_AUERSWALD is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_NO_PGT_CACHE is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/system3_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/system3_defconfig  2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/system3_defconfig       2003-09-27 11:38:18.658691832 +0800
+@@ -0,0 +1,967 @@
++#
++# Automatically generated make config: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++# CONFIG_OBSOLETE is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_KMOD is not set
++
++#
++# System Type
++#
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++
++#
++# Archimedes/A5000 Implementations (select only ONE)
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++CONFIG_SA1100_PT_SYSTEM3=y
++CONFIG_SA1111=y
++CONFIG_FORCE_MAX_ZONEORDER=9
++CONFIG_SA1100_USB=m
++CONFIG_SA1100_USB_NETLINK=m
++CONFIG_SA1100_USB_CHAR=m
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++
++#
++# Processor Type
++#
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_ARM_THUMB is not set
++CONFIG_DISCONTIGMEM=y
++
++#
++# General setup
++#
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++CONFIG_CPU_FREQ=y
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# At least one math emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++# CONFIG_BINFMT_AOUT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_PM=y
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="noinitrd root=/dev/mtdblock3"
++CONFIG_LEDS=y
++CONFIG_LEDS_TIMER=y
++CONFIG_LEDS_CPU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=y
++CONFIG_MTD_REDBOOT_PARTS=m
++CONFIG_MTD_BOOTLDR_PARTS=m
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++# CONFIG_MTD_CHAR is not set
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=y
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_PCI is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++
++#
++# 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_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_ISAPNP is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_LOOP=m
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_INITRD=y
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++# CONFIG_NETLINK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 is not set
++# CONFIG_KHTTPD is not set
++# CONFIG_ATM is not set
++# CONFIG_VLAN_8021Q is not set
++
++#
++#
++#
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_LLC 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 device support
++#
++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
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++# CONFIG_ARM_AM79C961A is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNBMAC is not set
++# CONFIG_SUNQE is not set
++# CONFIG_SUNLANCE is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_LANCE is not set
++CONFIG_NET_VENDOR_SMC=y
++# CONFIG_WD80x3 is not set
++# CONFIG_ULTRAMCA is not set
++# CONFIG_ULTRA is not set
++# CONFIG_ULTRA32 is not set
++CONFIG_SMC9194=m
++# CONFIG_NET_VENDOR_RACAL 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 is not set
++# CONFIG_NET_POCKET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN 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
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++CONFIG_PCMCIA_PCNET=m
++# CONFIG_PCMCIA_NMCLAN is not set
++CONFIG_PCMCIA_SMC91C92=m
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++# CONFIG_NET_PCMCIA_RADIO is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++# CONFIG_IRNET is not set
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++# CONFIG_IRDA_OPTIONS is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++CONFIG_IRPORT_SIR=m
++
++#
++# Dongle support
++#
++# CONFIG_DONGLE is not set
++
++#
++# FIR device drivers
++#
++# CONFIG_USB_IRDA is not set
++# CONFIG_NSC_FIR is not set
++# CONFIG_WINBOND_FIR is not set
++# CONFIG_TOSHIBA_FIR is not set
++# CONFIG_SMC_IRCC_FIR is not set
++# CONFIG_ALI_FIR is not set
++# CONFIG_VLSI_FIR is not set
++CONFIG_SA1100_FIR=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 is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_ATARAID is not set
++# CONFIG_BLK_DEV_ATARAID_PDC is not set
++# CONFIG_BLK_DEV_ATARAID_HPT is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Input core support
++#
++CONFIG_INPUT=y
++CONFIG_INPUT_KEYBDEV=y
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++# CONFIG_SERIAL is not set
++# CONFIG_SERIAL_EXTENDED is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SA1100_DEFAULT_BAUDRATE=38400
++CONFIG_SERIAL_8250=m
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_HUB6 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_UNIX98_PTY_COUNT=32
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++
++#
++# Other L3 adapters
++#
++# CONFIG_L3_SA1111 is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_MOUSE is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_GAMEPORT is not set
++# CONFIG_INPUT_NS558 is not set
++# CONFIG_INPUT_LIGHTNING is not set
++# CONFIG_INPUT_PCIGAME is not set
++# CONFIG_INPUT_CS461X is not set
++# CONFIG_INPUT_EMU10K1 is not set
++# CONFIG_INPUT_SERIO is not set
++# CONFIG_INPUT_SERPORT is not set
++
++#
++# Joysticks
++#
++# CONFIG_INPUT_ANALOG is not set
++# CONFIG_INPUT_A3D is not set
++# CONFIG_INPUT_ADI is not set
++# CONFIG_INPUT_COBRA is not set
++# CONFIG_INPUT_GF2K is not set
++# CONFIG_INPUT_GRIP is not set
++# CONFIG_INPUT_INTERACT is not set
++# CONFIG_INPUT_TMDC is not set
++# CONFIG_INPUT_SIDEWINDER is not set
++# CONFIG_INPUT_IFORCE_USB is not set
++# CONFIG_INPUT_IFORCE_232 is not set
++# CONFIG_INPUT_WARRIOR is not set
++# CONFIG_INPUT_MAGELLAN is not set
++# CONFIG_INPUT_SPACEORB is not set
++# CONFIG_INPUT_SPACEBALL is not set
++# CONFIG_INPUT_STINGER is not set
++# CONFIG_INPUT_DB9 is not set
++# CONFIG_INPUT_GAMECON is not set
++# CONFIG_INPUT_TURBOGRAFX is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_INTEL_RNG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++CONFIG_PCMCIA_SERIAL_CS=m
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_CRAMFS is not set
++CONFIG_TMPFS=y
++# CONFIG_RAMFS is not set
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_ZISOFS_FS is not set
++# CONFIG_ZLIB_FS_INFLATE is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++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_1251 is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# 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
++
++#
++# Console drivers
++#
++CONFIG_PC_KEYMAP=y
++# CONFIG_VGA_CONSOLE is not set
++
++#
++# Frame-buffer support
++#
++CONFIG_FB=y
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FB_ACORN is not set
++# CONFIG_FB_ANAKIN is not set
++# CONFIG_FB_CLPS711X is not set
++CONFIG_FB_SA1100=y
++# CONFIG_FB_CYBER2000 is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FBCON_ADVANCED is not set
++CONFIG_FBCON_CFB2=y
++CONFIG_FBCON_CFB4=y
++CONFIG_FBCON_CFB8=y
++CONFIG_FBCON_CFB16=y
++CONFIG_FBCON_FONTWIDTH8_ONLY=y
++CONFIG_FBCON_FONTS=y
++CONFIG_FONT_8x8=y
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# USB support
++#
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_BANDWIDTH is not set
++# CONFIG_USB_LONG_TIMEOUT is not set
++
++#
++# USB Controllers
++#
++# CONFIG_USB_UHCI is not set
++# CONFIG_USB_UHCI_ALT is not set
++# CONFIG_USB_OHCI is not set
++CONFIG_USB_OHCI_SA1111=m
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_AUDIO is not set
++# CONFIG_USB_BLUETOOTH is not set
++# CONFIG_USB_STORAGE is not set
++# 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_JUMPSHOT is not set
++# CONFIG_USB_ACM is not set
++CONFIG_USB_PRINTER=m
++
++#
++# USB Human Interface Devices (HID)
++#
++CONFIG_USB_HID=m
++CONFIG_USB_HIDDEV=y
++CONFIG_USB_KBD=m
++CONFIG_USB_MOUSE=m
++# CONFIG_USB_WACOM is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_DC2XX is not set
++# 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
++#
++
++#
++#   Video4Linux support is needed for USB Multimedia device support
++#
++
++#
++# USB Network adaptors
++#
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_CDCETHER is not set
++CONFIG_USB_USBNET=m
++
++#
++# USB port drivers
++#
++# CONFIG_USB_USS720 is not set
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++# CONFIG_USB_SERIAL_GENERIC is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
++# 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_USA49W is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_CYBERJACK is not set
++# CONFIG_USB_SERIAL_XIRCOM is not set
++# CONFIG_USB_SERIAL_OMNINET is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_RIO500 is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++CONFIG_FRAME_POINTER=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_NO_PGT_CACHE is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_DEBUG_SLAB=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_WAITQ=y
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
+Index: linux-2.6.0-test5/arch/arm/configs/trizeps_defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/configs/trizeps_defconfig  2003-09-27 11:38:18.428726792 +0800
++++ linux-2.6.0-test5/arch/arm/configs/trizeps_defconfig       2003-09-27 11:38:18.660691528 +0800
+@@ -0,0 +1,851 @@
++#
++# Automatically generated by make menuconfig: don't edit
++#
++CONFIG_ARM=y
++# CONFIG_EISA is not set
++# CONFIG_SBUS is not set
++# CONFIG_MCA is not set
++CONFIG_UID16=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
++# CONFIG_GENERIC_BUST_SPINLOCK is not set
++# CONFIG_GENERIC_ISA_DMA is not set
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++
++#
++# General setup
++#
++CONFIG_NET=y
++CONFIG_SYSVIPC=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_ADIFCC is not set
++# CONFIG_ARCH_ANAKIN is not set
++# CONFIG_ARCH_ARCA5K is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_CAMELOT is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_IOP310 is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_RPC is not set
++CONFIG_ARCH_SA1100=y
++# CONFIG_ARCH_SHARK is not set
++
++#
++# Archimedes/A5000 Implementations
++#
++# CONFIG_ARCH_ARC is not set
++# CONFIG_ARCH_A5K is not set
++
++#
++# CLPS711X/EP721X Implementations
++#
++# CONFIG_ARCH_AUTCPU12 is not set
++# CONFIG_ARCH_CDB89712 is not set
++# CONFIG_ARCH_CEIVA is not set
++# CONFIG_ARCH_CLEP7312 is not set
++# CONFIG_ARCH_EDB7211 is not set
++# CONFIG_ARCH_P720T is not set
++# CONFIG_ARCH_FORTUNET is not set
++# CONFIG_ARCH_EP7211 is not set
++# CONFIG_ARCH_EP7212 is not set
++
++#
++# Epxa10db
++#
++
++#
++# Footbridge Implementations
++#
++# CONFIG_ARCH_CATS is not set
++# CONFIG_ARCH_PERSONAL_SERVER is not set
++# CONFIG_ARCH_EBSA285_ADDIN is not set
++# CONFIG_ARCH_EBSA285_HOST is not set
++# CONFIG_ARCH_NETWINDER is not set
++
++#
++# IOP310 Implementation Options
++#
++# CONFIG_ARCH_IQ80310 is not set
++# CONFIG_IOP310_AAU is not set
++# CONFIG_IOP310_DMA is not set
++# CONFIG_IOP310_MU is not set
++# CONFIG_IOP310_PMON is not set
++
++#
++# Intel PXA250/210 Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_ARCH_PXA_IDP is not set
++
++#
++# SA11x0 Implementations
++#
++# CONFIG_SA1100_ASSABET is not set
++# CONFIG_ASSABET_NEPONSET is not set
++# CONFIG_SA1100_ADSBITSY is not set
++# CONFIG_SA1100_BRUTUS is not set
++# CONFIG_SA1100_CERF is not set
++# CONFIG_SA1100_H3100 is not set
++# CONFIG_SA1100_H3600 is not set
++# CONFIG_SA1100_H3800 is not set
++# CONFIG_SA1100_H3XXX is not set
++# CONFIG_SA1100_EXTENEX1 is not set
++# CONFIG_SA1100_FLEXANET is not set
++# CONFIG_SA1100_FREEBIRD is not set
++# CONFIG_SA1100_GRAPHICSCLIENT is not set
++# CONFIG_SA1100_GRAPHICSMASTER is not set
++# CONFIG_SA1100_BADGE4 is not set
++# CONFIG_SA1100_JORNADA720 is not set
++# CONFIG_SA1100_HUW_WEBPANEL is not set
++# CONFIG_SA1100_ITSY is not set
++# CONFIG_SA1100_LART is not set
++# CONFIG_SA1100_NANOENGINE is not set
++# CONFIG_SA1100_OMNIMETER is not set
++# CONFIG_SA1100_PANGOLIN is not set
++# CONFIG_SA1100_PLEB is not set
++# CONFIG_SA1100_PT_SYSTEM3 is not set
++# CONFIG_SA1100_SHANNON is not set
++# CONFIG_SA1100_SHERMAN is not set
++# CONFIG_SA1100_SIMPAD is not set
++CONFIG_SA1100_TRIZEPS=y
++CONFIG_TRIZEPS_MFTB2=y
++# CONFIG_SA1100_PFS168 is not set
++# CONFIG_SA1100_VICTOR is not set
++# CONFIG_SA1100_XP860 is not set
++# CONFIG_SA1100_YOPY is not set
++# CONFIG_SA1100_STORK is not set
++# CONFIG_SA1100_USB is not set
++# CONFIG_SA1100_USB_NETLINK is not set
++# CONFIG_SA1100_USB_CHAR is not set
++# CONFIG_H3600_SLEEVE is not set
++# CONFIG_ARCH_ACORN is not set
++# CONFIG_FOOTBRIDGE is not set
++# CONFIG_FOOTBRIDGE_HOST is not set
++# CONFIG_FOOTBRIDGE_ADDIN is not set
++# CONFIG_SA1111 is not set
++CONFIG_CPU_32=y
++# CONFIG_CPU_26 is not set
++# CONFIG_CPU_ARM610 is not set
++# CONFIG_CPU_ARM710 is not set
++# CONFIG_CPU_ARM720T is not set
++# CONFIG_CPU_ARM920T is not set
++# CONFIG_CPU_ARM922T is not set
++# CONFIG_CPU_ARM926T is not set
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_SA110 is not set
++CONFIG_CPU_SA1100=y
++# CONFIG_CPU_XSCALE is not set
++# CONFIG_CPU_32v3 is not set
++CONFIG_CPU_32v4=y
++# CONFIG_CPU_32v5 is not set
++# CONFIG_ARM_THUMB is not set
++
++#
++# General setup
++#
++CONFIG_DISCONTIGMEM=y
++# CONFIG_PCI is not set
++CONFIG_ISA=y
++# CONFIG_ISA_DMA is not set
++# CONFIG_FIQ is not set
++# CONFIG_ZBOOT_ROM is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPU_FREQ_24_API is not set
++# CONFIG_CPU_FREQ_26_API is not set
++CONFIG_HOTPLUG=y
++
++#
++# PCMCIA/CardBus support
++#
++CONFIG_PCMCIA=m
++# CONFIG_I82092 is not set
++# CONFIG_I82365 is not set
++# CONFIG_TCIC is not set
++# CONFIG_PCMCIA_CLPS6700 is not set
++CONFIG_PCMCIA_SA1100=m
++# CONFIG_PCMCIA_SA1111 is not set
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_KCORE_ELF=y
++# CONFIG_KCORE_AOUT is not set
++CONFIG_BINFMT_AOUT=y
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_PM is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_APM is not set
++# CONFIG_ARTHUR is not set
++CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/hda2 1"
++# CONFIG_LEDS is not set
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_PARTITIONS=m
++CONFIG_MTD_CONCAT=m
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++CONFIG_MTD_AFS_PARTS=m
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++# CONFIG_MTD_AMDSTD is not set
++# CONFIG_MTD_SHARP is not set
++# CONFIG_MTD_JEDEC is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_PHYSMAP is not set
++# CONFIG_MTD_NORA is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_CDB89712 is not set
++CONFIG_MTD_SA1100=m
++# CONFIG_MTD_2PARTS_IPAQ is not set
++# CONFIG_MTD_DC21285 is not set
++# CONFIG_MTD_IQ80310 is not set
++# CONFIG_MTD_EPXA10DB is not set
++# CONFIG_MTD_FORTUNET is not set
++# CONFIG_MTD_AUTCPU12 is not set
++# CONFIG_MTD_EDB7312 is not set
++# CONFIG_MTD_IMPA7 is not set
++# CONFIG_MTD_CEIVA is not set
++# CONFIG_MTD_PCI is not set
++# CONFIG_MTD_PCMCIA is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLKMTD is not set
++# CONFIG_MTD_DOC1000 is not set
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOCPROBE is not set
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# Plug and Play configuration
++#
++# CONFIG_PNP is not set
++# CONFIG_PNP_NAMES is not set
++# CONFIG_PNP_DEBUG is not set
++# CONFIG_ISAPNP is not set
++# CONFIG_PNPBIOS is not set
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# 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_CISS_SCSI_TAPE is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_SIZE=4096
++# CONFIG_BLK_DEV_INITRD is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_MD_LINEAR is not set
++# CONFIG_MD_RAID0 is not set
++# CONFIG_MD_RAID1 is not set
++# CONFIG_MD_RAID5 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_BLK_DEV_LVM is not set
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++# CONFIG_NETLINK_DEV is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_FILTER is not set
++CONFIG_UNIX=y
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# 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_ARPD is not set
++# CONFIG_INET_ECN is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_IPV6 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_LLC is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_DEV_APPLETALK 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
++# 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 device support
++#
++CONFIG_NETDEVICES=y
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_ETHERTAP is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++# CONFIG_NET_ETHERNET is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000_NAPI is not set
++# CONFIG_MYRI_SBUS is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PLIP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++# CONFIG_PPP_SYNC_TTY is not set
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_STRIP is not set
++# CONFIG_ARLAN is not set
++# CONFIG_AIRONET4500 is not set
++# CONFIG_AIRONET4500_NONCS is not set
++# CONFIG_AIRONET4500_PROC is not set
++# CONFIG_WAVELAN is not set
++# CONFIG_AIRO is not set
++# CONFIG_HERMES is not set
++# CONFIG_PCMCIA_NETWAVE is not set
++# CONFIG_PCMCIA_WAVELAN is not set
++# CONFIG_PCMCIA_HERMES is not set
++CONFIG_AIRO_CS=m
++CONFIG_NET_WIRELESS=y
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++# CONFIG_NET_FC is not set
++# CONFIG_RCPCI is not set
++# CONFIG_SHAPER is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++
++#
++# PCMCIA network device support
++#
++CONFIG_NET_PCMCIA=y
++# CONFIG_PCMCIA_3C589 is not set
++# CONFIG_PCMCIA_3C574 is not set
++# CONFIG_PCMCIA_FMVJ18X is not set
++# CONFIG_PCMCIA_PCNET is not set
++# CONFIG_PCMCIA_NMCLAN is not set
++# CONFIG_PCMCIA_SMC91C92 is not set
++# CONFIG_PCMCIA_XIRC2PS is not set
++# CONFIG_PCMCIA_AXNET is not set
++# CONFIG_ARCNET_COM20020_CS is not set
++# CONFIG_PCMCIA_IBMTR is not set
++CONFIG_NET_PCMCIA_RADIO=y
++# CONFIG_PCMCIA_RAYCS is not set
++# CONFIG_AIRONET4500_CS is not set
++
++#
++# Amateur Radio support
++#
++# CONFIG_HAMRADIO is not set
++
++#
++# IrDA (infrared) support
++#
++# CONFIG_IRDA is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++CONFIG_IDE=y
++
++#
++# IDE, ATA and ATAPI Block devices
++#
++CONFIG_BLK_DEV_IDE=y
++# CONFIG_BLK_DEV_HD_IDE is not set
++# CONFIG_BLK_DEV_HD is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_IDEDISK_STROKE is not set
++CONFIG_BLK_DEV_IDECS=m
++# CONFIG_BLK_DEV_IDECD 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_BLK_DEV_CMD640 is not set
++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
++# CONFIG_BLK_DEV_ISAPNP is not set
++# CONFIG_BLK_DEV_IDE_ICSIDE is not set
++# CONFIG_BLK_DEV_IDEDMA_ICS is not set
++# CONFIG_IDEDMA_ICS_AUTO is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++# CONFIG_BLK_DEV_IDE_RAPIDE is not set
++# CONFIG_IDE_CHIPSETS is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_DMA_NONPCI is not set
++
++#
++# SCSI support
++#
++# CONFIG_SCSI is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++# CONFIG_I2O_BLOCK is not set
++# CONFIG_I2O_LAN is not set
++# CONFIG_I2O_SCSI is not set
++# CONFIG_I2O_PROC is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN_BOOL is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_TSLIBDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++# CONFIG_GAMEPORT is not set
++CONFIG_SOUND_GAMEPORT=y
++# CONFIG_GAMEPORT_NS558 is not set
++# CONFIG_GAMEPORT_L4 is not set
++# CONFIG_GAMEPORT_EMU10K1 is not set
++# CONFIG_GAMEPORT_VORTEX is not set
++# CONFIG_GAMEPORT_FM801 is not set
++# CONFIG_GAMEPORT_CS461x is not set
++# CONFIG_SERIO is not set
++# CONFIG_SERIO_I8042 is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_SERIO_CT82C710 is not set
++# CONFIG_SERIO_PARKBD is not set
++# CONFIG_SERIO_RPCKBD is not set
++# CONFIG_SERIO_AMBAKMI is not set
++# CONFIG_SERIO_SA1111 is not set
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_MOUSE_PS2 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_JOYSTICK_ANALOG is not set
++# CONFIG_JOYSTICK_A3D is not set
++# CONFIG_JOYSTICK_ADI is not set
++# CONFIG_JOYSTICK_COBRA is not set
++# CONFIG_JOYSTICK_GF2K is not set
++# CONFIG_JOYSTICK_GRIP is not set
++# CONFIG_JOYSTICK_GRIP_MP is not set
++# CONFIG_JOYSTICK_GUILLEMOT is not set
++# CONFIG_JOYSTICK_INTERACT is not set
++# CONFIG_JOYSTICK_SIDEWINDER is not set
++# CONFIG_JOYSTICK_TMDC is not set
++# CONFIG_JOYSTICK_IFORCE is not set
++# CONFIG_JOYSTICK_WARRIOR is not set
++# CONFIG_JOYSTICK_MAGELLAN is not set
++# CONFIG_JOYSTICK_SPACEORB is not set
++# CONFIG_JOYSTICK_SPACEBALL is not set
++# CONFIG_JOYSTICK_STINGER is not set
++# CONFIG_JOYSTICK_TWIDDLER is not set
++# CONFIG_JOYSTICK_DB9 is not set
++# CONFIG_JOYSTICK_GAMECON is not set
++# CONFIG_JOYSTICK_TURBOGRAFX is not set
++# CONFIG_INPUT_JOYDUMP is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_INPUT_MISC is not set
++# CONFIG_INPUT_PCSPKR is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++# CONFIG_SERIAL_8250_CONSOLE is not set
++# CONFIG_SERIAL_8250_CS is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++# CONFIG_SERIAL_8250_SHARE_IRQ is not set
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_MULTIPORT is not set
++# CONFIG_SERIAL_8250_RSA is not set
++# CONFIG_SERIAL_ACORN is not set
++# CONFIG_SERIAL_ANAKIN is not set
++# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
++# CONFIG_SERIAL_AMBA is not set
++# CONFIG_SERIAL_AMBA_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X is not set
++# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
++# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
++# CONFIG_SERIAL_21285 is not set
++# CONFIG_SERIAL_21285_OLD is not set
++# CONFIG_SERIAL_21285_CONSOLE is not set
++# CONFIG_SERIAL_UART00 is not set
++# CONFIG_SERIAL_UART00_CONSOLE is not set
++CONFIG_SERIAL_SA1100=y
++CONFIG_SERIAL_SA1100_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_UNIX98_PTYS is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_PHILIPSPAR is not set
++# CONFIG_I2C_ELV is not set
++# CONFIG_I2C_VELLEMAN is not set
++# CONFIG_SCx200_I2C is not set
++# CONFIG_SCx200_ACB is not set
++# CONFIG_I2C_BIT_SA1100_GPIO is not set
++# CONFIG_I2C_ALGOPCF is not set
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_PROC=m
++
++#
++# L3 serial bus support
++#
++# CONFIG_L3 is not set
++# CONFIG_L3_ALGOBIT is not set
++# CONFIG_L3_BIT_SA1100_GPIO is not set
++# CONFIG_BIT_SA1100_GPIO is not set
++
++#
++# Mice
++#
++# CONFIG_BUSMOUSE is not set
++# CONFIG_QIC02_TAPE is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_NVRAM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_SA1100_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_FTAPE is not set
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++
++#
++# PCMCIA character devices
++#
++# CONFIG_SYNCLINK_CS is not set
++# CONFIG_SCx200_GPIO is not set
++# CONFIG_RAW_DRIVER is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++
++#
++# File systems
++#
++# CONFIG_QUOTA is not set
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_ADFS_FS is not set
++# CONFIG_ADFS_FS_RW is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_FAT_FS is not set
++# CONFIG_MSDOS_FS is not set
++# CONFIG_UMSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++# CONFIG_ISO9660_FS is not set
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_NTFS_FS is not set
++# CONFIG_NTFS_DEBUG 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 is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX4FS_RW is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_EXT2_FS=y
++# CONFIG_SYSV_FS is not set
++# CONFIG_UDF_FS is not set
++# CONFIG_UDF_RW is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_UFS_FS_WRITE is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_XFS_QUOTA is not set
++
++#
++# Network File Systems
++#
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++# CONFIG_NFSD_V3 is not set
++# CONFIG_NFSD_V4 is not set
++# CONFIG_NFSD_TCP is not set
++CONFIG_SUNRPC=y
++CONFIG_LOCKD=y
++# CONFIG_EXPORTFS is not set
++# CONFIG_CIFS is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++# CONFIG_NCPFS_NFS_NS is not set
++# CONFIG_NCPFS_OS2_NS is not set
++# CONFIG_NCPFS_SMALLDOS is not set
++# CONFIG_NCPFS_NLS is not set
++# CONFIG_NCPFS_EXTRAS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_ZISOFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SMB_NLS is not set
++# CONFIG_NLS is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# Multimedia Capabilities Port drivers
++#
++# CONFIG_MCP is not set
++# CONFIG_MCP_SA1100 is not set
++# CONFIG_MCP_UCB1200 is not set
++# CONFIG_MCP_UCB1200_AUDIO is not set
++# CONFIG_MCP_UCB1200_TS is not set
++
++#
++# Console Switches
++#
++# CONFIG_SWITCHES is not set
++# CONFIG_SWITCHES_SA1100 is not set
++# CONFIG_SWITCHES_UCB1X00 is not set
++
++#
++# USB support
++#
++# CONFIG_USB is not set
++
++#
++# Bluetooth support
++#
++# CONFIG_BT is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_NO_FRAME_POINTER is not set
++CONFIG_DEBUG_USER=y
++# CONFIG_DEBUG_INFO is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_WAITQ is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_LL is not set
++# CONFIG_DEBUG_DC21285_PORT is not set
++# CONFIG_DEBUG_CLPS711X_UART2 is not set
++
++#
++# Security options
++#
++CONFIG_SECURITY_CAPABILITIES=y
++
++#
++# Library routines
++#
++# CONFIG_CRC32 is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+Index: linux-2.6.0-test5/arch/arm/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/Kconfig    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/Kconfig 2003-09-27 11:38:18.668690312 +0800
+@@ -213,198 +213,7 @@
+       depends on SA1111
+       default "9"
+-comment "Processor Type"
+-
+-# Figure out whether this system uses 26-bit or 32-bit CPUs.
+-config CPU_32
+-      bool
+-      default y
+-
+-# Select CPU types depending on the architecture selected.  This selects
+-# which CPUs we support in the kernel image, and the compiler instruction
+-# optimiser behaviour.
+-# ARM610
+-config CPU_ARM610
+-      bool "Support ARM610 processor"
+-      depends on ARCH_RPC
+-      help
+-        The ARM610 is the successor to the ARM3 processor
+-        and was produced by VLSI Technology Inc.
+-
+-        Say Y if you want support for the ARM610 processor.
+-        Otherwise, say N.
+-
+-# ARM710
+-config CPU_ARM710
+-      bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC
+-      default y if ARCH_CLPS7500
+-      help
+-        A 32-bit RISC microprocessor based on the ARM7 processor core
+-        designed by Advanced RISC Machines Ltd. The ARM710 is the
+-        successor to the ARM610 processor. It was released in
+-        July 1994 by VLSI Technology Inc.
+-
+-        Say Y if you want support for the ARM710 processor.
+-        Otherwise, say N.
+-
+-# ARM720T
+-config CPU_ARM720T
+-      bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
+-      default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712
+-      help
+-        A 32-bit RISC processor with 8kByte Cache, Write Buffer and
+-        MMU built around an ARM7TDMI core.
+-
+-        Say Y if you want support for the ARM720T processor.
+-        Otherwise, say N.
+-
+-# ARM920T
+-config CPU_ARM920T
+-      bool "Support ARM920T processor"
+-      depends on ARCH_INTEGRATOR
+-      help
+-        The ARM920T is licensed to be produced by numerous vendors,
+-        and is used in the Maverick EP9312.  More information at
+-        <http://linuxdevices.com/products/PD2382866068.html>.
+-
+-        Say Y if you want support for the ARM920T processor.
+-        Otherwise, say N.
+-
+-# ARM922T
+-config CPU_ARM922T
+-      bool
+-      depends on ARCH_CAMELOT
+-      default y
+-      help
+-        The ARM922T is a version of the ARM920T, but with smaller
+-        instruction and data caches. It is used in Altera's
+-        Excalibur XA device family.
+-
+-        Say Y if you want support for the ARM922T processor.
+-        Otherwise, say N.
+-
+-# ARM926T
+-config CPU_ARM926T
+-      bool "Support ARM926T processor"
+-      depends on ARCH_INTEGRATOR
+-      help
+-        This is a variant of the ARM920.  It has slightly different
+-        instruction sequences for cache and TLB operations.  Curiously,
+-        there is no documentation on it at the ARM corporate website.
+-
+-        Say Y if you want support for the ARM926T processor.
+-        Otherwise, say N.
+-
+-# ARM1020
+-config CPU_ARM1020
+-      bool "Support ARM1020 processor"
+-      depends on ARCH_INTEGRATOR
+-      help
+-        The ARM1020 is the cached version of the ARM10 processor,
+-        with an addition of a floating-point unit.
+-
+-        Say Y if you want support for the ARM1020 processor.
+-        Otherwise, say N.
+-
+-# SA110
+-config CPU_SA110
+-      bool "Support StrongARM(R) SA-110 processor" if !ARCH_EBSA110 && !FOOTBRIDGE && !ARCH_TBOX && !ARCH_SHARK && !ARCH_NEXUSPCI && !ARCH_ANAKIN && ARCH_RPC
+-      default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_TBOX || ARCH_SHARK || ARCH_NEXUSPCI || ARCH_ANAKIN
+-      help
+-        The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and
+-        is available at five speeds ranging from 100 MHz to 233 MHz.
+-        More information is available at
+-        <http://developer.intel.com/design/strong/sa110.htm>.
+-
+-        Say Y if you want support for the SA-110 processor.
+-        Otherwise, say N.
+-
+-# SA1100
+-config CPU_SA1100
+-      bool
+-      depends on ARCH_SA1100
+-      default y
+-
+-# XScale
+-config CPU_XSCALE
+-      bool
+-      depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA
+-      default y
+-
+-# Figure out what processor architecture version we should be using.
+-# This defines the compiler instruction set which depends on the machine type.
+-config CPU_32v3
+-      bool
+-      depends on ARCH_RPC || ARCH_CLPS7500
+-      default y
+-
+-config CPU_32v4
+-      bool
+-      depends on ARCH_EBSA110 || FOOTBRIDGE || ARCH_TBOX || ARCH_SHARK || ARCH_NEXUSPCI || ARCH_CLPS711X || ARCH_INTEGRATOR || ARCH_SA1100 || ARCH_L7200 || ARCH_ANAKIN || ARCH_CAMELOT
+-      default y
+-
+-config CPU_32v5
+-      bool
+-      depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA
+-      default y
+-
+-comment "Processor Features"
+-
+-config ARM_THUMB
+-      bool "Support Thumb instructions (EXPERIMENTAL)"
+-      depends on (CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020 || CPU_XSCALE) && EXPERIMENTAL
+-      help
+-        Say Y if you want to have kernel support for ARM Thumb instructions,
+-        fault handlers, and system calls.
+-
+-        The Thumb instruction set is a compressed form of the standard ARM
+-        instruction set resulting in smaller binaries at the expense of
+-        slightly less efficient code.
+-
+-        If you don't know what this all is, saying Y is a safe choice.
+-
+-config CPU_BIG_ENDIAN
+-      bool "Build big-endian kernel"
+-      depends on ARCH_SUPPORTS_BIG_ENDIAN
+-      help
+-        Say Y if you plan on running a kernel in big-endian mode.
+-        Note that your board must be properly built and your board
+-        port must properly enable and big-endian related features
+-        of your chipset/board/processor.
+-
+-config CPU_ICACHE_DISABLE
+-      bool "Disable I-Cache"
+-      depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
+-      help
+-        Say Y here to disable the processor instruction cache. Unless
+-        you have a reason not to or are unsure, say N.
+-
+-config CPU_DCACHE_DISABLE
+-      bool "Disable D-Cache"
+-      depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
+-      help
+-        Say Y here to disable the processor data cache. Unless
+-        you have a reason not to or are unsure, say N.
+-
+-config CPU_DCACHE_WRITETHROUGH
+-      bool "Force write through D-cache"
+-      depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020) && !CPU_DISABLE_DCACHE
+-      help
+-        Say Y here to use the data cache in writethough mode. Unless you
+-        specifically require this or are unsure, say N.
+-
+-config CPU_CACHE_ROUND_ROBIN
+-      bool "Round robin I and D cache replacement algorithm"
+-      depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
+-      help
+-        Say Y here to use the predictable round-robin cache replacement
+-        policy.  Unless you specifically require this or are unsure, say N.
+-
+-config CPU_BPREDICT_DISABLE
+-      bool "Disable branch prediction"
+-      depends on CPU_ARM1020
+-      help
+-        Say Y here to disable branch prediction.  If unsure, say N.
++source arch/arm/mm/Kconfig
+ #  bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER
+ config XSCALE_PMU
+@@ -842,11 +651,6 @@
+ source "drivers/char/Kconfig"
+-config KBDMOUSE
+-      bool
+-      depends on ARCH_ACORN && BUSMOUSE=y && !ARCH_RPC
+-      default y
+-
+ source "drivers/media/Kconfig"
+ source "fs/Kconfig"
+Index: linux-2.6.0-test5/arch/arm/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/asm-offsets.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/asm-offsets.c    2003-09-27 11:38:18.678688792 +0800
+@@ -10,14 +10,9 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
+-
+-#include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+-#include <asm/pgtable.h>
+-#include <asm/uaccess.h>
+-
+ /*
+  * Make sure that the compiler and target are compatible.
+  */
+@@ -58,19 +53,6 @@
+   BLANK();
+   DEFINE(VM_EXEC,             VM_EXEC);
+   BLANK();
+-  DEFINE(HPTE_TYPE_SMALL,             PTE_TYPE_SMALL);
+-  DEFINE(HPTE_AP_READ,                PTE_AP_READ);
+-  DEFINE(HPTE_AP_WRITE,               PTE_AP_WRITE);
+-  BLANK();
+-  DEFINE(LPTE_PRESENT,                L_PTE_PRESENT);
+-  DEFINE(LPTE_YOUNG,          L_PTE_YOUNG);
+-  DEFINE(LPTE_BUFFERABLE,             L_PTE_BUFFERABLE);
+-  DEFINE(LPTE_CACHEABLE,              L_PTE_CACHEABLE);
+-  DEFINE(LPTE_USER,           L_PTE_USER);
+-  DEFINE(LPTE_WRITE,          L_PTE_WRITE);
+-  DEFINE(LPTE_EXEC,           L_PTE_EXEC);
+-  DEFINE(LPTE_DIRTY,          L_PTE_DIRTY);
+-  BLANK();
+   DEFINE(PAGE_SZ,             PAGE_SIZE);
+   BLANK();
+   DEFINE(SYS_ERROR0,          0x9f0000);
+Index: linux-2.6.0-test5/arch/arm/kernel/bios32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/bios32.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/bios32.c 2003-09-27 11:38:18.682688184 +0800
+@@ -35,18 +35,17 @@
+                       continue;
+               pci_read_config_word(dev, PCI_STATUS, &status);
++              if (status == 0xffff)
++                      continue;
+-              status &= status_mask;
+-              if (status == 0)
++              if ((status & status_mask) == 0)
+                       continue;
+               /* clear the status errors */
+-              pci_write_config_word(dev, PCI_STATUS, status);
++              pci_write_config_word(dev, PCI_STATUS, status & status_mask);
+               if (warn)
+-                      printk("(%02x:%02x.%d: %04X) ", dev->bus->number,
+-                              PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
+-                              status);
++                      printk("(%s: %04X) ", pci_name(dev), status);
+       }
+ }
+Index: linux-2.6.0-test5/arch/arm/kernel/ecard.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/ecard.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/ecard.c  2003-09-27 11:38:18.690686968 +0800
+@@ -329,8 +329,7 @@
+               BUG();
+       if (ecard_pid <= 0)
+-              ecard_pid = kernel_thread(ecard_task, NULL,
+-                              CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++              ecard_pid = kernel_thread(ecard_task, NULL, CLONE_KERNEL);
+       ecard_req = req;
+       wake_up(&ecard_wait);
+Index: linux-2.6.0-test5/arch/arm/kernel/entry-armv.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/entry-armv.S        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/entry-armv.S     2003-09-27 11:38:18.699685600 +0800
+@@ -729,7 +729,7 @@
+  * This routine must not corrupt r9
+  */
+ #ifdef MULTI_ABORT
+-              ldr     r4, .LCprocfns                  @ pass r0, r3 to
++              ldr     r4, .LCprocfns                  @ pass r2, r3 to
+               mov     lr, pc                          @ processor code
+               ldr     pc, [r4]                        @ call processor specific code
+ #else
+@@ -871,7 +871,7 @@
+               alignment_trap r7, r7, __temp_abt
+               zero_fp
+ #ifdef MULTI_ABORT
+-              ldr     r4, .LCprocfns                  @ pass r0, r3 to
++              ldr     r4, .LCprocfns                  @ pass r2, r3 to
+               mov     lr, pc                          @ processor code
+               ldr     pc, [r4]                        @ call processor specific code
+ #else
+Index: linux-2.6.0-test5/arch/arm/kernel/fiq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/fiq.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/fiq.c    2003-09-27 11:38:18.710683928 +0800
+@@ -35,7 +35,6 @@
+  *     - enables FIQ.
+  *  6. Goto 3
+  */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+Index: linux-2.6.0-test5/arch/arm/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/process.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/process.c        2003-09-27 11:38:18.713683472 +0800
+@@ -312,8 +312,8 @@
+ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+ int
+-copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+-          unsigned long unused, struct task_struct *p, struct pt_regs *regs)
++copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
++          unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
+ {
+       struct thread_info *thread = p->thread_info;
+       struct pt_regs *childregs;
+@@ -321,7 +321,7 @@
+       childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1;
+       *childregs = *regs;
+       childregs->ARM_r0 = 0;
+-      childregs->ARM_sp = esp;
++      childregs->ARM_sp = stack_start;
+       memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+       thread->cpu_context.sp = (unsigned long)childregs;
+@@ -373,33 +373,35 @@
+ }
+ /*
+- * This is the mechanism for creating a new kernel thread.
+- *
+- * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+- * who haven't done an "execve()") should use this: it will work within
+- * a system call from a "real" process, but the process memory space will
+- * not be free'd until both the parent and the child have exited.
++ * Shuffle the argument into the correct register before calling the
++ * thread function.  r1 is the thread argument, r2 is the pointer to
++ * the thread function, and r3 points to the exit function.
++ */
++extern void kernel_thread_helper(void);
++asm(  ".align\n"
++"     .type   kernel_thread_helper, #function\n"
++"kernel_thread_helper:\n"
++"     mov     r0, r1\n"
++"     mov     lr, r3\n"
++"     mov     pc, r2\n"
++"     .size   kernel_thread_helper, . - kernel_thread_helper");
++
++/*
++ * Create a kernel thread.
+  */
+ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+ {
+-      register unsigned int r0 asm("r0") = flags | CLONE_VM | CLONE_UNTRACED;
+-      register unsigned int r1 asm("r1") = 0;
+-      register pid_t __ret asm("r0");
+-
+-      __asm__ __volatile__(
+-      __syscall(clone)"       @ kernel_thread sys_clone       \n\
+-      movs    %0, r0          @ if we are the child           \n\
+-      bne     1f                                              \n\
+-      mov     fp, #0          @ ensure that fp is zero        \n\
+-      mov     r0, %4                                          \n\
+-      mov     lr, pc                                          \n\
+-      mov     pc, %3                                          \n\
+-      b       sys_exit                                        \n\
+-1:    "
+-        : "=r" (__ret)
+-        : "0" (r0), "r" (r1), "r" (fn), "r" (arg)
+-      : "lr");
+-      return __ret;
++      struct pt_regs regs;
++
++      memset(&regs, 0, sizeof(regs));
++
++      regs.ARM_r1 = (unsigned long)arg;
++      regs.ARM_r2 = (unsigned long)fn;
++      regs.ARM_r3 = (unsigned long)do_exit;
++      regs.ARM_pc = (unsigned long)kernel_thread_helper;
++      regs.ARM_cpsr = SVC_MODE;
++
++      return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+ }
+ /*
+Index: linux-2.6.0-test5/arch/arm/kernel/ptrace.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/ptrace.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/ptrace.c 2003-09-27 11:38:18.719682560 +0800
+@@ -9,7 +9,6 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+Index: linux-2.6.0-test5/arch/arm/kernel/semaphore.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/semaphore.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/semaphore.c      2003-09-27 11:38:18.724681800 +0800
+@@ -11,7 +11,6 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
+-#include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/errno.h>
+Index: linux-2.6.0-test5/arch/arm/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/kernel/setup.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/kernel/setup.c  2003-09-27 11:38:18.736679976 +0800
+@@ -498,7 +498,7 @@
+       if (tag->hdr.size > 2) {
+               if ((tag->u.core.flags & 1) == 0)
+                       root_mountflags &= ~MS_RDONLY;
+-              ROOT_DEV = tag->u.core.rootdev;
++              ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+       }
+       return 0;
+ }
+@@ -798,7 +798,7 @@
+                       seq_printf(m, "Cache type\t: %s\n"
+                                     "Cache clean\t: %s\n"
+                                     "Cache lockdown\t: %s\n"
+-                                    "Cache unified\t: %s\n",
++                                    "Cache format\t: %s\n",
+                                  cache_types[CACHE_TYPE(cache_info)],
+                                  cache_clean[CACHE_TYPE(cache_info)],
+                                  cache_lockdown[CACHE_TYPE(cache_info)],
+Index: linux-2.6.0-test5/arch/arm/lib/io-readsb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/io-readsb.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/io-readsb.S 2003-09-27 11:38:18.737679824 +0800
+@@ -9,7 +9,6 @@
+  */
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
+ .insb_align:  rsb     ip, ip, #4
+               cmp     ip, r2
+@@ -37,32 +36,36 @@
+ .insb_16_lp:  ldrb    r3, [r0]
+               ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #8
+-              ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #16
+-              ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #24
+-              ldrb    r4, [r0]
+-              ldrb    r5, [r0]
+-              orr     r4, r4, r5, lsl #8
+-              ldrb    r5, [r0]
+-              orr     r4, r4, r5, lsl #16
+-              ldrb    r5, [r0]
+-              orr     r4, r4, r5, lsl #24
+               ldrb    r5, [r0]
++              mov     r3, r3,     lsl #byte(0)
+               ldrb    r6, [r0]
+-              orr     r5, r5, r6, lsl #8
+-              ldrb    r6, [r0]
+-              orr     r5, r5, r6, lsl #16
++              orr     r3, r3, r4, lsl #byte(1)
++              ldrb    r4, [r0]
++              orr     r3, r3, r5, lsl #byte(2)
++              ldrb    r5, [r0]
++              orr     r3, r3, r6, lsl #byte(3)
+               ldrb    r6, [r0]
+-              orr     r5, r5, r6, lsl #24
++              mov     r4, r4,     lsl #byte(0)
++              ldrb    ip, [r0]
++              orr     r4, r4, r5, lsl #byte(1)
++              ldrb    r5, [r0]
++              orr     r4, r4, r6, lsl #byte(2)
+               ldrb    r6, [r0]
++              orr     r4, r4, ip, lsl #byte(3)
+               ldrb    ip, [r0]
+-              orr     r6, r6, ip, lsl #8
++              mov     r5, r5,     lsl #byte(0)
++              ldrb    lr, [r0]
++              orr     r5, r5, r6, lsl #byte(1)
++              ldrb    r6, [r0]
++              orr     r5, r5, ip, lsl #byte(2)
+               ldrb    ip, [r0]
+-              orr     r6, r6, ip, lsl #16
++              orr     r5, r5, lr, lsl #byte(3)
++              ldrb    lr, [r0]
++              mov     r6, r6,     lsl #byte(0)
++              orr     r6, r6, ip, lsl #byte(1)
+               ldrb    ip, [r0]
+-              orr     r6, r6, ip, lsl #24
++              orr     r6, r6, lr, lsl #byte(2)
++              orr     r6, r6, ip, lsl #byte(3)
+               stmia   r1!, {r3 - r6}
+               subs    r2, r2, #16
+@@ -76,18 +79,20 @@
+               ldrb    r3, [r0]
+               ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #8
+-              ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #16
+-              ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #24
+-              ldrb    r4, [r0]
+               ldrb    r5, [r0]
+-              orr     r4, r4, r5, lsl #8
+-              ldrb    r5, [r0]
+-              orr     r4, r4, r5, lsl #16
++              mov     r3, r3,     lsl #byte(0)
++              ldrb    r6, [r0]
++              orr     r3, r3, r4, lsl #byte(1)
++              ldrb    r4, [r0]
++              orr     r3, r3, r5, lsl #byte(2)
+               ldrb    r5, [r0]
+-              orr     r4, r4, r5, lsl #24
++              orr     r3, r3, r6, lsl #byte(3)
++              ldrb    r6, [r0]
++              mov     r4, r4,     lsl #byte(0)
++              ldrb    ip, [r0]
++              orr     r4, r4, r5, lsl #byte(1)
++              orr     r4, r4, r6, lsl #byte(2)
++              orr     r4, r4, ip, lsl #byte(3)
+               stmia   r1!, {r3, r4}
+ .insb_no_8:   tst     r2, #4
+@@ -95,11 +100,12 @@
+               ldrb    r3, [r0]
+               ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #8
+-              ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #16
+-              ldrb    r4, [r0]
+-              orr     r3, r3, r4, lsl #24
++              ldrb    r5, [r0]
++              ldrb    r6, [r0]
++              mov     r3, r3,     lsl #byte(0)
++              orr     r3, r3, r4, lsl #byte(1)
++              orr     r3, r3, r5, lsl #byte(2)
++              orr     r3, r3, r6, lsl #byte(3)
+               str     r3, [r1], #4
+ .insb_no_4:   ands    r2, r2, #3
+Index: linux-2.6.0-test5/arch/arm/lib/io-writesb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/io-writesb.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/io-writesb.S        2003-09-27 11:38:18.739679520 +0800
+@@ -9,7 +9,26 @@
+  */
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
++
++              .macro  outword, rd
++#ifndef __ARMEB__
++              strb    \rd, [r0]
++              mov     \rd, \rd, lsr #8
++              strb    \rd, [r0]
++              mov     \rd, \rd, lsr #8
++              strb    \rd, [r0]
++              mov     \rd, \rd, lsr #8
++              strb    \rd, [r0]
++#else
++              mov     lr, \rd, lsr #24
++              strb    lr, [r0]
++              mov     lr, \rd, lsr #16
++              strb    lr, [r0]
++              mov     lr, \rd, lsr #8
++              strb    lr, [r0]
++              strb    \rd, [r0]
++#endif
++              .endm
+ .outsb_align: rsb     ip, ip, #4
+               cmp     ip, r2
+@@ -30,86 +49,37 @@
+               ands    ip, r1, #3
+               bne     .outsb_align
+-.outsb_aligned:       stmfd   sp!, {r4 - r6, lr}
++.outsb_aligned:       stmfd   sp!, {r4, r5, lr}
+               subs    r2, r2, #16
+               bmi     .outsb_no_16
+-.outsb_16_lp: ldmia   r1!, {r3 - r6}
+-
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-
+-              strb    r4, [r0]
+-              mov     r4, r4, lsr #8
+-              strb    r4, [r0]
+-              mov     r4, r4, lsr #8
+-              strb    r4, [r0]
+-              mov     r4, r4, lsr #8
+-              strb    r4, [r0]
+-
+-              strb    r5, [r0]
+-              mov     r5, r5, lsr #8
+-              strb    r5, [r0]
+-              mov     r5, r5, lsr #8
+-              strb    r5, [r0]
+-              mov     r5, r5, lsr #8
+-              strb    r5, [r0]
+-
+-              strb    r6, [r0]
+-              mov     r6, r6, lsr #8
+-              strb    r6, [r0]
+-              mov     r6, r6, lsr #8
+-              strb    r6, [r0]
+-              mov     r6, r6, lsr #8
+-              strb    r6, [r0]
+-
++.outsb_16_lp: ldmia   r1!, {r3, r4, r5, ip}
++              outword r3
++              outword r4
++              outword r5
++              outword ip
+               subs    r2, r2, #16
+               bpl     .outsb_16_lp
+               tst     r2, #15
+-              LOADREGS(eqfd, sp!, {r4 - r6, pc})
++              LOADREGS(eqfd, sp!, {r4, r5, pc})
+ .outsb_no_16: tst     r2, #8
+               beq     .outsb_no_8
+               ldmia   r1!, {r3, r4}
+-
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-
+-              strb    r4, [r0]
+-              mov     r4, r4, lsr #8
+-              strb    r4, [r0]
+-              mov     r4, r4, lsr #8
+-              strb    r4, [r0]
+-              mov     r4, r4, lsr #8
+-              strb    r4, [r0]
++              outword r3
++              outword r4
+ .outsb_no_8:  tst     r2, #4
+               beq     .outsb_no_4
+               ldr     r3, [r1], #4
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
+-              mov     r3, r3, lsr #8
+-              strb    r3, [r0]
++              outword r3
+ .outsb_no_4:  ands    r2, r2, #3
+-              LOADREGS(eqfd, sp!, {r4 - r6, pc})
++              LOADREGS(eqfd, sp!, {r4, r5, pc})
+               cmp     r2, #2
+               ldrb    r3, [r1], #1
+@@ -119,4 +89,4 @@
+               ldrgtb  r3, [r1]
+               strgtb  r3, [r0]
+-              LOADREGS(fd, sp!, {r4 - r6, pc})
++              LOADREGS(fd, sp!, {r4, r5, pc})
+Index: linux-2.6.0-test5/arch/arm/lib/io-writesl.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/io-writesl.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/io-writesl.S        2003-09-27 11:38:18.740679368 +0800
+@@ -17,10 +17,15 @@
+               ands    ip, r1, #3
+               bne     2f
+-1:            ldr     r3, [r1], #4
+-              str     r3, [r0]
+-              subs    r2, r2, #1
+-              bne     1b
++              tst     r2, #1
++              ldrne   r3, [r1], #4
++              strne   r3, [r0, #0]
++1:            subs    r2, r2, #2
++              ldrcs   r3, [r1], #4
++              ldrcs   ip, [r1], #4
++              strcs   r3, [r0, #0]
++              strcs   ip, [r0, #0]
++              bcs     1b
+               mov     pc, lr
+ 2:            bic     r1, r1, #3
+@@ -31,25 +36,25 @@
+ 3:            mov     ip, r3, lsr #16
+               ldr     r3, [r1], #4
+-              orr     ip, ip, r3, lsl #16
+-              str     ip, [r0]
+               subs    r2, r2, #1
++              orr     ip, ip, r3, lsl #16
++              str     ip, [r0, #0]
+               bne     3b
+               mov     pc, lr
+ 4:            mov     ip, r3, lsr #24
+               ldr     r3, [r1], #4
+-              orr     ip, ip, r3, lsl #8
+-              str     ip, [r0]
+               subs    r2, r2, #1
++              orr     ip, ip, r3, lsl #8
++              str     ip, [r0, #0]
+               bne     4b
+               mov     pc, lr
+ 5:            mov     ip, r3, lsr #8
+               ldr     r3, [r1], #4
+-              orr     ip, ip, r3, lsl #24
+-              str     ip, [r0]
+               subs    r2, r2, #1
++              orr     ip, ip, r3, lsl #24
++              str     ip, [r0, #0]
+               bne     5b
+               mov     pc, lr
+Index: linux-2.6.0-test5/arch/arm/lib/lib1funcs.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/lib/lib1funcs.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/lib/lib1funcs.S 2003-09-27 11:38:18.744678760 +0800
+@@ -41,7 +41,6 @@
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+ #include <asm/hardware.h>
+-#include <linux/config.h>
+ #define RET   mov
+ #define RETc(x)       mov##x
+Index: linux-2.6.0-test5/arch/arm/mach-anakin/arch.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-anakin/arch.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-anakin/arch.c      2003-09-27 11:38:18.745678608 +0800
+@@ -10,8 +10,6 @@
+  *  Changelog:
+  *   09-Apr-2001 W/TTC        Created
+  */
+-
+-#include <linux/config.h>
+ #include <linux/tty.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/arm/mach-clps711x/mm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-clps711x/mm.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-clps711x/mm.c      2003-09-27 11:38:18.746678456 +0800
+@@ -22,7 +22,6 @@
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+-#include <linux/config.h>
+ #include <linux/bootmem.h>
+ #include <asm/hardware.h>
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/core.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/core.c  2003-09-27 11:38:18.749678000 +0800
+@@ -17,7 +17,6 @@
+  * 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/config.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -34,6 +33,8 @@
+ #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>
+@@ -46,6 +47,7 @@
+  * 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
+ /*
+@@ -66,7 +68,7 @@
+  * 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 },
+@@ -89,7 +91,7 @@
+       iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc));
+ }
+-#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) 
++#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
+ static void sc_mask_irq(unsigned int irq)
+ {
+@@ -161,6 +163,7 @@
+ static int __init register_devices(void)
+ {
++      unsigned long sc_dec;
+       int i;
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+@@ -169,6 +172,28 @@
+               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;
+ }
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/cpu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/cpu.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/cpu.c   2003-09-27 11:38:18.751677696 +0800
+@@ -11,7 +11,6 @@
+  *
+  * CPU support functions
+  */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/impd1.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/impd1.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/impd1.c 2003-09-27 11:38:18.754677240 +0800
+@@ -10,7 +10,7 @@
+  *  This file provides the core support for the IM-PD1 module.
+  *
+  * Module / boot parameters.
+- *   id=n   impd1.id=n - set the logic module position in stack to 'n'
++ *   lmid=n   impd1.lmid=n - set the logic module position in stack to 'n'
+  */
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+@@ -21,17 +21,15 @@
+ #include <asm/io.h>
+ #include <asm/hardware/icst525.h>
+ #include <asm/hardware/amba.h>
++#include <asm/arch/lm.h>
+ #include <asm/arch/impd1.h>
+ #include <asm/sizes.h>
+ static int module_id;
+-module_param_named(lmid, module_id, int, 0);
++module_param_named(lmid, module_id, int, 0444);
+ MODULE_PARM_DESC(lmid, "logic module stack position");
+-#define ROM_OFFSET    0x0fffff00
+-#define ROM_SIZE      256
+-
+ struct impd1_module {
+       void    *base;
+ };
+@@ -142,17 +140,15 @@
+       }
+ };
+-static int impd1_probe(struct device *dev)
++static int impd1_probe(struct lm_device *dev)
+ {
+-      struct platform_device *pdev = to_platform_device(dev);
+-      struct resource *res = &pdev->resource[0];
+       struct impd1_module *impd1;
+       int i, ret;
+-      if (pdev->id != module_id)
++      if (dev->id != module_id)
+               return -EINVAL;
+-      if (!request_mem_region(res->start, SZ_4K, "LM registers"))
++      if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
+               return -EBUSY;
+       impd1 = kmalloc(sizeof(struct impd1_module), GFP_KERNEL);
+@@ -162,22 +158,22 @@
+       }
+       memset(impd1, 0, sizeof(struct impd1_module));
+-      impd1->base = ioremap(res->start, SZ_4K);
++      impd1->base = ioremap(dev->resource.start, SZ_4K);
+       if (!impd1->base) {
+               ret = -ENOMEM;
+               goto free_impd1;
+       }
+-      dev_set_drvdata(dev, impd1);
++      lm_set_drvdata(dev, impd1);
+-      printk("IM-PD1 found at 0x%08lx\n", res->start);
++      printk("IM-PD1 found at 0x%08lx\n", dev->resource.start);
+       for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
+               struct impd1_device *idev = impd1_devs + i;
+               struct amba_device *d;
+               unsigned long pc_base;
+-              pc_base = res->start + idev->offset;
++              pc_base = dev->resource.start + idev->offset;
+               d = kmalloc(sizeof(struct amba_device), GFP_KERNEL);
+               if (!d)
+@@ -186,16 +182,16 @@
+               memset(d, 0, sizeof(struct amba_device));
+               snprintf(d->dev.bus_id, sizeof(d->dev.bus_id),
+-                       "lm%x:%5.5lx", pdev->id, idev->offset >> 12);
++                       "lm%x:%5.5lx", dev->id, idev->offset >> 12);
+-              d->dev.parent   = &pdev->dev;
+-              d->res.start    = res->start + idev->offset;
++              d->dev.parent   = &dev->dev;
++              d->res.start    = dev->resource.start + idev->offset;
+               d->res.end      = d->res.start + SZ_4K - 1;
+               d->res.flags    = IORESOURCE_MEM;
+-              d->irq          = pdev->resource[1].start;
++              d->irq          = dev->irq;
+               d->periphid     = idev->id;
+-              ret = amba_device_register(d, res);
++              ret = amba_device_register(d, &dev->resource);
+               if (ret) {
+                       printk("unable to register device %s: %d\n",
+                               d->dev.bus_id, ret);
+@@ -211,47 +207,44 @@
+       if (impd1)
+               kfree(impd1);
+  release_lm:
+-      release_mem_region(res->start, SZ_4K);
++      release_mem_region(dev->resource.start, SZ_4K);
+       return ret;
+ }
+-static int impd1_remove(struct device *dev)
++static void impd1_remove(struct lm_device *dev)
+ {
+-      struct platform_device *pdev = to_platform_device(dev);
+-      struct resource *res = &pdev->resource[0];
+-      struct impd1_module *impd1 = dev_get_drvdata(dev);
++      struct impd1_module *impd1 = lm_get_drvdata(dev);
+       struct list_head *l, *n;
+-      list_for_each_safe(l, n, &dev->children) {
++      list_for_each_safe(l, n, &dev->dev.children) {
+               struct device *d = list_to_dev(l);
+               device_unregister(d);
+       }
+-      dev_set_drvdata(dev, NULL);
++      lm_set_drvdata(dev, NULL);
+       iounmap(impd1->base);
+       kfree(impd1);
+-      release_mem_region(res->start, SZ_4K);
+-
+-      return 0;
++      release_mem_region(dev->resource.start, SZ_4K);
+ }
+-static struct device_driver impd1_driver = {
+-      .name           = "lm",
+-      .bus            = &platform_bus_type,
++static struct lm_driver impd1_driver = {
++      .drv = {
++              .name   = "impd1",
++      },
+       .probe          = impd1_probe,
+       .remove         = impd1_remove,
+ };
+ static int __init impd1_init(void)
+ {
+-      return driver_register(&impd1_driver);
++      return lm_driver_register(&impd1_driver);
+ }
+ static void __exit impd1_exit(void)
+ {
+-      driver_unregister(&impd1_driver);
++      lm_driver_unregister(&impd1_driver);
+ }
+ module_init(impd1_init);
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/lm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/lm.c       2003-09-27 11:38:18.429726640 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/lm.c    2003-09-27 11:38:18.754677240 +0800
+@@ -0,0 +1,92 @@
++/*
++ *  linux/arch/arm/mach-integrator/lm.c
++ *
++ *  Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
++ *
++ * 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/init.h>
++#include <linux/device.h>
++
++#include <asm/arch/lm.h>
++
++#define to_lm_device(d)       container_of(d, struct lm_device, dev)
++#define to_lm_driver(d)       container_of(d, struct lm_driver, drv)
++
++static int lm_match(struct device *dev, struct device_driver *drv)
++{
++      return 1;
++}
++
++static struct bus_type lm_bustype = {
++      .name           = "logicmodule",
++      .match          = lm_match,
++//    .suspend        = lm_suspend,
++//    .resume         = lm_resume,
++};
++
++static int __init lm_init(void)
++{
++      return bus_register(&lm_bustype);
++}
++
++postcore_initcall(lm_init);
++
++static int lm_bus_probe(struct device *dev)
++{
++      struct lm_device *lmdev = to_lm_device(dev);
++      struct lm_driver *lmdrv = to_lm_driver(dev->driver);
++
++      return lmdrv->probe(lmdev);
++}
++
++static int lm_bus_remove(struct device *dev)
++{
++      struct lm_device *lmdev = to_lm_device(dev);
++      struct lm_driver *lmdrv = to_lm_driver(dev->driver);
++
++      lmdrv->remove(lmdev);
++      return 0;
++}
++
++int lm_driver_register(struct lm_driver *drv)
++{
++      drv->drv.bus = &lm_bustype;
++      drv->drv.probe = lm_bus_probe;
++      drv->drv.remove = lm_bus_remove;
++
++      return driver_register(&drv->drv);
++}
++
++void lm_driver_unregister(struct lm_driver *drv)
++{
++      driver_unregister(&drv->drv);
++}
++
++static void lm_device_release(struct device *dev)
++{
++      struct lm_device *d = to_lm_device(dev);
++
++      kfree(d);
++}
++
++int lm_device_register(struct lm_device *dev)
++{
++      int ret;
++
++      dev->dev.release = lm_device_release;
++      dev->dev.bus = &lm_bustype;
++
++      snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "lm%d", dev->id);
++      dev->resource.name = dev->dev.bus_id;
++
++      ret = request_resource(&iomem_resource, &dev->resource);
++      if (ret == 0) {
++              ret = device_register(&dev->dev);
++              if (ret)
++                      release_resource(&dev->resource);
++      }
++      return ret;
++}
+Index: linux-2.6.0-test5/arch/arm/mach-integrator/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-integrator/Makefile   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-integrator/Makefile        2003-09-27 11:38:18.756676936 +0800
+@@ -4,7 +4,7 @@
+ # Object file lists.
+-obj-y                 := core.o time.o
++obj-y                 := core.o lm.o time.o
+ obj-$(CONFIG_LEDS)    += leds.o
+ obj-$(CONFIG_PCI)     += pci_v3.o pci.o
+Index: linux-2.6.0-test5/arch/arm/mach-iop3xx/mm-321.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-iop3xx/mm-321.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-iop3xx/mm-321.c    2003-09-27 11:38:18.757676784 +0800
+@@ -12,7 +12,7 @@
+  * option) any later version.
+  *
+  */
+-
++#include <linux/config.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/arm/mach-l7200/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-l7200/core.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-l7200/core.c       2003-09-27 11:38:18.758676632 +0800
+@@ -5,7 +5,6 @@
+  *
+  *  Extra MM routines for L7200 architecture
+  */
+-#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/arm/mach-pxa/generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-pxa/generic.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-pxa/generic.c      2003-09-27 11:38:18.760676328 +0800
+@@ -16,7 +16,6 @@
+  * initialization stuff for PXA machines which can be overridden later if
+  * need be.
+  */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/arm/mach-pxa/leds.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-pxa/leds.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-pxa/leds.c 2003-09-27 11:38:18.761676176 +0800
+@@ -7,7 +7,6 @@
+  *
+  * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
+  */
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <asm/leds.h>
+Index: linux-2.6.0-test5/arch/arm/mach-pxa/pm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-pxa/pm.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-pxa/pm.c   2003-09-27 11:38:18.763675872 +0800
+@@ -10,7 +10,7 @@
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License.
+  */
+-
++#include <linux/config.h>
+ #include <linux/errno.h>
+ #include <linux/time.h>
+Index: linux-2.6.0-test5/arch/arm/mach-rpc/riscpc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-rpc/riscpc.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-rpc/riscpc.c       2003-09-27 11:38:18.764675720 +0800
+@@ -17,7 +17,6 @@
+ #include <asm/elf.h>
+ #include <asm/io.h>
+-#include <asm/setup.h>
+ #include <asm/mach-types.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/h3600.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/h3600.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/h3600.c     2003-09-27 11:38:18.770674808 +0800
+@@ -19,6 +19,7 @@
+  *                               and abstracted EGPIO interface.
+  *
+  */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/hackkit.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/hackkit.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/hackkit.c   2003-09-27 11:38:18.771674656 +0800
+@@ -11,8 +11,6 @@
+  * published by the Free Software Foundation.
+  *
+  */
+-
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/pfs168.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/pfs168.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/pfs168.c    2003-09-27 11:38:18.773674352 +0800
+@@ -1,7 +1,6 @@
+ /*
+  * linux/arch/arm/mach-sa1100/pfs168.c
+  */
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/tty.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/simpad.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/simpad.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/simpad.c    2003-09-27 11:38:18.775674048 +0800
+@@ -9,24 +9,37 @@
+ #include <linux/tty.h>
+ #include <linux/proc_fs.h>
+ #include <linux/string.h> 
++#include <linux/pm.h>
++#include <asm/irq.h>
+ #include <asm/hardware.h>
+ #include <asm/setup.h>
++#include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/serial_sa1100.h>
++#include <asm/arch/simpad.h>
++#include <asm/arch/registry.h>
++
+ #include <linux/serial_core.h>
++#include <linux/ioport.h>
++#include <asm/io.h>
+ #include "generic.h"
+ long cs3_shadow;
+-long get_cs3_shadow()
++long get_cs3_shadow(void)
+ {
+       return cs3_shadow;
+ }
++void set_cs3(long value)
++{
++      *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
++}
++
+ void set_cs3_bit(int value)
+ {
+       cs3_shadow |= value;
+@@ -39,10 +52,15 @@
+       *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+ }
++EXPORT_SYMBOL(set_cs3_bit);
++EXPORT_SYMBOL(clear_cs3_bit);
++
+ static struct map_desc simpad_io_desc[] __initdata = {
+-  /* virtual  physical    length      type */
+-  { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE }, /* MQ200 */  
+-  { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE }  /* Paules CS3, write only */
++        /* virtual    physical    length      type */
++      /* MQ200 */
++      { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE },
++      /* Paules CS3, write only */
++      { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE },
+ };
+@@ -50,32 +68,52 @@
+ {
+       if (port->mapbase == (u_int)&Ser1UTCR0) {
+               if (state)
++              {
+                       clear_cs3_bit(RS232_ON);
+-              else
++                      clear_cs3_bit(DECT_POWER_ON);
++              }else
++              {
+                       set_cs3_bit(RS232_ON);
++                      set_cs3_bit(DECT_POWER_ON);
++              }
+       }
+ }
+ static struct sa1100_port_fns simpad_port_fns __initdata = {
+-      .pm     = simpad_uart_pm,
++      .pm        = simpad_uart_pm,
+ };
+ static void __init simpad_map_io(void)
+ {
+       sa1100_map_io();
++
+       iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
+-      PSPR = 0xc0008000;
+-      GPDR &= ~GPIO_GPIO0;
+-      cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | 
+-                    ENABLE_5V | RESET_SIMCARD);
+-      *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
++      set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
++                    ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
++
++
++        sa1100_register_uart_fns(&simpad_port_fns);
++      sa1100_register_uart(0, 3);  /* serial interface */
++      sa1100_register_uart(1, 1);  /* DECT             */
++
++      // Reassign UART 1 pins
++      GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
++      GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
++      GPDR &= ~GPIO_UART_RXD;
++      PPAR |= PPAR_UPR;
++
++      /*
++       * Set up registers for sleep mode.
++       */
++
++
++      PWER = PWER_GPIO0| PWER_RTC;
++      PGSR = 0x818;
++      PCFR = 0;
++      PSDR = 0;
+-      //It is only possible to register 3 UART in serial_sa1100.c
+-      sa1100_register_uart(0, 3);
+-      sa1100_register_uart(1, 1);
+-      set_irq_type(IRQ_GPIO_UCB1300_IRQ, IRQT_RISING);
+ }
+ #ifdef CONFIG_PROC_FS
+@@ -105,7 +143,7 @@
+       char *p = page;
+       int len, i;
+         
+-      p += sprintf(p, "Chipselect3 : %x\n", cs3_shadow);
++      p += sprintf(p, "Chipselect3 : %x\n", (uint)cs3_shadow);
+       for (i = 0; i <= 15; i++) {
+               if(cs3_shadow & (1<<i)) {
+                       p += sprintf(p, "%s\t: TRUE \n",name[i]);
+@@ -121,23 +159,76 @@
+  
+       return len;
+ }
+- 
++
++static int proc_cs3_write(struct file * file, const char * buffer,
++                        size_t count, loff_t *ppos)
++{
++        unsigned long newRegValue;
++      char *endp;
++
++        newRegValue = simple_strtoul(buffer,&endp,0);
++      set_cs3( newRegValue );
++        return (count+endp-buffer);
++}
++
++#endif
+  
+ static int __init cs3_init(void)
+ {
+-      struct proc_dir_entry *proc_cs3 = create_proc_entry("cs3", 0, 0);
++
++#ifdef CONFIG_PROC_FS
++      struct proc_dir_entry *proc_cs3 = create_proc_entry("CS3", 0, 0);
+       if (proc_cs3)
++      {
+               proc_cs3->read_proc = proc_cs3_read;
++              proc_cs3->write_proc = (void*)proc_cs3_write;
++      }
++#endif
++
++
++
+       return 0;
+ }
+  
+ arch_initcall(cs3_init);
+-#endif // CONFIG_PROC_FS
++static void simpad_power_off(void)
++{
++      local_irq_disable(); // was cli
++      set_cs3(0x800);        /* only SD_MEDIAQ */
++
++      /* disable internal oscillator, float CS lines */
++      PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
++      /* enable wake-up on GPIO0 (Assabet...) */
++      PWER = GFER = GRER = 1;
++      /*
++       * set scratchpad to zero, just in case it is used as a
++       * restart address by the bootloader.
++       */
++      PSPR = 0;
++      PGSR = 0;
++      /* enter sleep mode */
++      PMCR = PMCR_SF;
++      while(1);
++
++      local_irq_enable(); /* we won't ever call it */
++
++
++}
++
++static int __init simpad_init(void)
++{
++      set_power_off_handler( simpad_power_off );
++      return 0;
++}
++
++arch_initcall(simpad_init);
++
+ MACHINE_START(SIMPAD, "Simpad")
+       MAINTAINER("Juergen Messerer")
+       BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
++        BOOT_PARAMS(0xc0000100)
+       MAPIO(simpad_map_io)
+       INITIRQ(sa1100_init_irq)
+ MACHINE_END
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/stork.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/stork.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/stork.c     2003-09-27 11:38:18.778673592 +0800
+@@ -8,8 +8,6 @@
+  * published by the Free Software Foundation.
+  *
+  */
+-
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+Index: linux-2.6.0-test5/arch/arm/mach-sa1100/trizeps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-sa1100/trizeps.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-sa1100/trizeps.c   2003-09-27 11:38:18.780673288 +0800
+@@ -12,7 +12,6 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/arch/arm/mach-tbox/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mach-tbox/core.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mach-tbox/core.c        2003-09-27 11:38:18.782672984 +0800
+@@ -16,7 +16,6 @@
+ #include <asm/io.h>
+ #include <asm/pgtable.h>
+ #include <asm/page.h>
+-#include <asm/io.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+Index: linux-2.6.0-test5/arch/arm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/Makefile   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/Makefile        2003-09-27 11:38:18.784672680 +0800
+@@ -27,7 +27,6 @@
+ AFLAGS                += -mbig-endian
+ endif
+-check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+ comma = ,
+ # This selects which instruction set is used.
+@@ -172,22 +171,6 @@
+ i:;   $(Q)$(MAKE) $(build)=$(boot) install
+ zi:;  $(Q)$(MAKE) $(build)=$(boot) zinstall
+-#
+-# Configuration targets.  Use these to select a
+-# configuration for your architecture
+-%_config:
+-      @( \
+-      CFG=$(@:_config=); \
+-      if [ -f arch/arm/def-configs/$$CFG ]; then \
+-        [ -f .config ] && mv -f .config .config.old; \
+-        cp arch/arm/def-configs/$$CFG .config; \
+-        echo "*** Default configuration for $$CFG installed"; \
+-        echo "*** Next, you may run 'make oldconfig'"; \
+-      else \
+-        echo "$$CFG does not exist"; \
+-      fi; \
+-      )
+-
+ arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
+                                  include/asm-arm/.arch \
+                                  include/config/MARKER
+Index: linux-2.6.0-test5/arch/arm/mm/abort-ev5tj.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/abort-ev5tj.S   2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/abort-ev5tj.S        2003-09-27 11:38:18.785672528 +0800
+@@ -0,0 +1,36 @@
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++/*
++ * Function: v5tj_early_abort
++ *
++ * Params  : r2 = address of aborted instruction
++ *         : r3 = saved SPSR
++ *
++ * Returns : r0 = address of abort
++ *       : r1 = FSR, bit 11 = write
++ *       : r2-r8 = corrupted
++ *       : r9 = preserved
++ *       : sp = pointer to registers
++ *
++ * Purpose : obtain information about current aborted instruction.
++ * Note: we read user space.  This means we might cause a data
++ * abort here if the I-TLB and D-TLB aren't seeing the same
++ * picture.  Unfortunately, this does happen.  We live with it.
++ */
++      .align  5
++ENTRY(v5tj_early_abort)
++      mrc     p15, 0, r1, c5, c0, 0           @ get FSR
++      mrc     p15, 0, r0, c6, c0, 0           @ get FAR
++      bic     r1, r1, #1 << 11 | 1 << 10      @ clear bits 11 and 10 of FSR
++      tst     r3, #PSR_J_BIT                  @ Java?
++      orrne   r1, r1, #1 << 11                @ always assume write
++      movne   pc, lr
++      tst     r3, #PSR_T_BIT                  @ Thumb?
++      ldrneh  r3, [r2]                        @ read aborted thumb instruction
++      ldreq   r3, [r2]                        @ read aborted ARM instruction
++      movne   r3, r3, lsl #(21 - 12)          @ move thumb bit 11 to ARM bit 20
++      tst     r3, #1 << 20                    @ L = 0 -> write
++      orreq   r1, r1, #1 << 11                @ yes.
++      mov     pc, lr
++
++
+Index: linux-2.6.0-test5/arch/arm/mm/abort-ev5t.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/abort-ev5t.S    2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/abort-ev5t.S 2003-09-27 11:38:18.785672528 +0800
+@@ -0,0 +1,31 @@
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++/*
++ * Function: v5t_early_abort
++ *
++ * Params  : r2 = address of aborted instruction
++ *         : r3 = saved SPSR
++ *
++ * Returns : r0 = address of abort
++ *       : r1 = FSR, bit 11 = write
++ *       : r2-r8 = corrupted
++ *       : r9 = preserved
++ *       : sp = pointer to registers
++ *
++ * Purpose : obtain information about current aborted instruction.
++ * Note: we read user space.  This means we might cause a data
++ * abort here if the I-TLB and D-TLB aren't seeing the same
++ * picture.  Unfortunately, this does happen.  We live with it.
++ */
++      .align  5
++ENTRY(v5t_early_abort)
++      mrc     p15, 0, r1, c5, c0, 0           @ get FSR
++      mrc     p15, 0, r0, c6, c0, 0           @ get FAR
++      tst     r3, #PSR_T_BIT
++      ldrneh  r3, [r2]                        @ read aborted thumb instruction
++      ldreq   r3, [r2]                        @ read aborted ARM instruction
++      bic     r1, r1, #1 << 11                @ clear bits 11 of FSR
++      movne   r3, r3, lsl #(21 - 12)          @ move thumb bit 11 to ARM bit 20
++      tst     r3, #1 << 20                    @ check write
++      orreq   r1, r1, #1 << 11
++      mov     pc, lr
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v3.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v3.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v3.S   2003-09-27 11:38:18.786672376 +0800
+@@ -8,6 +8,7 @@
+  * published by the Free Software Foundation.
+  */
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -107,6 +108,9 @@
+ ENTRY(v3_dma_clean_range)
+       mov     pc, lr
++      __INITDATA
++
++      .type   v3_cache_fns, #object
+ ENTRY(v3_cache_fns)
+       .long   v3_flush_kern_cache_all
+       .long   v3_flush_user_cache_all
+@@ -116,3 +120,4 @@
+       .long   v3_dma_inv_range
+       .long   v3_dma_clean_range
+       .long   v3_dma_flush_range
++      .size   v3_cache_fns, . - v3_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v4.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v4.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v4.S   2003-09-27 11:38:18.788672072 +0800
+@@ -8,6 +8,7 @@
+  * published by the Free Software Foundation.
+  */
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -109,6 +110,9 @@
+ ENTRY(v4_dma_clean_range)
+       mov     pc, lr
++      __INITDATA
++
++      .type   v4_cache_fns, #object
+ ENTRY(v4_cache_fns)
+       .long   v4_flush_kern_cache_all
+       .long   v4_flush_user_cache_all
+@@ -118,3 +122,4 @@
+       .long   v4_dma_inv_range
+       .long   v4_dma_clean_range
+       .long   v4_dma_flush_range
++      .size   v4_cache_fns, . - v4_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v4wb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v4wb.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v4wb.S 2003-09-27 11:38:18.790671768 +0800
+@@ -7,7 +7,9 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
++#include <linux/config.h>
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -185,6 +187,9 @@
+       .globl  v4wb_dma_flush_range
+       .set    v4wb_dma_flush_range, v4wb_coherent_kern_range
++      __INITDATA
++
++      .type   v4wb_cache_fns, #object
+ ENTRY(v4wb_cache_fns)
+       .long   v4wb_flush_kern_cache_all
+       .long   v4wb_flush_user_cache_all
+@@ -194,3 +199,4 @@
+       .long   v4wb_dma_inv_range
+       .long   v4wb_dma_clean_range
+       .long   v4wb_dma_flush_range
++      .size   v4wb_cache_fns, . - v4wb_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/cache-v4wt.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/cache-v4wt.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/cache-v4wt.S 2003-09-27 11:38:18.792671464 +0800
+@@ -12,6 +12,7 @@
+  *  We assume that the write buffer is not enabled.
+  */
+ #include <linux/linkage.h>
++#include <linux/init.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+ #include "proc-macros.S"
+@@ -158,6 +159,9 @@
+       .globl  v4wt_dma_flush_range
+       .equ    v4wt_dma_flush_range, v4wt_dma_inv_range
++      __INITDATA
++
++      .type   v4wt_cache_fns, #object
+ ENTRY(v4wt_cache_fns)
+       .long   v4wt_flush_kern_cache_all
+       .long   v4wt_flush_user_cache_all
+@@ -167,4 +171,4 @@
+       .long   v4wt_dma_inv_range
+       .long   v4wt_dma_clean_range
+       .long   v4wt_dma_flush_range
+-
++      .size   v4wt_cache_fns, . - v4wt_cache_fns
+Index: linux-2.6.0-test5/arch/arm/mm/consistent.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/consistent.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/consistent.c 2003-09-27 11:38:18.795671008 +0800
+@@ -9,7 +9,6 @@
+  *
+  *  DMA uncached mapping support.
+  */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v3.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v3.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v3.S        2003-09-27 11:38:18.797670704 +0800
+@@ -58,8 +58,10 @@
+       bne     1b                              @ 1
+       ldr     pc, [sp], #4
+-      __INIT
++      __INITDATA
++      .type   v3_user_fns, #object
+ ENTRY(v3_user_fns)
+       .long   v3_clear_user_page
+       .long   v3_copy_user_page
++      .size   v3_user_fns, . - v3_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v4mc.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v4mc.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v4mc.S      2003-09-27 11:38:18.798670552 +0800
+@@ -71,9 +71,10 @@
+       bne     1b                              @ 1
+       ldr     pc, [sp], #4
+-      __INIT
++      __INITDATA
++      .type   v4_mc_user_fns, #object
+ ENTRY(v4_mc_user_fns)
+       .long   v4_mc_clear_user_page
+       .long   v4_mc_copy_user_page
+-
++      .size   v4_mc_user_fns, . - v4_mc_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v4wb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v4wb.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v4wb.S      2003-09-27 11:38:18.799670400 +0800
+@@ -70,9 +70,10 @@
+       mcr     p15, 0, r1, c7, c10, 4          @ 1   drain WB
+       ldr     pc, [sp], #4
+-      __INIT
++      __INITDATA
++      .type   v4wb_user_fns, #object
+ ENTRY(v4wb_user_fns)
+       .long   v4wb_clear_user_page
+       .long   v4wb_copy_user_page
+-
++      .size   v4wb_user_fns, . - v4wb_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-v4wt.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-v4wt.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-v4wt.S      2003-09-27 11:38:18.801670096 +0800
+@@ -64,9 +64,10 @@
+       mcr     p15, 0, r2, c7, c7, 0           @ flush ID cache
+       ldr     pc, [sp], #4
+-      __INIT
++      __INITDATA
++      .type   v4wt_user_fns, #object
+ ENTRY(v4wt_user_fns)
+       .long   v4wt_clear_user_page
+       .long   v4wt_copy_user_page
+-
++      .size   v4wt_user_fns, . - v4wt_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/copypage-xscale.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/copypage-xscale.S       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/copypage-xscale.S    2003-09-27 11:38:18.802669944 +0800
+@@ -104,8 +104,10 @@
+       bne     1b
+       mov     pc, lr
+-      __INIT
++      __INITDATA
++      .type   xscale_mc_user_fns, #object
+ ENTRY(xscale_mc_user_fns)
+       .long   xscale_mc_clear_user_page
+       .long   xscale_mc_copy_user_page
++      .size   xscale_mc_user_fns, . - xscale_mc_user_fns
+Index: linux-2.6.0-test5/arch/arm/mm/discontig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/discontig.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/discontig.c  2003-09-27 11:38:18.804669640 +0800
+@@ -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] },
+Index: linux-2.6.0-test5/arch/arm/mm/fault-armv.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/fault-armv.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/fault-armv.c 2003-09-27 11:38:18.806669336 +0800
+@@ -14,9 +14,11 @@
+ #include <linux/ptrace.h>
+ #include <linux/mm.h>
+ #include <linux/bitops.h>
++#include <linux/vmalloc.h>
+ #include <linux/init.h>
+ #include <asm/cacheflush.h>
++#include <asm/io.h>
+ #include <asm/pgalloc.h>
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
+@@ -127,6 +129,8 @@
+       do_translation_fault(addr, 0, regs);
+ }
++static unsigned long shared_pte_mask = L_PTE_CACHEABLE;
++
+ /*
+  * We take the easy way out of this problem - we make the
+  * PTE uncacheable.  However, we leave the write buffer on.
+@@ -157,9 +161,9 @@
+        * If this page isn't present, or is already setup to
+        * fault (ie, is old), we can safely ignore any issues.
+        */
+-      if (pte_present(entry) && pte_val(entry) & L_PTE_CACHEABLE) {
++      if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
+               flush_cache_page(vma, address);
+-              pte_val(entry) &= ~L_PTE_CACHEABLE;
++              pte_val(entry) &= ~shared_pte_mask;
+               set_pte(pte, entry);
+               flush_tlb_page(vma, address);
+               ret = 1;
+@@ -297,3 +301,65 @@
+               make_coherent(vma, addr, page, dirty);
+       }
+ }
++
++/*
++ * Check whether the write buffer has physical address aliasing
++ * issues.  If it has, we need to avoid them for the case where
++ * we have several shared mappings of the same object in user
++ * space.
++ */
++static int __init check_writebuffer(unsigned long *p1, unsigned long *p2)
++{
++      register unsigned long zero = 0, one = 1, val;
++
++      local_irq_disable();
++      mb();
++      *p1 = one;
++      mb();
++      *p2 = zero;
++      mb();
++      val = *p1;
++      mb();
++      local_irq_enable();
++      return val != zero;
++}
++
++void __init check_writebuffer_bugs(void)
++{
++      struct page *page;
++      const char *reason;
++      unsigned long v = 1;
++
++      printk(KERN_INFO "CPU: Testing write buffer coherency: ");
++
++      page = alloc_page(GFP_KERNEL);
++      if (page) {
++              unsigned long *p1, *p2;
++              pgprot_t prot = __pgprot(L_PTE_PRESENT|L_PTE_YOUNG|
++                                       L_PTE_DIRTY|L_PTE_WRITE|
++                                       L_PTE_BUFFERABLE);
++
++              p1 = vmap(&page, 1, VM_IOREMAP, prot);
++              p2 = vmap(&page, 1, VM_IOREMAP, prot);
++
++              if (p1 && p2) {
++                      v = check_writebuffer(p1, p2);
++                      reason = "enabling work-around";
++              } else {
++                      reason = "unable to map memory\n";
++              }
++
++              vunmap(p1);
++              vunmap(p2);
++              put_page(page);
++      } else {
++              reason = "unable to grab page\n";
++      }
++
++      if (v) {
++              printk("failed, %s\n", reason);
++              shared_pte_mask |= L_PTE_BUFFERABLE;
++      } else {
++              printk("ok\n");
++      }
++}
+Index: linux-2.6.0-test5/arch/arm/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/init.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/init.c       2003-09-27 11:38:18.811668576 +0800
+@@ -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 @@
+ {
+       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 @@
+                        * 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 @@
+  */
+ 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;
+Index: linux-2.6.0-test5/arch/arm/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/ioremap.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/ioremap.c    2003-09-27 11:38:18.813668272 +0800
+@@ -150,7 +150,7 @@
+       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;
+       }
+Index: linux-2.6.0-test5/arch/arm/mm/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/Kconfig 2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/Kconfig      2003-09-27 11:38:18.814668120 +0800
+@@ -0,0 +1,344 @@
++comment "Processor Type"
++
++config CPU_32
++      bool
++      default y
++
++# Select CPU types depending on the architecture selected.  This selects
++# which CPUs we support in the kernel image, and the compiler instruction
++# optimiser behaviour.
++
++# ARM610
++config CPU_ARM610
++      bool "Support ARM610 processor"
++      depends on ARCH_RPC
++      select CPU_32v3
++      select CPU_CACHE_V3
++      select CPU_COPY_V3
++      select CPU_TLB_V3
++      help
++        The ARM610 is the successor to the ARM3 processor
++        and was produced by VLSI Technology Inc.
++
++        Say Y if you want support for the ARM610 processor.
++        Otherwise, say N.
++
++# ARM710
++config CPU_ARM710
++      bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC
++      default y if ARCH_CLPS7500
++      select CPU_32v3
++      select CPU_CACHE_V3
++      select CPU_COPY_V3
++      select CPU_TLB_V3
++      help
++        A 32-bit RISC microprocessor based on the ARM7 processor core
++        designed by Advanced RISC Machines Ltd. The ARM710 is the
++        successor to the ARM610 processor. It was released in
++        July 1994 by VLSI Technology Inc.
++
++        Say Y if you want support for the ARM710 processor.
++        Otherwise, say N.
++
++# ARM720T
++config CPU_ARM720T
++      bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
++      default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712
++      select CPU_32v4
++      select CPU_ABRT_LV4T
++      select CPU_CACHE_V4
++      select CPU_COPY_V4WT
++      select CPU_TLB_V4WT
++      help
++        A 32-bit RISC processor with 8kByte Cache, Write Buffer and
++        MMU built around an ARM7TDMI core.
++
++        Say Y if you want support for the ARM720T processor.
++        Otherwise, say N.
++
++# ARM920T
++config CPU_ARM920T
++      bool "Support ARM920T processor"
++      depends on ARCH_INTEGRATOR
++      select CPU_32v4
++      select CPU_ABRT_EV4T
++      select CPU_CACHE_V4WT
++      select CPU_COPY_V4WB
++      select CPU_TLB_V4WBI
++      help
++        The ARM920T is licensed to be produced by numerous vendors,
++        and is used in the Maverick EP9312.  More information at
++        <http://linuxdevices.com/products/PD2382866068.html>.
++
++        Say Y if you want support for the ARM920T processor.
++        Otherwise, say N.
++
++# ARM922T
++config CPU_ARM922T
++      bool
++      depends on ARCH_CAMELOT
++      default y
++      select CPU_32v4
++      select CPU_ABRT_EV4T
++      select CPU_CACHE_V4WT
++      select CPU_COPY_V4WB
++      select CPU_TLB_V4WBI
++      help
++        The ARM922T is a version of the ARM920T, but with smaller
++        instruction and data caches. It is used in Altera's
++        Excalibur XA device family.
++
++        Say Y if you want support for the ARM922T processor.
++        Otherwise, say N.
++
++# ARM926T
++config CPU_ARM926T
++      bool "Support ARM926T processor"
++      depends on ARCH_INTEGRATOR
++      select CPU_32v5
++      select CPU_ABRT_EV5TJ
++      select CPU_COPY_V4WB
++      select CPU_TLB_V4WBI
++      help
++        This is a variant of the ARM920.  It has slightly different
++        instruction sequences for cache and TLB operations.  Curiously,
++        there is no documentation on it at the ARM corporate website.
++
++        Say Y if you want support for the ARM926T processor.
++        Otherwise, say N.
++
++# ARM1020 - needs validating
++config CPU_ARM1020
++      bool "Support ARM1020T (rev 0) processor"
++      depends on ARCH_INTEGRATOR
++      select CPU_32v5
++      select CPU_ABRT_EV4T
++      select CPU_CACHE_V4WT
++      select CPU_COPY_V4WB
++      select CPU_TLB_V4WBI
++      help
++        The ARM1020 is the 32K cached version of the ARM10 processor,
++        with an addition of a floating-point unit.
++
++        Say Y if you want support for the ARM1020 processor.
++        Otherwise, say N.
++
++# ARM1020E - needs validating
++config CPU_ARM1020E
++      bool "Support ARM1020E processor"
++      depends on ARCH_INTEGRATOR
++      select CPU_32v5
++      select CPU_ABRT_EV4T
++      select CPU_CACHE_V4WT
++      select CPU_COPY_V4WB
++      select CPU_TLB_V4WBI
++      depends on n
++
++# ARM1022E
++config CPU_ARM1022
++      bool "Support ARM1022E processor"
++      depends on ARCH_INTEGRATOR
++      select CPU_32v5
++      select CPU_ABRT_EV4T
++      select CPU_COPY_V4WB # can probably do better
++      select CPU_TLB_V4WBI
++      help
++        The ARM1022E is an implementation of the ARMv5TE architecture
++        based upon the ARM10 integer core with a 16KiB L1 Harvard cache,
++        embedded trace macrocell, and a floating-point unit.
++
++        Say Y if you want support for the ARM1022E processor.
++        Otherwise, say N.
++
++# ARM1026EJ-S
++config CPU_ARM1026
++      bool "Support ARM1026EJ-S processor"
++      depends on ARCH_INTEGRATOR
++      select CPU_32v5
++      select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
++      select CPU_COPY_V4WB # can probably do better
++      select CPU_TLB_V4WBI
++      help
++        The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture
++        based upon the ARM10 integer core.
++
++        Say Y if you want support for the ARM1026EJ-S processor.
++        Otherwise, say N.
++
++# SA110
++config CPU_SA110
++      bool "Support StrongARM(R) SA-110 processor" if !ARCH_EBSA110 && !FOOTBRIDGE && !ARCH_TBOX && !ARCH_SHARK && !ARCH_NEXUSPCI && !ARCH_ANAKIN && ARCH_RPC
++      default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_TBOX || ARCH_SHARK || ARCH_NEXUSPCI || ARCH_ANAKIN
++      select CPU_32v3 if ARCH_RPC
++      select CPU_32v4 if !ARCH_RPC
++      select CPU_ABRT_EV4
++      select CPU_CACHE_V4WB
++      select CPU_COPY_V4WB
++      select CPU_TLB_V4WB
++      help
++        The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and
++        is available at five speeds ranging from 100 MHz to 233 MHz.
++        More information is available at
++        <http://developer.intel.com/design/strong/sa110.htm>.
++
++        Say Y if you want support for the SA-110 processor.
++        Otherwise, say N.
++
++# SA1100
++config CPU_SA1100
++      bool
++      depends on ARCH_SA1100
++      default y
++      select CPU_32v4
++      select CPU_ABRT_EV4
++      select CPU_CACHE_V4WB
++      select CPU_TLB_V4WB
++      select CPU_MINICACHE
++
++# XScale
++config CPU_XSCALE
++      bool
++      depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA
++      default y
++      select CPU_32v5
++      select CPU_ABRT_EV5T
++      select CPU_TLB_V4WBI
++      select CPU_MINICACHE
++
++# This defines the compiler instruction set which depends on the machine type.
++config CPU_32v3
++      bool
++
++config CPU_32v4
++      bool
++
++config CPU_32v5
++      bool
++
++# The abort model
++config CPU_ABRT_EV4
++      bool
++
++config CPU_ABRT_EV4T
++      bool
++
++config CPU_ABRT_LV4T
++      bool
++
++config CPU_ABRT_EV5T
++      bool
++
++config CPU_ABRT_EV5TJ
++      bool
++
++# The cache model
++config CPU_CACHE_V3
++      bool
++
++config CPU_CACHE_V4
++      bool
++
++config CPU_CACHE_V4WT
++      bool
++
++config CPU_CACHE_V4WB
++      bool
++
++# The copy-page model
++config CPU_COPY_V3
++      bool
++
++config CPU_COPY_V4WT
++      bool
++
++config CPU_COPY_V4WB
++      bool
++
++# This selects the TLB model
++config CPU_TLB_V3
++      bool
++      help
++        ARM Architecture Version 3 TLB.
++
++config CPU_TLB_V4WT
++      bool
++      help
++        ARM Architecture Version 4 TLB with writethrough cache.
++
++config CPU_TLB_V4WB
++      bool
++      help
++        ARM Architecture Version 4 TLB with writeback cache.
++
++config CPU_TLB_V4WBI
++      bool
++      help
++        ARM Architecture Version 4 TLB with writeback cache and invalidate
++        instruction cache entry.
++
++config CPU_TLB_V6
++      bool
++
++config CPU_MINICACHE
++      bool
++      help
++        Processor has a minicache.
++
++comment "Processor Features"
++
++config ARM_THUMB
++      bool "Support Thumb user binaries"
++      depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE
++      default y
++      help
++        Say Y if you want to have kernel support for ARM Thumb instructions,
++        fault handlers, and system calls.
++
++        The Thumb instruction set is a compressed form of the standard ARM
++        instruction set resulting in smaller binaries at the expense of
++        slightly less efficient code.
++
++        If you don't know what this all is, saying Y is a safe choice.
++
++config CPU_BIG_ENDIAN
++      bool "Build big-endian kernel"
++      depends on ARCH_SUPPORTS_BIG_ENDIAN
++      help
++        Say Y if you plan on running a kernel in big-endian mode.
++        Note that your board must be properly built and your board
++        port must properly enable and big-endian related features
++        of your chipset/board/processor.
++
++config CPU_ICACHE_DISABLE
++      bool "Disable I-Cache"
++      depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
++      help
++        Say Y here to disable the processor instruction cache. Unless
++        you have a reason not to or are unsure, say N.
++
++config CPU_DCACHE_DISABLE
++      bool "Disable D-Cache"
++      depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020
++      help
++        Say Y here to disable the processor data cache. Unless
++        you have a reason not to or are unsure, say N.
++
++config CPU_DCACHE_WRITETHROUGH
++      bool "Force write through D-cache"
++      depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM926T || CPU_ARM1020) && !CPU_DISABLE_DCACHE
++      help
++        Say Y here to use the data cache in writethough mode. Unless you
++        specifically require this or are unsure, say N.
++
++config CPU_CACHE_ROUND_ROBIN
++      bool "Round robin I and D cache replacement algorithm"
++      depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
++      help
++        Say Y here to use the predictable round-robin cache replacement
++        policy.  Unless you specifically require this or are unsure, say N.
++
++config CPU_BPREDICT_DISABLE
++      bool "Disable branch prediction"
++      depends on CPU_ARM1020
++      help
++        Say Y here to disable branch prediction.  If unsure, say N.
+Index: linux-2.6.0-test5/arch/arm/mm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/Makefile        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/Makefile     2003-09-27 11:38:18.816667816 +0800
+@@ -2,29 +2,48 @@
+ # Makefile for the linux arm-specific parts of the memory manager.
+ #
+-# Object file lists.
++obj-y                         := consistent.o extable.o fault-armv.o \
++                                 fault-common.o init.o ioremap.o mm-armv.o
+-obj-y         := consistent.o extable.o fault-armv.o fault-common.o \
+-                 init.o ioremap.o mm-armv.o
+-obj-$(CONFIG_MODULES) += proc-syms.o
+-
+-obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
+-obj-$(CONFIG_DISCONTIGMEM) += discontig.o
+-
+-# ARMv3
+-p-$(CONFIG_CPU_ARM610)        += proc-arm6_7.o  tlb-v3.o    cache-v3.o    copypage-v3.o
+-p-$(CONFIG_CPU_ARM710)        += proc-arm6_7.o  tlb-v3.o    cache-v3.o    copypage-v3.o
+-
+-# ARMv4
+-p-$(CONFIG_CPU_ARM720T)       += proc-arm720.o  tlb-v4.o    cache-v4.o    copypage-v4wt.o abort-lv4t.o
+-p-$(CONFIG_CPU_ARM920T)       += proc-arm920.o  tlb-v4wbi.o cache-v4wt.o  copypage-v4wb.o abort-ev4t.o
+-p-$(CONFIG_CPU_ARM922T)       += proc-arm922.o  tlb-v4wbi.o cache-v4wt.o  copypage-v4wb.o abort-ev4t.o
+-p-$(CONFIG_CPU_ARM1020)       += proc-arm1020.o tlb-v4wbi.o cache-v4wt.o  copypage-v4wb.o abort-ev4t.o
+-p-$(CONFIG_CPU_SA110) += proc-sa110.o   tlb-v4wb.o  cache-v4wb.o  copypage-v4wb.o abort-ev4.o
+-p-$(CONFIG_CPU_SA1100)        += proc-sa1100.o  tlb-v4wb.o  cache-v4wb.o  copypage-v4mc.o abort-ev4.o   minicache.o
+-
+-# ARMv5
+-p-$(CONFIG_CPU_ARM926T)       += proc-arm926.o  tlb-v4wbi.o copypage-v4wb.o abort-ev5tej.o
+-p-$(CONFIG_CPU_XSCALE)        += proc-xscale.o  tlb-v4wbi.o copypage-xscale.o abort-xscale.o minicache.o
++obj-$(CONFIG_MODULES)         += proc-syms.o
+-obj-y         += $(sort $(p-y))
++obj-$(CONFIG_ALIGNMENT_TRAP)  += alignment.o
++obj-$(CONFIG_DISCONTIGMEM)    += discontig.o
++
++obj-$(CONFIG_CPU_ABRT_EV4)    += abort-ev4.o
++obj-$(CONFIG_CPU_ABRT_EV4T)   += abort-ev4t.o
++obj-$(CONFIG_CPU_ABRT_LV4T)   += abort-lv4t.o
++obj-$(CONFIG_CPU_ABRT_EV5T)   += abort-ev5t.o
++obj-$(CONFIG_CPU_ABRT_EV5TJ)  += abort-ev5tj.o
++
++obj-$(CONFIG_CPU_CACHE_V3)    += cache-v3.o
++obj-$(CONFIG_CPU_CACHE_V4)    += cache-v4.o
++obj-$(CONFIG_CPU_CACHE_V4WT)  += cache-v4wt.o
++obj-$(CONFIG_CPU_CACHE_V4WB)  += cache-v4wb.o
++
++obj-$(CONFIG_CPU_COPY_V3)     += copypage-v3.o
++obj-$(CONFIG_CPU_COPY_V4WT)   += copypage-v4wt.o
++obj-$(CONFIG_CPU_COPY_V4WB)   += copypage-v4wb.o
++obj-$(CONFIG_CPU_SA1100)      += copypage-v4mc.o
++obj-$(CONFIG_CPU_XSCALE)      += copypage-xscale.o
++
++obj-$(CONFIG_CPU_MINICACHE)   += minicache.o
++
++obj-$(CONFIG_CPU_TLB_V3)      += tlb-v3.o
++obj-$(CONFIG_CPU_TLB_V4WT)    += tlb-v4.o
++obj-$(CONFIG_CPU_TLB_V4WB)    += tlb-v4wb.o
++obj-$(CONFIG_CPU_TLB_V4WBI)   += tlb-v4wbi.o
++
++obj-$(CONFIG_CPU_ARM610)      += proc-arm6_7.o
++obj-$(CONFIG_CPU_ARM710)      += proc-arm6_7.o
++obj-$(CONFIG_CPU_ARM720T)     += proc-arm720.o
++obj-$(CONFIG_CPU_ARM920T)     += proc-arm920.o
++obj-$(CONFIG_CPU_ARM922T)     += proc-arm922.o
++obj-$(CONFIG_CPU_ARM926T)     += proc-arm926.o
++obj-$(CONFIG_CPU_ARM1020)     += proc-arm1020.o
++obj-$(CONFIG_CPU_ARM1020E)    += proc-arm1020e.o
++obj-$(CONFIG_CPU_ARM1022)     += proc-arm1022.o
++obj-$(CONFIG_CPU_ARM1026)     += proc-arm1026.o
++obj-$(CONFIG_CPU_SA110)               += proc-sa110.o
++obj-$(CONFIG_CPU_SA1100)      += proc-sa1100.o
++obj-$(CONFIG_CPU_XSCALE)      += proc-xscale.o
+Index: linux-2.6.0-test5/arch/arm/mm/mm-armv.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/mm-armv.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/mm-armv.c    2003-09-27 11:38:18.820667208 +0800
+@@ -9,6 +9,7 @@
+  *
+  *  Page table sludge for ARM v3 and v4 processor architectures.
+  */
++#include <linux/config.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+@@ -392,12 +393,19 @@
+       long off;
+       if (md->virtual != vectors_base() && md->virtual < PAGE_OFFSET) {
+-              printk(KERN_WARNING "MM: not creating mapping for "
++              printk(KERN_WARNING "BUG: not creating mapping for "
+                      "0x%08lx at 0x%08lx in user region\n",
+                      md->physical, md->virtual);
+               return;
+       }
++      if (md->type == MT_DEVICE &&
++          md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
++              printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx "
++                     "overlaps vmalloc space\n",
++                     md->physical, md->virtual);
++      }
++
+       domain    = mem_types[md->type].domain;
+       prot_pte  = __pgprot(mem_types[md->type].prot_pte);
+       prot_l1   = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
+@@ -409,7 +417,7 @@
+       if (mem_types[md->type].prot_l1 == 0 &&
+           (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
+-              printk(KERN_WARNING "MM: map for 0x%08lx at 0x%08lx can not "
++              printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
+                      "be mapped using pages, ignoring.\n",
+                      md->physical, md->virtual);
+               return;
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1020e.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1020e.S 2003-09-27 11:38:18.430726488 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1020e.S      2003-09-27 11:38:18.821667056 +0800
+@@ -0,0 +1,504 @@
++/*
++ *  linux/arch/arm/mm/proc-arm1020e.S: MMU functions for ARM1020
++ *
++ *  Copyright (C) 2000 ARM Limited
++ *  Copyright (C) 2000 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
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the arm1020e.
++ *
++ *  CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt
++ */
++#include <linux/linkage.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/constants.h>
++#include <asm/pgtable.h>
++#include <asm/procinfo.h>
++#include <asm/ptrace.h>
++#include <asm/hardware.h>
++
++/*
++ * This is the maximum size of an area which will be invalidated
++ * using the single invalidate entry instructions.  Anything larger
++ * than this, and we go for the whole cache.
++ *
++ * This value should be chosen such that we choose the cheapest
++ * alternative.
++ */
++#define MAX_AREA_SIZE 32768
++
++/*
++ * The size of one data cache line.
++ */
++#define CACHE_DLINESIZE       32
++
++/*
++ * The number of data cache segments.
++ */
++#define CACHE_DSEGMENTS       16
++
++/*
++ * The number of lines in a cache segment.
++ */
++#define CACHE_DENTRIES        64
++
++/*
++ * This is the size at which it becomes more efficient to
++ * clean the whole cache, rather than using the individual
++ * cache line maintainence instructions.
++ */
++#define CACHE_DLIMIT  32768
++
++      .text
++/*
++ * cpu_arm1020e_proc_init()
++ */
++ENTRY(cpu_arm1020e_proc_init)
++      mov     pc, lr
++
++/*
++ * cpu_arm1020e_proc_fin()
++ */
++ENTRY(cpu_arm1020e_proc_fin)
++      stmfd   sp!, {lr}
++      mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++      msr     cpsr_c, ip
++      bl      arm1020e_flush_kern_cache_all
++      mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
++      bic     r0, r0, #0x1000                 @ ...i............
++      bic     r0, r0, #0x000e                 @ ............wca.
++      mcr     p15, 0, r0, c1, c0, 0           @ disable caches
++      ldmfd   sp!, {pc}
++
++/*
++ * cpu_arm1020e_reset(loc)
++ *
++ * Perform a soft reset of the system.        Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++      .align  5
++ENTRY(cpu_arm1020e_reset)
++      mov     ip, #0
++      mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
++      mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
++      bic     ip, ip, #0x000f                 @ ............wcam
++      bic     ip, ip, #0x1100                 @ ...i...s........
++      mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
++      mov     pc, r0
++
++/*
++ * cpu_arm1020e_do_idle()
++ */
++      .align  5
++ENTRY(cpu_arm1020e_do_idle)
++      mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
++      mov     pc, lr
++
++/* ================================= CACHE ================================ */
++
++      .align  5
++/*
++ *    flush_user_cache_all()
++ *
++ *    Invalidate all cache entries in a particular address
++ *    space.
++ */
++ENTRY(arm1020e_flush_user_cache_all)
++      /* FALLTHROUGH */
++/*
++ *    flush_kern_cache_all()
++ *
++ *    Clean and invalidate the entire cache.
++ */
++ENTRY(arm1020e_flush_kern_cache_all)
++      mov     r2, #VM_EXEC
++      mov     ip, #0
++__flush_whole_cache:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
++1:    orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
++2:    mcr     p15, 0, r3, c7, c14, 2          @ clean+invalidate D index
++      subs    r3, r3, #1 << 26
++      bcs     2b                              @ entries 63 to 0
++      subs    r1, r1, #1 << 5
++      bcs     1b                              @ segments 15 to 0
++#endif
++      tst     r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++      mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    flush_user_cache_range(start, end, flags)
++ *
++ *    Invalidate a range of cache entries in the specified
++ *    address space.
++ *
++ *    - start - start address (inclusive)
++ *    - end   - end address (exclusive)
++ *    - flags - vm_flags for this space
++ */
++ENTRY(arm1020e_flush_user_cache_range)
++      mov     ip, #0
++      sub     r3, r1, r0                      @ calculate total size
++      cmp     r3, #CACHE_DLIMIT
++      bhs     __flush_whole_cache
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      tst     r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++      mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    coherent_kern_range(start, end)
++ *
++ *    Ensure coherency between the Icache and the Dcache in the
++ *    region described by start.  If you have non-snooping
++ *    Harvard caches, you need to implement this function.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ */
++ENTRY(arm1020e_coherent_kern_range)
++      mov     ip, #0
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
++#endif
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    flush_kern_dcache_page(void *page)
++ *
++ *    Ensure no D cache aliasing occurs, either with itself or
++ *    the I cache
++ *
++ *    - page  - page aligned address
++ */
++ENTRY(arm1020e_flush_kern_dcache_page)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      add     r1, r0, #PAGE_SZ
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_inv_range(start, end)
++ *
++ *    Invalidate (discard) the specified virtual address range.
++ *    May not write back any entries.  If 'start' or 'end'
++ *    are not cache line aligned, those lines must be written
++ *    back.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1020e_dma_inv_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      tst     r0, #CACHE_DLINESIZE - 1
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++      mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
++      tst     r1, #CACHE_DLINESIZE - 1
++      mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
++1:    mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_clean_range(start, end)
++ *
++ *    Clean the specified virtual address range.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1020e_dma_clean_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_flush_range(start, end)
++ *
++ *    Clean and invalidate the specified virtual address range.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ */
++ENTRY(arm1020e_dma_flush_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++ENTRY(arm1020e_cache_fns)
++      .long   arm1020e_flush_kern_cache_all
++      .long   arm1020e_flush_user_cache_all
++      .long   arm1020e_flush_user_cache_range
++      .long   arm1020e_coherent_kern_range
++      .long   arm1020e_flush_kern_dcache_page
++      .long   arm1020e_dma_inv_range
++      .long   arm1020e_dma_clean_range
++      .long   arm1020e_dma_flush_range
++
++      .align  5
++ENTRY(cpu_arm1020e_dcache_clean_area)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mov     ip, #0
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      subs    r1, r1, #CACHE_DLINESIZE
++      bhi     1b
++#endif
++      mov     pc, lr
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_arm1020e_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++      .align  5
++ENTRY(cpu_arm1020e_switch_mm)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, r3, c7, c10, 4
++      mov     r1, #0xF                        @ 16 segments
++1:    mov     r3, #0x3F                       @ 64 entries
++2:    mov     ip, r3, LSL #26                 @ shift up entry
++      orr     ip, ip, r1, LSL #5              @ shift in/up index
++      mcr     p15, 0, ip, c7, c14, 2          @ Clean & Inval DCache entry
++      mov     ip, #0
++      subs    r3, r3, #1
++      cmp     r3, #0
++      bge     2b                              @ entries 3F to 0
++      subs    r1, r1, #1
++      cmp     r1, #0
++      bge     1b                              @ segments 15 to 0
++
++#endif
++      mov     r1, #0
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, r1, c7, c5, 0           @ invalidate I cache
++#endif
++      mcr     p15, 0, r1, c7, c10, 4          @ drain WB
++      mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
++      mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
++      mov     pc, lr
++        
++/*
++ * cpu_arm1020e_set_pte(ptep, pte)
++ *
++ * Set a PTE and flush it out
++ */
++      .align  5
++ENTRY(cpu_arm1020e_set_pte)
++      str     r1, [r0], #-2048                @ linux version
++
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
++
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
++
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
++      movne   r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      eor     r3, r1, #0x0a                   @ C & small page?
++      tst     r3, #0x0b
++      biceq   r2, r2, #4
++#endif
++      str     r2, [r0]                        @ hardware version
++      mov     r0, r0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++#endif
++      mov     pc, lr
++
++      __INIT
++
++      .type   __arm1020e_setup, #function
++__arm1020e_setup:
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
++      mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
++      mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs on v4
++      mcr     p15, 0, r4, c2, c0              @ load page table pointer
++      mov     r0, #0x1f                       @ Domains 0, 1 = client
++      mcr     p15, 0, r0, c3, c0              @ load domain access register
++      mrc     p15, 0, r0, c1, c0              @ get control register v4
++/*
++ * Clear out 'unwanted' bits (then put them in if we need them)
++ */
++      bic     r0, r0, #0x1e00                 @ i...??r.........
++      bic     r0, r0, #0x000e                 @ ............wca.
++/*
++ * Turn on what we want
++ */
++      orr     r0, r0, #0x0031                 @ ..........DP...M
++      orr     r0, r0, #0x0100                 @ .......S........
++
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      orr     r0, r0, #0x4000                 @ .R..............
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++      orr     r0, r0, #0x0800                 @ ....Z...........
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      orr     r0, r0, #0x0004                 @ Enable D cache
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      orr     r0, r0, #0x1000                 @ I Cache on
++#endif
++      mov     pc, lr
++      .size   __arm1020e_setup, . - __arm1020e_setup
++
++      __INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ *         come through these
++ */
++      .type   arm1020e_processor_functions, #object
++arm1020e_processor_functions:
++      .word   v4t_early_abort
++      .word   cpu_arm1020e_proc_init
++      .word   cpu_arm1020e_proc_fin
++      .word   cpu_arm1020e_reset
++      .word   cpu_arm1020e_do_idle
++      .word   cpu_arm1020e_dcache_clean_area
++      .word   cpu_arm1020e_switch_mm
++      .word   cpu_arm1020e_set_pte
++      .size   arm1020e_processor_functions, . - arm1020e_processor_functions
++
++      .section ".rodata"
++
++      .type   cpu_arch_name, #object
++cpu_arch_name:
++      .asciz  "armv5te"
++      .size   cpu_arch_name, . - cpu_arch_name
++
++      .type   cpu_elf_name, #object
++cpu_elf_name:
++      .asciz  "v5"
++      .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_arm1020e_name, #object
++cpu_arm1020e_name:
++      .ascii  "ARM1020E"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++      .ascii  "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      .ascii  "RR"
++#endif
++      .ascii  "\0"
++      .size   cpu_arm1020e_name, . - cpu_arm1020e_name
++
++      .align
++
++      .section ".proc.info", #alloc, #execinstr
++
++      .type   __arm1020e_proc_info,#object
++__arm1020e_proc_info:
++      .long   0x4105a200                      @ ARM 1020TE (Architecture v5TE)
++      .long   0xff0ffff0
++      .long   0x00000c12                      @ mmuflags
++      b       __arm1020e_setup
++      .long   cpu_arch_name
++      .long   cpu_elf_name
++      .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
++      .long   cpu_arm1020e_name
++      .long   arm1020e_processor_functions
++      .long   v4wbi_tlb_fns
++      .long   v4wb_user_fns
++      .long   arm1020e_cache_fns
++      .size   __arm1020e_proc_info, . - __arm1020e_proc_info
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1020.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1020.S  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1020.S       2003-09-27 11:38:18.826666296 +0800
+@@ -1,5 +1,5 @@
+ /*
+- *  linux/arch/arm/mm/arm1020.S: MMU functions for ARM1020
++ *  linux/arch/arm/mm/proc-arm1020.S: MMU functions for ARM1020
+  *
+  *  Copyright (C) 2000 ARM Limited
+  *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+@@ -29,6 +29,7 @@
+ #include <linux/init.h>
+ #include <asm/assembler.h>
+ #include <asm/constants.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/ptrace.h>
+ #include <asm/hardware.h>
+@@ -379,19 +380,19 @@
+ ENTRY(cpu_arm1020_set_pte)
+       str     r1, [r0], #-2048                @ linux version
+-      eor     r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-      bic     r2, r1, #0xff0
+-      bic     r2, r2, #3
+-      orr     r2, r2, #HPTE_TYPE_SMALL
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
+-      tst     r1, #LPTE_USER                  @ User?
+-      orrne   r2, r2, #HPTE_AP_READ
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+-      tst     r1, #LPTE_WRITE | LPTE_DIRTY    @ Write and Dirty?
+-      orreq   r2, r2, #HPTE_AP_WRITE
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
+-      tst     r1, #LPTE_PRESENT | LPTE_YOUNG  @ Present and Young?
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
+       movne   r2, #0
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -408,31 +409,9 @@
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+-
+-ENTRY(cpu_arm1020_name)
+-      .ascii  "Arm1020"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+-      .ascii  "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+-      .ascii  "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+-      .ascii  "(wt)"
+-#else
+-      .ascii  "(wb)"
+-#endif
+-#endif
+-#ifndef CONFIG_CPU_BPREDICT_DISABLE
+-      .ascii  "B"
+-#endif
+-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+-      .ascii  "RR"
+-#endif
+-      .ascii  "\0"
+-      .align
+-
+       __INIT
++      .type   __arm1020_setup, #function
+ __arm1020_setup:
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
+@@ -445,10 +424,8 @@
+ /*
+  * Clear out 'unwanted' bits (then put them in if we need them)
+  */
+-      bic     r0, r0, #0x0e00                 @ ....??r.........
+-      bic     r0, r0, #0x0002                 @ ..............a.
+-      bic     r0, r0, #0x000c                 @ W,D
+-      bic     r0, r0, #0x1000                 @ I
++      bic     r0, r0, #0x1e00                 @ i...??r.........
++      bic     r0, r0, #0x000e                 @ ............wca.
+ /*
+  * Turn on what we want
+  */
+@@ -468,8 +445,9 @@
+       orr     r0, r0, #0x1000                 @ I Cache on
+ #endif
+       mov     pc, lr
++      .size   __arm1020_setup, . - __arm1020_setup
+-      .text
++      __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -485,26 +463,51 @@
+       .word   cpu_arm1020_dcache_clean_area
+       .word   cpu_arm1020_switch_mm
+       .word   cpu_arm1020_set_pte
+-
+       .size   arm1020_processor_functions, . - arm1020_processor_functions
++      .section ".rodata"
++
+       .type   cpu_arch_name, #object
+ cpu_arch_name:
+-      .asciz  "armv4t"
++      .asciz  "armv5t"
+       .size   cpu_arch_name, . - cpu_arch_name
+       .type   cpu_elf_name, #object
+ cpu_elf_name:
+-      .asciz  "v4"
++      .asciz  "v5"
+       .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_arm1020_name, #object
++cpu_arm1020_name:
++      .ascii  "ARM1020"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++      .ascii  "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      .ascii  "RR"
++#endif
++      .ascii  "\0"
++      .size   cpu_arm1020_name, . - cpu_arm1020_name
++
+       .align
+       .section ".proc.info", #alloc, #execinstr
+       .type   __arm1020_proc_info,#object
+ __arm1020_proc_info:
+-      .long   0x4100a200
+-      .long   0xff00fff0
++      .long   0x4104a200                      @ ARM 1020T (Architecture v5T)
++      .long   0xff0ffff0
+       .long   0x00000c02                      @ mmuflags
+       b       __arm1020_setup
+       .long   cpu_arch_name
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1022.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1022.S  2003-09-27 11:38:18.431726336 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1022.S       2003-09-27 11:38:18.827666144 +0800
+@@ -0,0 +1,484 @@
++/*
++ *  linux/arch/arm/mm/proc-arm1022.S: MMU functions for ARM1022E
++ *
++ *  Copyright (C) 2000 ARM Limited
++ *  Copyright (C) 2000 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.
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the ARM1022E.
++ */
++#include <linux/linkage.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/constants.h>
++#include <asm/pgtable.h>
++#include <asm/procinfo.h>
++#include <asm/ptrace.h>
++
++/*
++ * This is the maximum size of an area which will be invalidated
++ * using the single invalidate entry instructions.  Anything larger
++ * than this, and we go for the whole cache.
++ *
++ * This value should be chosen such that we choose the cheapest
++ * alternative.
++ */
++#define MAX_AREA_SIZE 32768
++
++/*
++ * The size of one data cache line.
++ */
++#define CACHE_DLINESIZE       32
++
++/*
++ * The number of data cache segments.
++ */
++#define CACHE_DSEGMENTS       16
++
++/*
++ * The number of lines in a cache segment.
++ */
++#define CACHE_DENTRIES        64
++
++/*
++ * This is the size at which it becomes more efficient to
++ * clean the whole cache, rather than using the individual
++ * cache line maintainence instructions.
++ */
++#define CACHE_DLIMIT  32768
++
++      .text
++/*
++ * cpu_arm1022_proc_init()
++ */
++ENTRY(cpu_arm1022_proc_init)
++      mov     pc, lr
++
++/*
++ * cpu_arm1022_proc_fin()
++ */
++ENTRY(cpu_arm1022_proc_fin)
++      stmfd   sp!, {lr}
++      mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++      msr     cpsr_c, ip
++      bl      arm1022_flush_kern_cache_all
++      mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
++      bic     r0, r0, #0x1000                 @ ...i............
++      bic     r0, r0, #0x000e                 @ ............wca.
++      mcr     p15, 0, r0, c1, c0, 0           @ disable caches
++      ldmfd   sp!, {pc}
++
++/*
++ * cpu_arm1022_reset(loc)
++ *
++ * Perform a soft reset of the system.        Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++      .align  5
++ENTRY(cpu_arm1022_reset)
++      mov     ip, #0
++      mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
++      mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
++      bic     ip, ip, #0x000f                 @ ............wcam
++      bic     ip, ip, #0x1100                 @ ...i...s........
++      mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
++      mov     pc, r0
++
++/*
++ * cpu_arm1022_do_idle()
++ */
++      .align  5
++ENTRY(cpu_arm1022_do_idle)
++      mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
++      mov     pc, lr
++
++/* ================================= CACHE ================================ */
++
++      .align  5
++/*
++ *    flush_user_cache_all()
++ *
++ *    Invalidate all cache entries in a particular address
++ *    space.
++ */
++ENTRY(arm1022_flush_user_cache_all)
++      /* FALLTHROUGH */
++/*
++ *    flush_kern_cache_all()
++ *
++ *    Clean and invalidate the entire cache.
++ */
++ENTRY(arm1022_flush_kern_cache_all)
++      mov     r2, #VM_EXEC
++      mov     ip, #0
++__flush_whole_cache:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mov     r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
++1:    orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
++2:    mcr     p15, 0, r3, c7, c14, 2          @ clean+invalidate D index
++      subs    r3, r3, #1 << 26
++      bcs     2b                              @ entries 63 to 0
++      subs    r1, r1, #1 << 5
++      bcs     1b                              @ segments 15 to 0
++#endif
++      tst     r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++      mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    flush_user_cache_range(start, end, flags)
++ *
++ *    Invalidate a range of cache entries in the specified
++ *    address space.
++ *
++ *    - start - start address (inclusive)
++ *    - end   - end address (exclusive)
++ *    - flags - vm_flags for this space
++ */
++ENTRY(arm1022_flush_user_cache_range)
++      mov     ip, #0
++      sub     r3, r1, r0                      @ calculate total size
++      cmp     r3, #CACHE_DLIMIT
++      bhs     __flush_whole_cache
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      tst     r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++      mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    coherent_kern_range(start, end)
++ *
++ *    Ensure coherency between the Icache and the Dcache in the
++ *    region described by start.  If you have non-snooping
++ *    Harvard caches, you need to implement this function.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ */
++ENTRY(arm1022_coherent_kern_range)
++      mov     ip, #0
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
++#endif
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    flush_kern_dcache_page(void *page)
++ *
++ *    Ensure no D cache aliasing occurs, either with itself or
++ *    the I cache
++ *
++ *    - page  - page aligned address
++ */
++ENTRY(arm1022_flush_kern_dcache_page)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      add     r1, r0, #PAGE_SZ
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_inv_range(start, end)
++ *
++ *    Invalidate (discard) the specified virtual address range.
++ *    May not write back any entries.  If 'start' or 'end'
++ *    are not cache line aligned, those lines must be written
++ *    back.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1022_dma_inv_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      tst     r0, #CACHE_DLINESIZE - 1
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++      mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
++      tst     r1, #CACHE_DLINESIZE - 1
++      mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
++1:    mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_clean_range(start, end)
++ *
++ *    Clean the specified virtual address range.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1022_dma_clean_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_flush_range(start, end)
++ *
++ *    Clean and invalidate the specified virtual address range.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ */
++ENTRY(arm1022_dma_flush_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++ENTRY(arm1022_cache_fns)
++      .long   arm1022_flush_kern_cache_all
++      .long   arm1022_flush_user_cache_all
++      .long   arm1022_flush_user_cache_range
++      .long   arm1022_coherent_kern_range
++      .long   arm1022_flush_kern_dcache_page
++      .long   arm1022_dma_inv_range
++      .long   arm1022_dma_clean_range
++      .long   arm1022_dma_flush_range
++
++      .align  5
++ENTRY(cpu_arm1022_dcache_clean_area)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mov     ip, #0
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      subs    r1, r1, #CACHE_DLINESIZE
++      bhi     1b
++#endif
++      mov     pc, lr
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_arm1022_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++      .align  5
++ENTRY(cpu_arm1022_switch_mm)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mov     r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
++1:    orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
++2:    mcr     p15, 0, r3, c7, c14, 2          @ clean+invalidate D index
++      subs    r3, r3, #1 << 26
++      bcs     2b                              @ entries 63 to 0
++      subs    r1, r1, #1 << 5
++      bcs     1b                              @ segments 15 to 0
++#endif
++      mov     r1, #0
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, r1, c7, c5, 0           @ invalidate I cache
++#endif
++      mcr     p15, 0, r1, c7, c10, 4          @ drain WB
++      mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
++      mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
++      mov     pc, lr
++        
++/*
++ * cpu_arm1022_set_pte(ptep, pte)
++ *
++ * Set a PTE and flush it out
++ */
++      .align  5
++ENTRY(cpu_arm1022_set_pte)
++      str     r1, [r0], #-2048                @ linux version
++
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
++
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
++
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
++      movne   r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      eor     r3, r1, #0x0a                   @ C & small page?
++      tst     r3, #0x0b
++      biceq   r2, r2, #4
++#endif
++      str     r2, [r0]                        @ hardware version
++      mov     r0, r0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++#endif
++      mov     pc, lr
++
++      __INIT
++
++      .type   __arm1022_setup, #function
++__arm1022_setup:
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
++      mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
++      mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs on v4
++      mcr     p15, 0, r4, c2, c0              @ load page table pointer
++      mov     r0, #0x1f                       @ Domains 0, 1 = client
++      mcr     p15, 0, r0, c3, c0              @ load domain access register
++      mrc     p15, 0, r0, c1, c0              @ get control register v4
++/*
++ * Clear out 'unwanted' bits (then put them in if we need them)
++ */
++      bic     r0, r0, #0x1e00                 @ ...i??r.........
++      bic     r0, r0, #0x000e                 @ ............wca.
++/*
++ * Turn on what we want
++ */
++      orr     r0, r0, #0x0031                 @ ..........DP...M
++      orr     r0, r0, #0x2100                 @ ..V....S........
++
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      orr     r0, r0, #0x4000                 @ .R..............
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++      orr     r0, r0, #0x0800                 @ ....Z...........
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      orr     r0, r0, #0x0004                 @ .............C..
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      orr     r0, r0, #0x1000                 @ ...I............
++#endif
++      mov     pc, lr
++      .size   __arm1022_setup, . - __arm1022_setup
++
++      __INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ *         come through these
++ */
++      .type   arm1022_processor_functions, #object
++arm1022_processor_functions:
++      .word   v4t_early_abort
++      .word   cpu_arm1022_proc_init
++      .word   cpu_arm1022_proc_fin
++      .word   cpu_arm1022_reset
++      .word   cpu_arm1022_do_idle
++      .word   cpu_arm1022_dcache_clean_area
++      .word   cpu_arm1022_switch_mm
++      .word   cpu_arm1022_set_pte
++      .size   arm1022_processor_functions, . - arm1022_processor_functions
++
++      .section ".rodata"
++
++      .type   cpu_arch_name, #object
++cpu_arch_name:
++      .asciz  "armv5te"
++      .size   cpu_arch_name, . - cpu_arch_name
++
++      .type   cpu_elf_name, #object
++cpu_elf_name:
++      .asciz  "v5"
++      .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_arm1022_name, #object
++cpu_arm1022_name:
++      .ascii  "arm1022"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++      .ascii  "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      .ascii  "RR"
++#endif
++      .ascii  "\0"
++      .size   cpu_arm1022_name, . - cpu_arm1022_name
++
++      .align
++
++      .section ".proc.info", #alloc, #execinstr
++
++      .type   __arm1022_proc_info,#object
++__arm1022_proc_info:
++      .long   0x4105a220                      @ ARM 1022E (v5TE)
++      .long   0xff0ffff0
++      .long   0x00000c12                      @ mmuflags
++      b       __arm1022_setup
++      .long   cpu_arch_name
++      .long   cpu_elf_name
++      .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
++      .long   cpu_arm1022_name
++      .long   arm1022_processor_functions
++      .long   v4wbi_tlb_fns
++      .long   v4wb_user_fns
++      .long   arm1022_cache_fns
++      .size   __arm1022_proc_info, . - __arm1022_proc_info
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm1026.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm1026.S  2003-09-27 11:38:18.431726336 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm1026.S       2003-09-27 11:38:18.829665840 +0800
+@@ -0,0 +1,480 @@
++/*
++ *  linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S
++ *
++ *  Copyright (C) 2000 ARM Limited
++ *  Copyright (C) 2000 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.
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the ARM1026EJ-S.
++ */
++#include <linux/linkage.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/constants.h>
++#include <asm/pgtable.h>
++#include <asm/procinfo.h>
++#include <asm/ptrace.h>
++
++/*
++ * This is the maximum size of an area which will be invalidated
++ * using the single invalidate entry instructions.  Anything larger
++ * than this, and we go for the whole cache.
++ *
++ * This value should be chosen such that we choose the cheapest
++ * alternative.
++ */
++#define MAX_AREA_SIZE 32768
++
++/*
++ * The size of one data cache line.
++ */
++#define CACHE_DLINESIZE       32
++
++/*
++ * The number of data cache segments.
++ */
++#define CACHE_DSEGMENTS       16
++
++/*
++ * The number of lines in a cache segment.
++ */
++#define CACHE_DENTRIES        64
++
++/*
++ * This is the size at which it becomes more efficient to
++ * clean the whole cache, rather than using the individual
++ * cache line maintainence instructions.
++ */
++#define CACHE_DLIMIT  32768
++
++      .text
++/*
++ * cpu_arm1026_proc_init()
++ */
++ENTRY(cpu_arm1026_proc_init)
++      mov     pc, lr
++
++/*
++ * cpu_arm1026_proc_fin()
++ */
++ENTRY(cpu_arm1026_proc_fin)
++      stmfd   sp!, {lr}
++      mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++      msr     cpsr_c, ip
++      bl      arm1026_flush_kern_cache_all
++      mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
++      bic     r0, r0, #0x1000                 @ ...i............
++      bic     r0, r0, #0x000e                 @ ............wca.
++      mcr     p15, 0, r0, c1, c0, 0           @ disable caches
++      ldmfd   sp!, {pc}
++
++/*
++ * cpu_arm1026_reset(loc)
++ *
++ * Perform a soft reset of the system.        Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++      .align  5
++ENTRY(cpu_arm1026_reset)
++      mov     ip, #0
++      mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
++      mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
++      bic     ip, ip, #0x000f                 @ ............wcam
++      bic     ip, ip, #0x1100                 @ ...i...s........
++      mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
++      mov     pc, r0
++
++/*
++ * cpu_arm1026_do_idle()
++ */
++      .align  5
++ENTRY(cpu_arm1026_do_idle)
++      mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
++      mov     pc, lr
++
++/* ================================= CACHE ================================ */
++
++      .align  5
++/*
++ *    flush_user_cache_all()
++ *
++ *    Invalidate all cache entries in a particular address
++ *    space.
++ */
++ENTRY(arm1026_flush_user_cache_all)
++      /* FALLTHROUGH */
++/*
++ *    flush_kern_cache_all()
++ *
++ *    Clean and invalidate the entire cache.
++ */
++ENTRY(arm1026_flush_kern_cache_all)
++      mov     r2, #VM_EXEC
++      mov     ip, #0
++__flush_whole_cache:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1:    mrc     p15, 0, r15, c7, c14, 3         @ test, clean, invalidate
++      bne     1b
++#endif
++      tst     r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++      mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    flush_user_cache_range(start, end, flags)
++ *
++ *    Invalidate a range of cache entries in the specified
++ *    address space.
++ *
++ *    - start - start address (inclusive)
++ *    - end   - end address (exclusive)
++ *    - flags - vm_flags for this space
++ */
++ENTRY(arm1026_flush_user_cache_range)
++      mov     ip, #0
++      sub     r3, r1, r0                      @ calculate total size
++      cmp     r3, #CACHE_DLIMIT
++      bhs     __flush_whole_cache
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      tst     r2, #VM_EXEC
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++      mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    coherent_kern_range(start, end)
++ *
++ *    Ensure coherency between the Icache and the Dcache in the
++ *    region described by start.  If you have non-snooping
++ *    Harvard caches, you need to implement this function.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ */
++ENTRY(arm1026_coherent_kern_range)
++      mov     ip, #0
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
++#endif
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    flush_kern_dcache_page(void *page)
++ *
++ *    Ensure no D cache aliasing occurs, either with itself or
++ *    the I cache
++ *
++ *    - page  - page aligned address
++ */
++ENTRY(arm1026_flush_kern_dcache_page)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      add     r1, r0, #PAGE_SZ
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_inv_range(start, end)
++ *
++ *    Invalidate (discard) the specified virtual address range.
++ *    May not write back any entries.  If 'start' or 'end'
++ *    are not cache line aligned, those lines must be written
++ *    back.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1026_dma_inv_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      tst     r0, #CACHE_DLINESIZE - 1
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++      mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
++      tst     r1, #CACHE_DLINESIZE - 1
++      mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
++1:    mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_clean_range(start, end)
++ *
++ *    Clean the specified virtual address range.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ *
++ * (same as v4wb)
++ */
++ENTRY(arm1026_dma_clean_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++/*
++ *    dma_flush_range(start, end)
++ *
++ *    Clean and invalidate the specified virtual address range.
++ *
++ *    - start - virtual start address
++ *    - end   - virtual end address
++ */
++ENTRY(arm1026_dma_flush_range)
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++1:    mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      blo     1b
++#endif
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++      mov     pc, lr
++
++ENTRY(arm1026_cache_fns)
++      .long   arm1026_flush_kern_cache_all
++      .long   arm1026_flush_user_cache_all
++      .long   arm1026_flush_user_cache_range
++      .long   arm1026_coherent_kern_range
++      .long   arm1026_flush_kern_dcache_page
++      .long   arm1026_dma_inv_range
++      .long   arm1026_dma_clean_range
++      .long   arm1026_dma_flush_range
++
++      .align  5
++ENTRY(cpu_arm1026_dcache_clean_area)
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mov     ip, #0
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      subs    r1, r1, #CACHE_DLINESIZE
++      bhi     1b
++#endif
++      mov     pc, lr
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_arm1026_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++      .align  5
++ENTRY(cpu_arm1026_switch_mm)
++      mov     r1, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++1:    mrc     p15, 0, r15, c7, c14, 3         @ test, clean, invalidate
++      bne     1b
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, r1, c7, c5, 0           @ invalidate I cache
++#endif
++      mcr     p15, 0, r1, c7, c10, 4          @ drain WB
++      mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
++      mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
++      mov     pc, lr
++        
++/*
++ * cpu_arm1026_set_pte(ptep, pte)
++ *
++ * Set a PTE and flush it out
++ */
++      .align  5
++ENTRY(cpu_arm1026_set_pte)
++      str     r1, [r0], #-2048                @ linux version
++
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
++
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
++
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
++      movne   r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      eor     r3, r1, #0x0a                   @ C & small page?
++      tst     r3, #0x0b
++      biceq   r2, r2, #4
++#endif
++      str     r2, [r0]                        @ hardware version
++      mov     r0, r0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++#endif
++      mov     pc, lr
++
++
++      __INIT
++
++      .type   __arm1026_setup, #function
++__arm1026_setup:
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
++      mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
++      mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs on v4
++      mcr     p15, 0, r4, c2, c0              @ load page table pointer
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      mov     r0, #4                          @ explicitly disable writeback
++      mcr     p15, 7, r0, c15, c0, 0
++#endif
++      mov     r0, #0x1f                       @ Domains 0, 1 = client
++      mcr     p15, 0, r0, c3, c0              @ load domain access register
++      mrc     p15, 0, r0, c1, c0              @ get control register v4
++/*
++ * Clear out 'unwanted' bits (then put them in if we need them)
++ */
++      bic     r0, r0, #0x1e00                 @ ...i??r.........
++      bic     r0, r0, #0x000e                 @ ............wca.
++/*
++ * Turn on what we want
++ */
++      orr     r0, r0, #0x0031                 @ ..........DP...M
++      orr     r0, r0, #0x2100                 @ ..V....S........
++
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      orr     r0, r0, #0x4000                 @ .R..............
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++      orr     r0, r0, #0x0800                 @ ....Z...........
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      orr     r0, r0, #0x0004                 @ .............C..
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      orr     r0, r0, #0x1000                 @ ...I............
++#endif
++      mov     pc, lr
++      .size   __arm1026_setup, . - __arm1026_setup
++
++      __INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ *         come through these
++ */
++      .type   arm1026_processor_functions, #object
++arm1026_processor_functions:
++      .word   v5t_early_abort
++      .word   cpu_arm1026_proc_init
++      .word   cpu_arm1026_proc_fin
++      .word   cpu_arm1026_reset
++      .word   cpu_arm1026_do_idle
++      .word   cpu_arm1026_dcache_clean_area
++      .word   cpu_arm1026_switch_mm
++      .word   cpu_arm1026_set_pte
++      .size   arm1026_processor_functions, . - arm1026_processor_functions
++
++      .section .rodata
++
++      .type   cpu_arch_name, #object
++cpu_arch_name:
++      .asciz  "armv5tej"
++      .size   cpu_arch_name, . - cpu_arch_name
++
++      .type   cpu_elf_name, #object
++cpu_elf_name:
++      .asciz  "v5"
++      .size   cpu_elf_name, . - cpu_elf_name
++      .align
++
++      .type   cpu_arm1026_name, #object
++cpu_arm1026_name:
++      .ascii  "ARM1026EJ-S"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#endif
++#ifndef CONFIG_CPU_BPREDICT_DISABLE
++      .ascii  "B"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      .ascii  "RR"
++#endif
++      .ascii  "\0"
++      .size   cpu_arm1026_name, . - cpu_arm1026_name
++
++      .align
++
++      .section ".proc.info", #alloc, #execinstr
++
++      .type   __arm1026_proc_info,#object
++__arm1026_proc_info:
++      .long   0x4106a260                      @ ARM 1026EJ-S (v5TEJ)
++      .long   0xff0ffff0
++      .long   0x00000c12                      @ mmuflags
++      b       __arm1026_setup
++      .long   cpu_arch_name
++      .long   cpu_elf_name
++      .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT
++      .long   cpu_arm1026_name
++      .long   arm1026_processor_functions
++      .long   v4wbi_tlb_fns
++      .long   v4wb_user_fns
++      .long   arm1026_cache_fns
++      .size   __arm1026_proc_info, . - __arm1026_proc_info
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm6_7.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm6_7.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm6_7.S        2003-09-27 11:38:18.832665384 +0800
+@@ -14,6 +14,7 @@
+ #include <linux/init.h>
+ #include <asm/assembler.h>
+ #include <asm/constants.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/ptrace.h>
+@@ -214,19 +215,19 @@
+ ENTRY(cpu_arm7_set_pte)
+               str     r1, [r0], #-2048                @ linux version
+-              eor     r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++              eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-              bic     r2, r1, #0xff0
+-              bic     r2, r2, #3
+-              orr     r2, r2, #HPTE_TYPE_SMALL
++              bic     r2, r1, #PTE_SMALL_AP_MASK
++              bic     r2, r2, #PTE_TYPE_MASK
++              orr     r2, r2, #PTE_TYPE_SMALL
+-              tst     r1, #LPTE_USER | LPTE_EXEC      @ User or Exec?
+-              orrne   r2, r2, #HPTE_AP_READ
++              tst     r1, #L_PTE_USER                 @ User?
++              orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+-              tst     r1, #LPTE_WRITE | LPTE_DIRTY    @ Write and Dirty?
+-              orreq   r2, r2, #HPTE_AP_WRITE
++              tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++              orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
+-              tst     r1, #LPTE_PRESENT | LPTE_YOUNG  @ Present and Young
++              tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young
+               movne   r2, #0
+               str     r2, [r0]                        @ hardware version
+@@ -246,16 +247,9 @@
+               mcr     p15, 0, r1, c1, c0, 0           @ turn off MMU etc
+               mov     pc, r0
+-cpu_arm6_name:        .asciz  "ARM6"
+-cpu_arm610_name:
+-              .asciz  "ARM610"
+-cpu_arm7_name:        .asciz  "ARM7"
+-cpu_arm710_name:
+-              .asciz  "ARM710"
+-              .align
+-
+               __INIT
++              .type   __arm6_setup, #function
+ __arm6_setup: mov     r0, #0
+               mcr     p15, 0, r0, c7, c0              @ flush caches on v3
+               mcr     p15, 0, r0, c5, c0              @ flush TLBs on v3
+@@ -265,7 +259,9 @@
+               mov     r0, #0x3d                       @ . ..RS BLDP WCAM
+               orr     r0, r0, #0x100                  @ . ..01 0011 1101
+               mov     pc, lr
++              .size   __arm6_setup, . - __arm6_setup
++              .type   __arm7_setup, #function
+ __arm7_setup: mov     r0, #0
+               mcr     p15, 0, r0, c7, c0              @ flush caches on v3
+               mcr     p15, 0, r0, c5, c0              @ flush TLBs on v3
+@@ -275,6 +271,9 @@
+               mov     r0, #0x7d                       @ . ..RS BLDP WCAM
+               orr     r0, r0, #0x100                  @ . ..01 0111 1101
+               mov     pc, lr
++              .size   __arm7_setup, . - __arm7_setup
++
++              __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -308,6 +307,8 @@
+               .word   cpu_arm7_set_pte
+               .size   arm7_processor_functions, . - arm7_processor_functions
++              .section ".rodata"
++
+               .type   cpu_arch_name, #object
+ cpu_arch_name:        .asciz  "armv3"
+               .size   cpu_arch_name, . - cpu_arch_name
+@@ -315,6 +316,25 @@
+               .type   cpu_elf_name, #object
+ cpu_elf_name: .asciz  "v3"
+               .size   cpu_elf_name, . - cpu_elf_name
++
++              .type   cpu_arm6_name, #object
++cpu_arm6_name:        .asciz  "ARM6"
++              .size   cpu_arm6_name, . - cpu_arm6_name
++
++              .type   cpu_arm610_name, #object
++cpu_arm610_name:
++              .asciz  "ARM610"
++              .size   cpu_arm610_name, . - cpu_arm610_name
++
++              .type   cpu_arm7_name, #object
++cpu_arm7_name:        .asciz  "ARM7"
++              .size   cpu_arm7_name, . - cpu_arm7_name
++
++              .type   cpu_arm710_name, #object
++cpu_arm710_name:
++              .asciz  "ARM710"
++              .size   cpu_arm710_name, . - cpu_arm710_name
++
+               .align
+               .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm720.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm720.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm720.S        2003-09-27 11:38:18.835664928 +0800
+@@ -34,6 +34,7 @@
+ #include <linux/init.h>
+ #include <asm/assembler.h>
+ #include <asm/constants.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/ptrace.h>
+ #include <asm/hardware.h>
+@@ -90,19 +91,19 @@
+ ENTRY(cpu_arm720_set_pte)
+               str     r1, [r0], #-2048                @ linux version
+-              eor     r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++              eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-              bic     r2, r1, #0xff0
+-              bic     r2, r2, #3
+-              orr     r2, r2, #HPTE_TYPE_SMALL
++              bic     r2, r1, #PTE_SMALL_AP_MASK
++              bic     r2, r2, #PTE_TYPE_MASK
++              orr     r2, r2, #PTE_TYPE_SMALL
+-              tst     r1, #LPTE_USER                  @ User?
+-              orrne   r2, r2, #HPTE_AP_READ
++              tst     r1, #L_PTE_USER                 @ User?
++              orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+-              tst     r1, #LPTE_WRITE | LPTE_DIRTY    @ Write and Dirty?
+-              orreq   r2, r2, #HPTE_AP_WRITE
++              tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++              orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
+-              tst     r1, #LPTE_PRESENT | LPTE_YOUNG  @ Present and Young
++              tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young
+               movne   r2, #0
+               str     r2, [r0]                        @ hardware version
+@@ -123,13 +124,9 @@
+               mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
+               mov     pc, r0
+-      
+-cpu_arm720_name:
+-              .asciz  "ARM720T"
+-              .align
+-
+               __INIT
++              .type   __arm720_setup, #function
+ __arm720_setup:       mov     r0, #0
+               mcr     p15, 0, r0, c7, c7, 0           @ invalidate caches
+               mcr     p15, 0, r0, c8, c7, 0           @ flush TLB (v4)
+@@ -142,6 +139,9 @@
+               orr     r0, r0, #0x2100                 @ .... .... .111 .... (old)
+               orr     r0, r0, #0x003d                 @ ..1. ..01 ..11 1101 (new)
+               mov     pc, lr                          @ __ret (head-armv.S)
++              .size   __arm720_setup, . - __arm720_setup
++
++              __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -159,6 +159,8 @@
+               .word   cpu_arm720_set_pte
+               .size   arm720_processor_functions, . - arm720_processor_functions
++              .section ".rodata"
++
+               .type   cpu_arch_name, #object
+ cpu_arch_name:        .asciz  "armv4t"
+               .size   cpu_arch_name, . - cpu_arch_name
+@@ -166,6 +168,12 @@
+               .type   cpu_elf_name, #object
+ cpu_elf_name: .asciz  "v4"
+               .size   cpu_elf_name, . - cpu_elf_name
++
++              .type   cpu_arm720_name, #object
++cpu_arm720_name:
++              .asciz  "ARM720T"
++              .size   cpu_arm720_name, . - cpu_arm720_name
++
+               .align
+ /*
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm920.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm920.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm920.S        2003-09-27 11:38:18.838664472 +0800
+@@ -1,5 +1,5 @@
+ /*
+- *  linux/arch/arm/mm/arm920.S: MMU functions for ARM920
++ *  linux/arch/arm/mm/proc-arm920.S: MMU functions for ARM920
+  *
+  *  Copyright (C) 1999,2000 ARM Limited
+  *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+@@ -28,6 +28,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <asm/assembler.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+@@ -333,19 +334,19 @@
+ ENTRY(cpu_arm920_set_pte)
+       str     r1, [r0], #-2048                @ linux version
+-      eor     r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-      bic     r2, r1, #0xff0
+-      bic     r2, r2, #3
+-      orr     r2, r2, #HPTE_TYPE_SMALL
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
+-      tst     r1, #LPTE_USER                  @ User or Exec?
+-      orrne   r2, r2, #HPTE_AP_READ
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+-      tst     r1, #LPTE_WRITE | LPTE_DIRTY    @ Write and Dirty?
+-      orreq   r2, r2, #HPTE_AP_WRITE
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
+-      tst     r1, #LPTE_PRESENT | LPTE_YOUNG  @ Present and Young?
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
+       movne   r2, #0
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -359,25 +360,9 @@
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+-
+-ENTRY(cpu_arm920_name)
+-      .ascii  "Arm920T"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+-      .ascii  "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+-      .ascii  "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+-      .ascii  "(wt)"
+-#else
+-      .ascii  "(wb)"
+-#endif
+-#endif
+-      .ascii  "\0"
+-      .align
+-
+       __INIT
++      .type   __arm920_setup, #function
+ __arm920_setup:
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
+@@ -408,8 +393,9 @@
+       orr     r0, r0, #0x1000                 @ ...1 .... .... ....
+ #endif
+       mov     pc, lr
++      .size   __arm920_setup, . - __arm920_setup
+-      .text
++      __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -427,6 +413,8 @@
+       .word   cpu_arm920_set_pte
+       .size   arm920_processor_functions, . - arm920_processor_functions
++      .section ".rodata"
++
+       .type   cpu_arch_name, #object
+ cpu_arch_name:
+       .asciz  "armv4t"
+@@ -436,6 +424,24 @@
+ cpu_elf_name:
+       .asciz  "v4"
+       .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_arm920_name, #object
++cpu_arm920_name:
++      .ascii  "ARM920T"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#endif
++      .ascii  "\0"
++      .size   cpu_arm920_name, . - cpu_arm920_name
++
+       .align
+       .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm922.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm922.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm922.S        2003-09-27 11:38:18.842663864 +0800
+@@ -1,5 +1,5 @@
+ /*
+- *  linux/arch/arm/mm/arm922.S: MMU functions for ARM922
++ *  linux/arch/arm/mm/proc-arm922.S: MMU functions for ARM922
+  *
+  *  Copyright (C) 1999,2000 ARM Limited
+  *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+@@ -29,6 +29,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <asm/assembler.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+@@ -337,19 +338,19 @@
+ ENTRY(cpu_arm922_set_pte)
+       str     r1, [r0], #-2048                @ linux version
+-      eor     r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-      bic     r2, r1, #0xff0
+-      bic     r2, r2, #3
+-      orr     r2, r2, #HPTE_TYPE_SMALL
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
+-      tst     r1, #LPTE_USER                  @ User?
+-      orrne   r2, r2, #HPTE_AP_READ
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+-      tst     r1, #LPTE_WRITE | LPTE_DIRTY    @ Write and Dirty?
+-      orreq   r2, r2, #HPTE_AP_WRITE
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
+-      tst     r1, #LPTE_PRESENT | LPTE_YOUNG  @ Present and Young?
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
+       movne   r2, #0
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -363,25 +364,9 @@
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+-
+-ENTRY(cpu_arm922_name)
+-      .ascii  "Arm922T"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+-      .ascii  "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+-      .ascii  "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+-      .ascii  "(wt)"
+-#else
+-      .ascii  "(wb)"
+-#endif
+-#endif
+-      .ascii  "\0"
+-      .align
+-
+       __INIT
++      .type   __arm922_setup, #function
+ __arm922_setup:
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
+@@ -412,8 +397,9 @@
+       orr     r0, r0, #0x1000                 @ ...1 .... .... ....
+ #endif
+       mov     pc, lr
++      .size   __arm922_setup, . - __arm922_setup
+-      .text
++      __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -431,6 +417,8 @@
+       .word   cpu_arm922_set_pte
+       .size   arm922_processor_functions, . - arm922_processor_functions
++      .section ".rodata"
++
+       .type   cpu_arch_name, #object
+ cpu_arch_name:
+       .asciz  "armv4t"
+@@ -440,6 +428,24 @@
+ cpu_elf_name:
+       .asciz  "v4"
+       .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_arm922_name, #object
++cpu_arm922_name:
++      .ascii  "ARM922T"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#endif
++      .ascii  "\0"
++      .size   cpu_arm922_name, . - cpu_arm922_name
++
+       .align
+       .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-arm926.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-arm926.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-arm926.S        2003-09-27 11:38:18.846663256 +0800
+@@ -28,6 +28,7 @@
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <asm/assembler.h>
++#include <asm/pgtable.h>
+ #include <asm/procinfo.h>
+ #include <asm/hardware.h>
+ #include <asm/page.h>
+@@ -337,19 +338,19 @@
+ ENTRY(cpu_arm926_set_pte)
+       str     r1, [r0], #-2048                @ linux version
+-      eor     r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-      bic     r2, r1, #0xff0
+-      bic     r2, r2, #3
+-      orr     r2, r2, #HPTE_TYPE_SMALL
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
+-      tst     r1, #LPTE_USER                  @ User?
+-      orrne   r2, r2, #HPTE_AP_READ
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+-      tst     r1, #LPTE_WRITE | LPTE_DIRTY    @ Write and Dirty?
+-      orreq   r2, r2, #HPTE_AP_WRITE
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
+-      tst     r1, #LPTE_PRESENT | LPTE_YOUNG  @ Present and Young?
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
+       movne   r2, #0
+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+@@ -365,28 +366,9 @@
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+-
+-ENTRY(cpu_arm926_name)
+-      .ascii  "ARM926EJ-S"
+-#ifndef CONFIG_CPU_ICACHE_DISABLE
+-      .ascii  "i"
+-#endif
+-#ifndef CONFIG_CPU_DCACHE_DISABLE
+-      .ascii  "d"
+-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+-      .ascii  "(wt)"
+-#else
+-      .ascii  "(wb)"
+-#endif
+-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+-      .ascii  "RR"
+-#endif
+-#endif
+-      .ascii  "\0"
+-      .align
+-
+       __INIT
++      .type   __arm926_setup, #function
+ __arm926_setup:
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
+@@ -427,8 +409,9 @@
+       orr     r0, r0, #0x1000                 @ ...1 .... .... ....
+ #endif
+       mov     pc, lr
++      .size   __arm926_setup, . - __arm926_setup
+-      .text
++      __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -436,7 +419,7 @@
+  */
+       .type   arm926_processor_functions, #object
+ arm926_processor_functions:
+-      .word   v5tej_early_abort
++      .word   v5tj_early_abort
+       .word   cpu_arm926_proc_init
+       .word   cpu_arm926_proc_fin
+       .word   cpu_arm926_reset
+@@ -446,6 +429,8 @@
+       .word   cpu_arm926_set_pte
+       .size   arm926_processor_functions, . - arm926_processor_functions
++      .section ".rodata"
++
+       .type   cpu_arch_name, #object
+ cpu_arch_name:
+       .asciz  "armv5tej"
+@@ -455,14 +440,35 @@
+ cpu_elf_name:
+       .asciz  "v5"
+       .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_arm926_name, #object
++cpu_arm926_name:
++      .ascii  "ARM926EJ-S"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
++      .ascii  "RR"
++#endif
++#endif
++      .ascii  "\0"
++      .size   cpu_arm926_name, . - cpu_arm926_name
++
+       .align
+       .section ".proc.info", #alloc, #execinstr
+       .type   __arm926_proc_info,#object
+ __arm926_proc_info:
+-      .long   0x41009260
+-      .long   0xff00fff0
++      .long   0x41069260                      @ ARM926EJ-S (v5TEJ)
++      .long   0xff0ffff0
+       .long   0x00000c1e                      @ mmuflags
+       b       __arm926_setup
+       .long   cpu_arch_name
+Index: linux-2.6.0-test5/arch/arm/mm/proc-sa1100.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-sa1100.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-sa1100.S        2003-09-27 11:38:18.848662952 +0800
+@@ -1,5 +1,5 @@
+ /*
+- *  linux/arch/arm/mm/proc-sa110.S
++ *  linux/arch/arm/mm/proc-sa1100.S
+  *
+  *  Copyright (C) 1997-2002 Russell King
+  *
+@@ -187,11 +187,11 @@
+       eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-      bic     r2, r1, #0xff0
+-      bic     r2, r2, #3
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
+       orr     r2, r2, #PTE_TYPE_SMALL
+-      tst     r1, #L_PTE_USER                 @ User or Exec?
++      tst     r1, #L_PTE_USER                 @ User?
+       orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+       tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
+@@ -206,15 +206,9 @@
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+-
+-cpu_sa1100_name:
+-      .asciz  "StrongARM-1100"
+-cpu_sa1110_name:
+-      .asciz  "StrongARM-1110"
+-      .align
+-
+       __INIT
++      .type   __sa1100_setup, #function
+ __sa1100_setup:
+       mov     r10, #0
+       mcr     p15, 0, r10, c7, c7             @ invalidate I,D caches on v4
+@@ -229,8 +223,9 @@
+       orr     r0, r0, #0x003d
+       orr     r0, r0, #0x3100                 @ ..11 ...1 ..11 11.1
+       mov     pc, lr
++      .size   __sa1100_setup, . - __sa1100_setup
+-      .text
++      __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -252,6 +247,8 @@
+       .word   cpu_sa1100_set_pte
+       .size   sa1100_processor_functions, . - sa1100_processor_functions
++      .section ".rodata"
++
+       .type   cpu_arch_name, #object
+ cpu_arch_name:
+       .asciz  "armv4"
+@@ -261,6 +258,17 @@
+ cpu_elf_name:
+       .asciz  "v4"
+       .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_sa1100_name, #object
++cpu_sa1100_name:
++      .asciz  "StrongARM-1100"
++      .size   cpu_sa1100_name, . - cpu_sa1100_name
++
++      .type   cpu_sa1110_name, #object
++cpu_sa1110_name:
++      .asciz  "StrongARM-1110"
++      .size   cpu_sa1110_name, . - cpu_sa1110_name
++
+       .align
+       .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-sa110.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-sa110.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-sa110.S 2003-09-27 11:38:18.851662496 +0800
+@@ -163,11 +163,11 @@
+       eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+-      bic     r2, r1, #0xff0
+-      bic     r2, r2, #3
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
+       orr     r2, r2, #PTE_TYPE_SMALL
+-      tst     r1, #L_PTE_USER                 @ User or Exec?
++      tst     r1, #L_PTE_USER                 @ User?
+       orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
+       tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
+@@ -182,13 +182,9 @@
+       mcr     p15, 0, r0, c7, c10, 4          @ drain WB
+       mov     pc, lr
+-
+-cpu_sa110_name:
+-      .asciz  "StrongARM-110"
+-      .align
+-
+       __INIT
++      .type   __sa110_setup, #function
+ __sa110_setup:
+       mrc     p15, 0, r0, c1, c0              @ get control register v4
+       bic     r0, r0, #0x2e00                 @ ..VI ZFRS BLDP WCAM
+@@ -203,8 +199,9 @@
+       mov     r10, #0x1f                      @ Domains 0, 1 = client
+       mcr     p15, 0, r10, c3, c0             @ load domain access register
+       mov     pc, lr
++      .size   __sa110_setup, . - __sa110_setup
+-      .text
++      __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -218,16 +215,13 @@
+       .word   cpu_sa110_proc_fin
+       .word   cpu_sa110_reset
+       .word   cpu_sa110_do_idle
+-
+-      /* dcache */
+       .word   cpu_sa110_dcache_clean_area
+-
+-      /* pgtable */
+       .word   cpu_sa110_switch_mm
+       .word   cpu_sa110_set_pte
+-
+       .size   sa110_processor_functions, . - sa110_processor_functions
++      .section ".rodata"
++
+       .type   cpu_arch_name, #object
+ cpu_arch_name:
+       .asciz  "armv4"
+@@ -237,6 +231,12 @@
+ cpu_elf_name:
+       .asciz  "v4"
+       .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_sa110_name, #object
++cpu_sa110_name:
++      .asciz  "StrongARM-110"
++      .size   cpu_sa110_name, . - cpu_sa110_name
++
+       .align
+       .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/proc-xscale.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/proc-xscale.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/proc-xscale.S        2003-09-27 11:38:18.856661736 +0800
+@@ -236,6 +236,9 @@
+  *
+  *    - start  - virtual start address
+  *    - end    - virtual end address
++ *
++ *    Note: single I-cache line invalidation isn't used here since
++ *    it also trashes the mini I-cache used by JTAG debuggers.
+  */
+ ENTRY(xscale_coherent_kern_range)
+       bic     r0, r0, #CACHELINESIZE - 1
+@@ -568,22 +571,11 @@
+       .ltorg
+-cpu_80200_name:
+-      .asciz  "XScale-80200"
+-
+-cpu_80321_name:
+-      .asciz  "XScale-IOP80321"
+-
+-cpu_pxa250_name:
+-      .asciz  "XScale-PXA250"
+-
+-cpu_pxa210_name:
+-      .asciz  "XScale-PXA210"
+-
+       .align
+       __INIT
++      .type   __xscale_setup, #function
+ __xscale_setup:
+       mov     r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+       msr     cpsr_c, r0
+@@ -602,8 +594,9 @@
+       orr     r0, r0, #0x0005                 @ .... .... .... .C.M
+       orr     r0, r0, #0x3900                 @ ..VI Z..S .... ....
+       mov     pc, lr
++      .size   __xscale_setup, . - __xscale_setup
+-      .text
++      __INITDATA
+ /*
+  * Purpose : Function pointers used to access above functions - all calls
+@@ -612,7 +605,7 @@
+       .type   xscale_processor_functions, #object
+ ENTRY(xscale_processor_functions)
+-      .word   xscale_abort
++      .word   v5t_early_abort
+       .word   cpu_xscale_proc_init
+       .word   cpu_xscale_proc_fin
+       .word   cpu_xscale_reset
+@@ -622,6 +615,8 @@
+       .word   cpu_xscale_set_pte
+       .size   xscale_processor_functions, . - xscale_processor_functions
++      .section ".rodata"
++
+       .type   cpu_arch_name, #object
+ cpu_arch_name:
+       .asciz  "armv5te"
+@@ -631,6 +626,27 @@
+ cpu_elf_name:
+       .asciz  "v5"
+       .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_80200_name, #object
++cpu_80200_name:
++      .asciz  "XScale-80200"
++      .size   cpu_80200_name, . - cpu_80200_name
++
++      .type   cpu_80321_name, #object
++cpu_80321_name:
++      .asciz  "XScale-IOP80321"
++      .size   cpu_80321_name, . - cpu_80321_name
++
++      .type   cpu_pxa250_name, #object
++cpu_pxa250_name:
++      .asciz  "XScale-PXA250"
++      .size   cpu_pxa250_name, . - cpu_pxa250_name
++
++      .type   cpu_pxa210_name, #object
++cpu_pxa210_name:
++      .asciz  "XScale-PXA210"
++      .size   cpu_pxa210_name, . - cpu_pxa210_name
++
+       .align
+       .section ".proc.info", #alloc, #execinstr
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v3.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v3.S        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v3.S     2003-09-27 11:38:18.858661432 +0800
+@@ -42,7 +42,7 @@
+       blo     1b
+       mov     pc, lr
+-      __INIT
++      __INITDATA
+       .type   v3_tlb_fns, #object
+ ENTRY(v3_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v4.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v4.S        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v4.S     2003-09-27 11:38:18.859661280 +0800
+@@ -34,7 +34,6 @@
+       act_mm  r3                              @ get current->active_mm
+       eors    r3, ip, r3                              @ == mm ?
+       movne   pc, lr                          @ no, we dont do anything
+-      vma_vm_flags ip, r2
+ .v4_flush_kern_tlb_range:
+       bic     r0, r0, #0x0ff
+       bic     r0, r0, #0xf00
+@@ -56,7 +55,7 @@
+ .globl v4_flush_kern_tlb_range
+ .equ v4_flush_kern_tlb_range, .v4_flush_kern_tlb_range
+-      __INIT
++      __INITDATA
+       .type   v4_tlb_fns, #object
+ ENTRY(v4_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v4wbi.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v4wbi.S     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v4wbi.S  2003-09-27 11:38:18.860661128 +0800
+@@ -58,7 +58,7 @@
+       blo     1b
+       mov     pc, lr
+-      __INIT
++      __INITDATA
+       .type   v4wbi_tlb_fns, #object
+ ENTRY(v4wbi_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/mm/tlb-v4wb.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/mm/tlb-v4wb.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/mm/tlb-v4wb.S   2003-09-27 11:38:18.862660824 +0800
+@@ -67,7 +67,7 @@
+       blo     1b
+       mov     pc, lr
+-      __INIT
++      __INITDATA
+       .type   v4wb_tlb_fns, #object
+ ENTRY(v4wb_tlb_fns)
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11.c   2003-09-27 11:38:18.863660672 +0800
+@@ -26,6 +26,7 @@
+ #include "fpmodule.h"
+ #include "fpmodule.inl"
++#include <linux/config.h>
+ #include <linux/compiler.h>
+ #include <linux/string.h>
+ #include <asm/system.h>
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdo.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11_cpdo.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdo.c      2003-09-27 11:38:18.865660368 +0800
+@@ -20,6 +20,7 @@
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "fpopcode.h"
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdt.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11_cpdt.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cpdt.c      2003-09-27 11:38:18.867660064 +0800
+@@ -20,6 +20,7 @@
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "softfloat.h"
+ #include "fpopcode.h"
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cprt.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11_cprt.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11_cprt.c      2003-09-27 11:38:18.870659608 +0800
+@@ -20,6 +20,7 @@
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "fpopcode.h"
+ #include "fpa11.inl"
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpa11.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpa11.h      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpa11.h   2003-09-27 11:38:18.872659304 +0800
+@@ -33,6 +33,7 @@
+ #define GET_USERREG() (user_registers)
++#include <linux/config.h>
+ #include <linux/thread_info.h>
+ /* includes */
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpopcode.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.c        2003-09-27 11:38:18.874659000 +0800
+@@ -19,6 +19,7 @@
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
++#include <linux/config.h>
+ #include "fpa11.h"
+ #include "softfloat.h"
+ #include "fpopcode.h"
+Index: linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/fpopcode.h   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/fpopcode.h        2003-09-27 11:38:18.878658392 +0800
+@@ -23,6 +23,8 @@
+ #ifndef __FPOPCODE_H__
+ #define __FPOPCODE_H__
++#include <linux/config.h>
++
+ /*
+ ARM Floating Point Instruction Classes
+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
+Index: linux-2.6.0-test5/arch/arm/nwfpe/softfloat.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/nwfpe/softfloat.h  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/nwfpe/softfloat.h       2003-09-27 11:38:18.883657632 +0800
+@@ -32,6 +32,8 @@
+ #ifndef __SOFTFLOAT_H__
+ #define __SOFTFLOAT_H__
++#include <linux/config.h>
++
+ /*
+ -------------------------------------------------------------------------------
+ The macro `FLOATX80' must be defined to enable the extended double-precision
+Index: linux-2.6.0-test5/arch/arm/tools/mach-types
+===================================================================
+--- linux-2.6.0-test5.orig/arch/arm/tools/mach-types   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/arm/tools/mach-types        2003-09-27 11:38:18.887657024 +0800
+@@ -6,7 +6,7 @@
+ # To add an entry into this database, please see Documentation/arm/README,
+ # or contact rmk@arm.linux.org.uk
+ #
+-# Last update: Sun Aug 3 16:26:10 2003
++# Last update: Thu Sep 18 17:15:55 2003
+ #
+ # machine_is_xxx      CONFIG_xxxx             MACH_TYPE_xxx           number
+ #
+@@ -367,3 +367,21 @@
+ ixp2000                       ARCH_IXP2000            IXP2000                 356
+ xda                   SA1100_XDA              XDA                     357
+ csir_ims              ARCH_CSIR_IMS           CSIR_IMS                358
++ixp421_dnaeeth                ARCH_IXP421_DNAEETH     IXP421_DNAEETH          359
++pocketserv9200                ARCH_POCKETSERV9200     POCKETSERV9200          360
++toto                  ARCH_TOTO               TOTO                    361
++s3c2440                       ARCH_S3C2440            S3C2440                 362
++ks8695p                       ARCH_KS8695P            KS8695P                 363
++se4000                        ARCH_SE4000             SE4000                  364
++quadriceps            ARCH_QUADRICEPS         QUADRICEPS              365
++bronco                        ARCH_BRONCO             BRONCO                  366
++esl_wireless_tab      ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET     367
++esl_sofcomp           ARCH_ESL_SOFCOMP        ESL_SOFCOMP             368
++s5c7375                       ARCH_S5C7375            S5C7375                 369
++spearhead             ARCH_SPEARHEAD          SPEARHEAD               370
++pantera                       ARCH_PANTERA            PANTERA                 371
++prayoglite            ARCH_PRAYOGLITE         PRAYOGLITE              372
++gumstik                       ARCH_GUMSTIK            GUMSTIK                 373
++rcube                 ARCH_RCUBE              RCUBE                   374
++rea_olv                       ARCH_REA_OLV            REA_OLV                 375
++pxa_iphone            ARCH_PXA_IPHONE         PXA_IPHONE              376
+Index: linux-2.6.0-test5/arch/cris/arch-v10/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/cris/arch-v10/boot/compressed/misc.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/cris/arch-v10/boot/compressed/misc.c        2003-09-27 11:38:18.890656568 +0800
+@@ -115,7 +115,7 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
++      if (size <0) error("Malloc error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+Index: linux-2.6.0-test5/arch/cris/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/cris/mm/ioremap.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/cris/mm/ioremap.c   2003-09-27 11:38:18.892656264 +0800
+@@ -157,7 +157,7 @@
+       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;
+       }
+Index: linux-2.6.0-test5/arch/h8300/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/h8300/kernel/signal.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/h8300/kernel/signal.c       2003-09-27 11:38:18.897655504 +0800
+@@ -593,7 +593,7 @@
+                               continue;
+                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
+-                              if (is_orphaned_pgrp(current->pgrp))
++                              if (is_orphaned_pgrp(process_group(current)))
+                                       continue;
+                               /* FALLTHRU */
+Index: linux-2.6.0-test5/arch/i386/boot98/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot98/compressed/misc.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot98/compressed/misc.c       2003-09-27 11:38:18.901654896 +0800
+@@ -132,8 +132,8 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
+-      if (free_mem_ptr <= 0) error("Memory error\n");
++      if (size <0) error("Malloc error");
++      if (free_mem_ptr <= 0) error("Memory error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+@@ -141,7 +141,7 @@
+       free_mem_ptr += size;
+       if (free_mem_ptr >= free_mem_end_ptr)
+-              error("\nOut of memory\n");
++              error("Out of memory");
+       return p;
+ }
+@@ -232,7 +232,7 @@
+ static int fill_inbuf(void)
+ {
+       if (insize != 0) {
+-              error("ran out of input data\n");
++              error("ran out of input data");
+       }
+       inbuf = input_data;
+@@ -306,9 +306,9 @@
+ static void setup_normal_output_buffer(void)
+ {
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+-      if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
++      if (EXT_MEM_K < 1024) error("Less than 2MB of memory");
+ #else
+-      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
++      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
+ #endif
+       output_data = (char *)0x100000; /* Points to 1M */
+       free_mem_end_ptr = (long)real_mode;
+@@ -323,9 +323,9 @@
+ {
+       high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+-      if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
++      if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory");
+ #else
+-      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
++      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory");
+ #endif        
+       mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+       low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
+Index: linux-2.6.0-test5/arch/i386/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot/compressed/misc.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot/compressed/misc.c 2003-09-27 11:38:18.904654440 +0800
+@@ -132,8 +132,8 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
+-      if (free_mem_ptr <= 0) error("Memory error\n");
++      if (size <0) error("Malloc error");
++      if (free_mem_ptr <= 0) error("Memory error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+@@ -141,7 +141,7 @@
+       free_mem_ptr += size;
+       if (free_mem_ptr >= free_mem_end_ptr)
+-              error("\nOut of memory\n");
++              error("Out of memory");
+       return p;
+ }
+@@ -232,7 +232,7 @@
+ static int fill_inbuf(void)
+ {
+       if (insize != 0) {
+-              error("ran out of input data\n");
++              error("ran out of input data");
+       }
+       inbuf = input_data;
+@@ -306,9 +306,9 @@
+ static void setup_normal_output_buffer(void)
+ {
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+-      if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
++      if (EXT_MEM_K < 1024) error("Less than 2MB of memory");
+ #else
+-      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
++      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
+ #endif
+       output_data = (char *)0x100000; /* Points to 1M */
+       free_mem_end_ptr = (long)real_mode;
+@@ -323,9 +323,9 @@
+ {
+       high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+-      if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
++      if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory");
+ #else
+-      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
++      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory");
+ #endif        
+       mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+       low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
+Index: linux-2.6.0-test5/arch/i386/boot/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot/Makefile     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot/Makefile  2003-09-27 11:38:18.906654136 +0800
+@@ -99,4 +99,4 @@
+       if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+ install: $(BOOTIMAGE)
+-      sh $(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
++      sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
+Index: linux-2.6.0-test5/arch/i386/boot/setup.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot/setup.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot/setup.S   2003-09-27 11:38:18.914652920 +0800
+@@ -162,7 +162,7 @@
+                                       # 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
+@@ -506,6 +506,17 @@
+       movw    $0xAA, (0x1ff)                  # device present
+ no_psmouse:
++#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
++      movl    $0x0000E980, %eax               # IST Support 
++      movl    $0x47534943, %edx               # Request value
++      int     $0x15
++
++      movl    %eax, (96)
++      movl    %ebx, (100)
++      movl    %ecx, (104)
++      movl    %edx, (108)
++#endif
++
+ #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+ # Then check for an APM BIOS...
+                                               # %ds points to the bootsector
+Index: linux-2.6.0-test5/arch/i386/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/Kconfig   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/Kconfig        2003-09-27 11:38:18.926651096 +0800
+@@ -397,16 +397,53 @@
+       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6
+       default y
+-config HUGETLB_PAGE
+-      bool "Huge TLB Page Support"
++config X86_4G
++      bool "4 GB kernel-space and 4 GB user-space virtual memory support"
+       help
+-        This enables support for huge pages.  User space applications
+-        can make use of this support with the sys_alloc_hugepages and
+-        sys_free_hugepages system calls.  If your applications are
+-        huge page aware and your processor (Pentium or later for x86)
+-        supports this, then say Y here.
++          This option is only useful for systems that have more than 1 GB
++          of RAM.
+-        Otherwise, say N.
++          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"
+@@ -454,6 +491,7 @@
+ config NR_CPUS
+       int "Maximum number of CPUs (2-255)"
+       depends on SMP
++      default "32" if X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000
+       default "8"
+       help
+         This allows you to specify the maximum number of CPUs which this
+@@ -814,49 +852,7 @@
+ menu "Power management options (ACPI, APM)"
+       depends on !X86_VOYAGER
+-config PM
+-      bool "Power Management support"
+-      ---help---
+-        "Power Management" means that parts of your computer are shut
+-        off or put into a power conserving "sleep" mode if they are not
+-        being used.  There are two competing standards for doing this: APM
+-        and ACPI.  If you want to use either one, say Y here and then also
+-        to the requisite support below.
+-
+-        Power Management is most important for battery powered laptop
+-        computers; if you have a laptop, check out the Linux Laptop home
+-        page on the WWW at
+-        <http://www.cs.utexas.edu/users/kharker/linux-laptop/> and the
+-        Battery Powered Linux mini-HOWTO, available from
+-        <http://www.tldp.org/docs.html#howto>.
+-
+-        Note that, even if you say N here, Linux on the x86 architecture
+-        will issue the hlt instruction if nothing is to be done, thereby
+-        sending the processor to sleep and saving power.
+-
+-config SOFTWARE_SUSPEND
+-      bool "Software Suspend (EXPERIMENTAL)"
+-      depends on EXPERIMENTAL && PM && SWAP
+-      ---help---
+-        Enable the possibilty of suspendig machine. It doesn't need APM.
+-        You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 
+-        (patch for sysvinit needed). 
+-
+-        It creates an image which is saved in your active swaps. By the next
+-        booting the, pass 'resume=/dev/swappartition' and kernel will 
+-        detect the saved image, restore the memory from
+-        it and then it continues to run as before you've suspended.
+-        If you don't want the previous state to continue use the 'noresume'
+-        kernel option. However note that your partitions will be fsck'd and
+-        you must re-mkswap your swap partitions. It does not work with swap
+-        files.
+-
+-        Right now you may boot without resuming and then later resume but
+-        in meantime you cannot use those swap partitions/files which were
+-        involved in suspending. Also in this case there is a risk that buffers
+-        on disk won't match with saved ones.
+-
+-        For more information take a look at Documentation/swsusp.txt.
++source kernel/power/Kconfig
+ source "drivers/acpi/Kconfig"
+@@ -1293,6 +1289,15 @@
+         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
+@@ -1309,20 +1314,208 @@
+         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
+Index: linux-2.6.0-test5/arch/i386/kernel/acpi/boot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/acpi/boot.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/acpi/boot.c     2003-09-27 11:38:18.930650488 +0800
+@@ -183,8 +183,7 @@
+ #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 (
+@@ -368,7 +367,6 @@
+       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 +414,7 @@
+ #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 +470,8 @@
+       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 +479,7 @@
+               clustered_apic_check();
+       }
+ #endif
++
+ #ifdef CONFIG_HPET_TIMER
+       acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
+ #endif
+Index: linux-2.6.0-test5/arch/i386/kernel/apm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/apm.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/apm.c   2003-09-27 11:38:18.946648056 +0800
+@@ -2008,7 +2008,7 @@
+       if (apm_proc)
+               apm_proc->owner = THIS_MODULE;
+-      kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
++      kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD);
+       if (num_online_cpus() > 1 && !smp ) {
+               printk(KERN_NOTICE
+Index: linux-2.6.0-test5/arch/i386/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/asm-offsets.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/asm-offsets.c   2003-09-27 11:38:18.948647752 +0800
+@@ -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 @@
+       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]));
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/common.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/common.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/common.c    2003-09-27 11:38:18.952647144 +0800
+@@ -510,16 +510,20 @@
+               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");
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/acpi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/acpi.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/acpi.c      2003-09-27 11:38:18.957646384 +0800
+@@ -24,6 +24,7 @@
+  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  */
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/Kconfig        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Kconfig     2003-09-27 11:38:18.960645928 +0800
+@@ -99,34 +99,46 @@
+        If in doubt, say N.
++config X86_SPEEDSTEP_CENTRINO
++      tristate "Intel Enhanced SpeedStep"
++      depends on CPU_FREQ_TABLE
++      help
++        This adds the CPUFreq driver for Enhanced SpeedStep enabled
++        mobile CPUs.  This means Intel Pentium M (Centrino) CPUs.
++        
++        For details, take a look at linux/Documentation/cpu-freq. 
++        
++        If in doubt, say N.
++
+ config X86_SPEEDSTEP_ICH
+-      tristate "Intel Speedstep"
++      tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
+       depends on CPU_FREQ_TABLE
+       help
+         This adds the CPUFreq driver for certain mobile Intel Pentium III
+         (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all
+-        mobile Intel Pentium 4 P4-Ms, with an Intel ICH2, ICH3,
+-        or ICH4 southbridge.
++        mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2, 
++        ICH3 or ICH4 southbridge.
+         For details, take a look at linux/Documentation/cpu-freq. 
+         If in doubt, say N.
+-config X86_SPEEDSTEP_CENTRINO
+-      tristate "Intel Enhanced SpeedStep"
+-      depends on CPU_FREQ_TABLE
++config X86_SPEEDSTEP_SMI
++      tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)"
++      depends on CPU_FREQ_TABLE && EXPERIMENTAL
+       help
+-        This adds the CPUFreq driver for Enhanced SpeedStep enabled
+-        mobile CPUs.  This means Intel Pentium M (Centrino) CPUs.
+-        
+-        For details, take a look at linux/Documentation/cpu-freq. 
+-        
++        This adds the CPUFreq driver for certain mobile Intel Pentium III
++        (Coppermine), all mobile Intel Pentium III-M (Tualatin)  
++        on systems which have an Intel 440BX/ZX/MX southbridge.
++
++        For details, take a look at linux/Documentation/cpu-freq.
++
+         If in doubt, say N.
+ config X86_SPEEDSTEP_LIB
+-       tristate
+-       depends on X86_SPEEDSTEP_ICH
+-       default X86_SPEEDSTEP_ICH
++      tristate
++      depends on (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI)
++      default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI)
+ config X86_P4_CLOCKMOD
+       tristate "Intel Pentium 4 clock modulation"
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/Makefile       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/Makefile    2003-09-27 11:38:18.961645776 +0800
+@@ -9,6 +9,7 @@
+ obj-$(CONFIG_X86_SPEEDSTEP_ICH)       += speedstep-ich.o
+ obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
+ obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
++obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o
+ ifdef CONFIG_X86_ACPI_CPUFREQ
+   ifdef CONFIG_ACPI_DEBUG
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c       2003-09-27 11:38:18.964645320 +0800
+@@ -20,6 +20,7 @@
+  *
+  */
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h> 
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/powernow-k7.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/powernow-k7.c       2003-09-27 11:38:18.967644864 +0800
+@@ -14,6 +14,7 @@
+  * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
+  */
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h> 
+ #include <linux/init.h>
+@@ -191,10 +192,11 @@
+ {
+       union msr_fidvidctl fidvidctl;
++      rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+       if (fidvidctl.bits.FID != fid) {
+-              rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+               fidvidctl.bits.SGTC = latency;
+               fidvidctl.bits.FID = fid;
++              fidvidctl.bits.VIDC = 0;
+               fidvidctl.bits.FIDC = 1;
+               wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+       }
+@@ -205,9 +207,11 @@
+ {
+       union msr_fidvidctl fidvidctl;
++      rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+       if (fidvidctl.bits.VID != vid) {
+-              rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
++              fidvidctl.bits.SGTC = latency;
+               fidvidctl.bits.VID = vid;
++              fidvidctl.bits.FIDC = 0;
+               fidvidctl.bits.VIDC = 1;
+               wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+       }
+@@ -297,8 +301,14 @@
+                       dprintk (" voltage regulator)\n");
+                       latency = psb->settlingtime;
++                      if (latency < 100) {
++                              printk (KERN_INFO PFX "BIOS set settling time to %d microseconds."
++                                              "Should be at least 100. Correcting.\n", latency);
++                              latency = 100;
++                      }
+                       dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", psb->settlingtime);
+                       dprintk (KERN_INFO PFX "Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);
++                      latency *= 100; /* SGTC needs to be in units of 10ns */
+                       p += sizeof (struct psb_s);
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c        2003-09-27 11:38:18.432726184 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c     2003-09-27 11:38:18.968644712 +0800
+@@ -0,0 +1,362 @@
++/*
++ * Intel SpeedStep SMI driver.
++ *
++ * (C) 2003  Hiroshi Miura <miura@da-cha.org>
++ *
++ *  Licensed under the terms of the GNU GPL License version 2.
++ *
++ */
++
++
++/*********************************************************************
++ *                        SPEEDSTEP - DEFINITIONS                    *
++ *********************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/module.h> 
++#include <linux/moduleparam.h> 
++#include <linux/init.h>
++#include <linux/cpufreq.h>
++#include <linux/pci.h>
++#include <linux/slab.h>
++#include <asm/ist.h>
++
++#include "speedstep-lib.h"
++
++#define PFX "speedstep-smi: "
++
++/* speedstep system management interface port/command.
++ *
++ * These parameters are got from IST-SMI BIOS call.
++ * If user gives it, these are used.
++ * 
++ */
++static int            smi_port        = 0;
++static int            smi_cmd         = 0;
++static unsigned int   smi_sig         = 0;
++
++
++/* 
++ *   There are only two frequency states for each processor. Values
++ * are in kHz for the time being.
++ */
++static struct cpufreq_frequency_table speedstep_freqs[] = {
++      {SPEEDSTEP_HIGH,        0},
++      {SPEEDSTEP_LOW,         0},
++      {0,                     CPUFREQ_TABLE_END},
++};
++
++#define GET_SPEEDSTEP_OWNER 0
++#define GET_SPEEDSTEP_STATE 1
++#define SET_SPEEDSTEP_STATE 2
++#define GET_SPEEDSTEP_FREQS 4
++
++/* DEBUG
++ *   Define it if you want verbose debug output, e.g. for bug reporting
++ */
++#define SPEEDSTEP_DEBUG
++
++#ifdef SPEEDSTEP_DEBUG
++#define dprintk(msg...) printk(msg)
++#else
++#define dprintk(msg...) do { } while(0)
++#endif
++
++/**
++ * speedstep_smi_ownership
++ */
++static int speedstep_smi_ownership (void)
++{
++      u32 command, result, magic;
++      u32 function = GET_SPEEDSTEP_OWNER;
++      unsigned char magic_data[] = "Copyright (c) 1999 Intel Corporation";
++
++      command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++      magic = virt_to_phys(magic_data);
++
++      __asm__ __volatile__(
++              "out %%al, (%%dx)\n"
++              : "=D" (result)
++              : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic)
++      );
++
++      return result;
++}
++
++/**
++ * speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
++ *
++ */
++static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
++{
++      u32 command, result, edi, high_mhz, low_mhz;
++      u32 state=0;
++      u32 function = GET_SPEEDSTEP_FREQS;
++
++      command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++
++      __asm__ __volatile__("movl $0, %%edi\n"
++              "out %%al, (%%dx)\n"
++              : "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi)
++              : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
++      );
++      *high = high_mhz * 1000;
++      *low  = low_mhz  * 1000;
++
++      return result;
++} 
++
++/**
++ * speedstep_get_state - set the SpeedStep state
++ * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
++ *
++ */
++static int speedstep_get_state (void)
++{
++      u32 function=GET_SPEEDSTEP_STATE;
++      u32 result, state, edi, command;
++
++      command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++
++      __asm__ __volatile__("movl $0, %%edi\n"
++              "out %%al, (%%dx)\n"
++              : "=a" (result), "=b" (state), "=D" (edi)
++              : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0)
++      );
++
++      return state;
++}
++
++/**
++ * speedstep_set_state - set the SpeedStep state
++ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
++ *
++ */
++static void speedstep_set_state (unsigned int state, unsigned int notify)
++{
++      unsigned int old_state, result, command, new_state;
++      unsigned long flags;
++      struct cpufreq_freqs freqs;
++      unsigned int function=SET_SPEEDSTEP_STATE;
++
++      if (state > 0x1)
++              return;
++
++      old_state = speedstep_get_state();
++      freqs.old = speedstep_freqs[old_state].frequency;
++      freqs.new = speedstep_freqs[state].frequency;
++      freqs.cpu = 0; /* speedstep.c is UP only driver */
++
++      if (old_state == state)
++              return;
++
++      if (notify)
++              cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++
++      /* Disable IRQs */
++      local_irq_save(flags);
++
++      command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
++      __asm__ __volatile__(
++              "movl $0, %%edi\n"
++              "out %%al, (%%dx)\n"
++              : "=b" (new_state), "=D" (result)
++              : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
++      );
++
++      /* enable IRQs */
++      local_irq_restore(flags);
++
++      if (new_state == state) {
++              dprintk(KERN_INFO "cpufreq: change to %u MHz succeded\n", (freqs.new / 1000));
++      } else {
++              printk(KERN_ERR "cpufreq: change failed\n");
++      }
++
++      if (notify)
++              cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++
++      return;
++}
++
++
++/**
++ * speedstep_target - set a new CPUFreq policy
++ * @policy: new policy
++ * @target_freq: new freq
++ * @relation: 
++ *
++ * Sets a new CPUFreq policy/freq.
++ */
++static int speedstep_target (struct cpufreq_policy *policy,
++                      unsigned int target_freq, unsigned int relation)
++{
++      unsigned int newstate = 0;
++
++      if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
++              return -EINVAL;
++
++      speedstep_set_state(newstate, 1);
++
++      return 0;
++}
++
++
++/**
++ * speedstep_verify - verifies a new CPUFreq policy
++ * @freq: new policy
++ *
++ * Limit must be within speedstep_low_freq and speedstep_high_freq, with
++ * at least one border included.
++ */
++static int speedstep_verify (struct cpufreq_policy *policy)
++{
++      return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
++}
++
++
++static int speedstep_cpu_init(struct cpufreq_policy *policy)
++{
++      int result;
++      unsigned int speed,state;
++
++      /* capability check */
++      if (policy->cpu != 0)
++              return -ENODEV;
++
++      result = speedstep_smi_ownership();
++
++      if (result)
++              dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n");
++
++      /* detect low and high frequency */
++      result = speedstep_smi_get_freqs(&speedstep_freqs[SPEEDSTEP_LOW].frequency,
++                              &speedstep_freqs[SPEEDSTEP_HIGH].frequency);
++      if (result) {
++              /* fall back to speedstep_lib.c dection mechanism: try both states out */
++              unsigned int speedstep_processor = speedstep_detect_processor();
++
++              dprintk(KERN_INFO PFX "could not detect low and high frequencies by SMI call.\n");
++              if (!speedstep_processor)
++                      return -ENODEV;
++
++              result = speedstep_get_freqs(speedstep_processor,
++                              &speedstep_freqs[SPEEDSTEP_LOW].frequency,
++                              &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
++                              &speedstep_set_state);
++
++              if (result) {
++                      dprintk(KERN_INFO PFX "could not detect two different speeds -- aborting.\n");
++                      return result;
++              } else
++                      dprintk(KERN_INFO PFX "workaround worked.\n");
++      }
++
++      /* get current speed setting */
++      state = speedstep_get_state();
++      speed = speedstep_freqs[state].frequency;
++
++      dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", 
++              (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
++              (speed / 1000));
++
++      /* cpuinfo and default policy values */
++      policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
++      policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
++      policy->cur = speed;
++
++      return cpufreq_frequency_table_cpuinfo(policy, &speedstep_freqs[0]);
++}
++
++
++static int speedstep_resume(struct cpufreq_policy *policy)
++{
++      int result = speedstep_smi_ownership();
++
++      if (result)
++              dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n");
++
++      return result;
++}
++
++
++static struct cpufreq_driver speedstep_driver = {
++      .name           = "speedstep-smi",
++      .verify         = speedstep_verify,
++      .target         = speedstep_target,
++      .init           = speedstep_cpu_init,
++      .resume         = speedstep_resume,
++};
++
++/**
++ * speedstep_init - initializes the SpeedStep CPUFreq driver
++ *
++ *   Initializes the SpeedStep support. Returns -ENODEV on unsupported
++ * BIOS, -EINVAL on problems during initiatization, and zero on
++ * success.
++ */
++static int __init speedstep_init(void)
++{
++    struct cpuinfo_x86 *c = cpu_data;
++
++    if (c->x86_vendor != X86_VENDOR_INTEL) {
++              printk (KERN_INFO PFX "No Intel CPU detected.\n");
++              return -ENODEV;
++      }
++
++      dprintk(KERN_DEBUG PFX "signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", 
++              ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level);
++
++
++      /* Error if no IST-SMI BIOS or no PARM 
++               sig= 'ISGE' aka 'Intel Speedstep Gate E' */
++      if ((ist_info.signature !=  0x47534943) && ( 
++          (smi_port == 0) || (smi_cmd == 0)))
++              return -ENODEV;
++
++      if (smi_sig == 1)
++              smi_sig = 0x47534943;
++      else
++              smi_sig = ist_info.signature;
++
++      /* setup smi_port from MODLULE_PARM or BIOS */
++      if ((smi_port > 0xff) || (smi_port < 0)) {
++              return -EINVAL;
++      } else if (smi_port == 0) {
++              smi_port = ist_info.command & 0xff;
++      }
++
++      if ((smi_cmd > 0xff) || (smi_cmd < 0)) {
++              return -EINVAL;
++      } else if (smi_cmd == 0) {
++              smi_cmd = (ist_info.command >> 16) & 0xff;
++      }
++
++      return cpufreq_register_driver(&speedstep_driver);
++}
++
++
++/**
++ * speedstep_exit - unregisters SpeedStep support
++ *
++ *   Unregisters SpeedStep support.
++ */
++static void __exit speedstep_exit(void)
++{
++      cpufreq_unregister_driver(&speedstep_driver);
++}
++
++module_param(smi_port,  int, 0444);
++module_param(smi_cmd,   int, 0444);
++module_param(smi_sig,  uint, 0444);
++
++MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value -- Intel's default setting is 0xb2");
++MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value -- Intel's default setting is 0x82");
++MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the SMI interface.");
++
++MODULE_AUTHOR ("Hiroshi Miura");
++MODULE_DESCRIPTION ("Speedstep driver for IST applet SMI interface.");
++MODULE_LICENSE ("GPL");
++
++module_init(speedstep_init);
++module_exit(speedstep_exit);
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/intel.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/intel.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/intel.c     2003-09-27 11:38:18.972644104 +0800
+@@ -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,14 +156,14 @@
+               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;
+               }
+       }
+ #endif
+-
++      select_idle_routine(c);
+       if (c->cpuid_level > 1) {
+               /* supports eax=2  call */
+               int i, j, n;
+Index: linux-2.6.0-test5/arch/i386/kernel/cpu/mtrr/if.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/cpu/mtrr/if.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/cpu/mtrr/if.c   2003-09-27 11:38:18.975643648 +0800
+@@ -13,7 +13,6 @@
+ /* RED-PEN: this is accessed without any locking */
+ extern unsigned int *usage_table;
+-static int mtrr_seq_show(struct seq_file *seq, void *offset);
+ #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private)
+@@ -33,6 +32,8 @@
+       return (x <= 6) ? mtrr_strings[x] : "?";
+ }
++#ifdef CONFIG_PROC_FS
++
+ static int
+ mtrr_file_add(unsigned long base, unsigned long size,
+             unsigned int type, char increment, struct file *file, int page)
+@@ -291,6 +292,8 @@
+       return single_release(ino, file);
+ }
++static int mtrr_seq_show(struct seq_file *seq, void *offset);
++
+ static int mtrr_open(struct inode *inode, struct file *file)
+ {
+       if (!mtrr_if) 
+@@ -310,11 +313,9 @@
+       .release = mtrr_close,
+ };
+-#  ifdef CONFIG_PROC_FS
+ static struct proc_dir_entry *proc_root_mtrr;
+-#  endif                      /*  CONFIG_PROC_FS  */
+ static int mtrr_seq_show(struct seq_file *seq, void *offset)
+ {
+@@ -351,15 +352,14 @@
+ static int __init mtrr_if_init(void)
+ {
+-#ifdef CONFIG_PROC_FS
+       proc_root_mtrr =
+           create_proc_entry("mtrr", S_IWUSR | S_IRUGO, &proc_root);
+       if (proc_root_mtrr) {
+               proc_root_mtrr->owner = THIS_MODULE;
+               proc_root_mtrr->proc_fops = &mtrr_fops;
+       }
+-#endif
+       return 0;
+ }
+ arch_initcall(mtrr_if_init);
++#endif                        /*  CONFIG_PROC_FS  */
+Index: linux-2.6.0-test5/arch/i386/kernel/dmi_scan.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/dmi_scan.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/dmi_scan.c      2003-09-27 11:38:18.984642280 +0800
+@@ -939,11 +939,6 @@
+                       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 @@
+       { 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, }
+Index: linux-2.6.0-test5/arch/i386/kernel/doublefault.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/doublefault.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/doublefault.c   2003-09-27 11:38:18.985642128 +0800
+@@ -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 @@
+                       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);
+               }
+       }
+Index: linux-2.6.0-test5/arch/i386/kernel/entry.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/entry.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/entry.S 2003-09-27 11:38:18.991641216 +0800
+@@ -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 @@
+ #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 @@
+       movl %edx, %ds; \
+       movl %edx, %es;
+-#define RESTORE_INT_REGS \
++#define __RESTORE_INT_REGS \
+       popl %ebx;      \
+       popl %ecx;      \
+       popl %edx;      \
+@@ -109,29 +218,28 @@
+       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 @@
+ .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 @@
+       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 @@
+       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 @@
+ #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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+                                       # 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 @@
+  */
+ .data
+ ENTRY(interrupt)
+-.text
++.previous
+ vector=0
+ ENTRY(irq_entries_start)
+@@ -390,7 +549,7 @@
+       jmp common_interrupt
+ .data
+       .long 1b
+-.text
++.previous
+ vector=vector+1
+ .endr
+@@ -431,12 +590,17 @@
+       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 @@
+       pushl %edx
+       call do_nmi
+       addl $8, %esp
+-      RESTORE_ALL
++      jmp restore_all
+ nmi_stack_fixup:
+       FIX_STACK(12,nmi_stack_correct, 1)
+@@ -604,6 +768,8 @@
+       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 */
+@@ -881,3 +1047,57 @@
+       .long sys_fadvise64_64
+ 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
+Index: linux-2.6.0-test5/arch/i386/kernel/entry_trampoline.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/entry_trampoline.c 2003-09-27 11:38:18.433726032 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/entry_trampoline.c      2003-09-27 11:38:18.992641064 +0800
+@@ -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();
++}
+Index: linux-2.6.0-test5/arch/i386/kernel/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/head.S     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/head.S  2003-09-27 11:38:18.996640456 +0800
+@@ -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 @@
+ /* 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 @@
+       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 @@
+       .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 @@
+ .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)
+ /*
+- * 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 @@
+       .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 */
+Index: linux-2.6.0-test5/arch/i386/kernel/i386_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/i386_ksyms.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/i386_ksyms.c    2003-09-27 11:38:18.998640152 +0800
+@@ -33,6 +33,7 @@
+ #include <asm/tlbflush.h>
+ #include <asm/nmi.h>
+ #include <asm/edd.h>
++#include <asm/ist.h>
+ extern void dump_thread(struct pt_regs *, struct user *);
+ extern spinlock_t rtc_lock;
+@@ -62,9 +63,6 @@
+ /* platform dependent support */
+ EXPORT_SYMBOL(boot_cpu_data);
+-#ifdef CONFIG_EISA
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+ EXPORT_SYMBOL(MCA_bus);
+ #ifdef CONFIG_DISCONTIGMEM
+ EXPORT_SYMBOL(node_data);
+@@ -100,7 +98,6 @@
+ 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);
+@@ -114,13 +111,17 @@
+ 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);
+@@ -209,3 +210,7 @@
+ EXPORT_SYMBOL(edd);
+ EXPORT_SYMBOL(eddnr);
+ #endif
++
++#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
++EXPORT_SYMBOL(ist_info);
++#endif
+Index: linux-2.6.0-test5/arch/i386/kernel/i387.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/i387.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/i387.c  2003-09-27 11:38:19.009638480 +0800
+@@ -219,6 +219,7 @@
+ 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 @@
+       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 @@
+       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 @@
+       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;
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/init_task.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/init_task.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/init_task.c     2003-09-27 11:38:19.011638176 +0800
+@@ -23,7 +23,7 @@
+  */
+ 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 @@
+  * 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 };
+Index: linux-2.6.0-test5/arch/i386/kernel/io_apic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/io_apic.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/io_apic.c       2003-09-27 11:38:19.027635744 +0800
+@@ -1143,6 +1143,7 @@
+ static int __init assign_irq_vector(int irq)
+ {
+       static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
++      BUG_ON(irq >= NR_IRQS);
+       if (IO_APIC_VECTOR(irq) > 0)
+               return IO_APIC_VECTOR(irq);
+ next:
+@@ -1652,6 +1653,10 @@
+                       mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
+               }
++              /* Don't check I/O APIC IDs for some xAPIC systems.  They have
++               * no meaning without the serial APIC bus. */
++              if (NO_IOAPIC_CHECK)
++                      continue;
+               /*
+                * Sanity check, is the ID really free? Every APIC in a
+                * system must have a unique ID or we get lots of nice
+Index: linux-2.6.0-test5/arch/i386/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/irq.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/irq.c   2003-09-27 11:38:19.035634528 +0800
+@@ -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 @@
+       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;
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/kgdb_stub.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/kgdb_stub.c        2003-09-27 11:38:18.433726032 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/kgdb_stub.c     2003-09-27 11:38:19.040633768 +0800
+@@ -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);
++
+Index: linux-2.6.0-test5/arch/i386/kernel/ldt.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/ldt.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/ldt.c   2003-09-27 11:38:19.043633312 +0800
+@@ -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 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 @@
+               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 @@
+       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 @@
+ /*
+  * 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 @@
+               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 @@
+       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 @@
+                       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 @@
+       *lp     = entry_1;
+       *(lp+1) = entry_2;
+       error = 0;
++      preempt_enable();
+ out_unlock:
+       up(&mm->context.sem);
+@@ -248,3 +271,26 @@
+       }
+       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();
++}
+Index: linux-2.6.0-test5/arch/i386/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/Makefile   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/Makefile        2003-09-27 11:38:19.045633008 +0800
+@@ -7,19 +7,18 @@
+ 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 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
+-obj-$(CONFIG_PM)              += suspend.o
+ obj-$(CONFIG_APM)             += apm.o
+-obj-$(CONFIG_SOFTWARE_SUSPEND)        += suspend_asm.o
+ obj-$(CONFIG_X86_SMP)         += smp.o smpboot.o
+ obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline.o
+ obj-$(CONFIG_X86_MPPARSE)     += mpparse.o
+Index: linux-2.6.0-test5/arch/i386/kernel/mpparse.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/mpparse.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/mpparse.c       2003-09-27 11:38:19.053631792 +0800
+@@ -167,6 +167,11 @@
+               boot_cpu_logical_apicid = apicid;
+       }
++      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);
++              return;
++      }
+       num_processors++;
+       if (MAX_APICS - m->mpc_apicid <= 0) {
+@@ -656,7 +661,7 @@
+                * 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");
+@@ -825,7 +830,7 @@
+       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
+@@ -1014,10 +1019,6 @@
+       }
+ }
+-#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)
+@@ -1026,6 +1027,7 @@
+       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,15 +1051,12 @@
+                                * 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;
++                              flags = entry->flags;
++                              acpi_fadt.sci_int = entry->global_irq;
++                              irq = entry->global_irq;
++                              break;
+                       }
+-
++                      
+                       entry = (struct acpi_table_int_src_ovr *)
+                               ((unsigned long) entry + entry->header.length);
+               }
+@@ -1067,9 +1066,14 @@
+       ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+-      io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered
++      if (flags.polarity == 0)
++              flags.polarity = 0x3;   /* Active low */ 
++      if (flags.trigger == 0) 
++              flags.trigger = 0x3;    /* Level-triggered */
++
++      io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 
++                              (flags.trigger >> 1) , (flags.polarity >> 1));
+ }
+-#endif        /* CONFIG_ACPI */
+ #ifdef CONFIG_ACPI_PCI
+@@ -1149,5 +1153,5 @@
+ }
+ #endif /*CONFIG_ACPI_PCI*/
+-#endif        /* CONFIG_X86_IO_APIC */
++#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
+ #endif /*CONFIG_ACPI_BOOT*/
+Index: linux-2.6.0-test5/arch/i386/kernel/nmi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/nmi.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/nmi.c   2003-09-27 11:38:19.057631184 +0800
+@@ -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 @@
+       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 @@
+       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);
+                       /*
+Index: linux-2.6.0-test5/arch/i386/kernel/numaq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/numaq.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/numaq.c 2003-09-27 11:38:19.058631032 +0800
+@@ -99,8 +99,14 @@
+       }
+ }
+-void __init get_memcfg_numaq(void)
++/*
++ * Unlike Summit, we don't really care to let the NUMA-Q
++ * fall back to flat mode.  Don't compile for NUMA-Q
++ * unless you really need it!
++ */
++int __init get_memcfg_numaq(void)
+ {
+       smp_dump_qct();
+       initialize_physnode_map();
++      return 1;
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/process.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/process.c       2003-09-27 11:38:19.064630120 +0800
+@@ -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
+@@ -151,11 +152,57 @@
+       }
+ }
++/*
++ * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
++ * which can obviate IPI to trigger checking of need_resched.
++ * We execute MONITOR against need_resched and enter optimized wait state
++ * through MWAIT. Whenever someone changes need_resched, we would be woken
++ * up from MWAIT (without an IPI).
++ */
++static void mwait_idle(void)
++{
++      local_irq_enable();
++
++      if (!need_resched()) {
++              set_thread_flag(TIF_POLLING_NRFLAG);
++              do {
++                      __monitor((void *)&current_thread_info()->flags, 0, 0);
++                      if (need_resched())
++                              break;
++                      __mwait(0, 0);
++              } while (!need_resched());
++              clear_thread_flag(TIF_POLLING_NRFLAG);
++      }
++}
++
++void __init select_idle_routine(const struct cpuinfo_x86 *c)
++{
++      if (cpu_has(c, X86_FEATURE_MWAIT)) {
++              printk("monitor/mwait feature present.\n");
++              /*
++               * Skip, if setup has overridden idle.
++               * Also, take care of system with asymmetric CPUs.
++               * Use, mwait_idle only if all cpus support it.
++               * If not, we fallback to default_idle()
++               */
++              if (!pm_idle) {
++                      printk("using mwait in idle threads.\n");
++                      pm_idle = mwait_idle;
++              }
++              return;
++      }
++      pm_idle = default_idle;
++      return;
++}
++
+ static int __init idle_setup (char *str)
+ {
+       if (!strncmp(str, "poll", 4)) {
+               printk("using polling idle threads.\n");
+               pm_idle = poll_idle;
++      } else if (!strncmp(str, "halt", 4)) {
++              printk("using halt in idle threads.\n");
++              pm_idle = default_idle;
+       }
+       return 1;
+@@ -252,6 +299,9 @@
+       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..
+@@ -265,9 +315,8 @@
+       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();
+               }
+@@ -302,7 +351,17 @@
+       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);
+@@ -454,10 +513,40 @@
+       __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.
+Index: linux-2.6.0-test5/arch/i386/kernel/reboot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/reboot.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/reboot.c        2003-09-27 11:38:19.072628904 +0800
+@@ -153,12 +153,11 @@
+       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.
+@@ -251,7 +250,7 @@
+        * other OSs see a clean IRQ state.
+        */
+       smp_send_stop();
+-#elif CONFIG_X86_LOCAL_APIC
++#elif defined(CONFIG_X86_LOCAL_APIC)
+       if (cpu_has_apic) {
+               local_irq_disable();
+               disable_local_APIC();
+Index: linux-2.6.0-test5/arch/i386/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/setup.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/setup.c 2003-09-27 11:38:19.079627840 +0800
+@@ -44,6 +44,7 @@
+ #include <asm/arch_hooks.h>
+ #include <asm/sections.h>
+ #include <asm/io_apic.h>
++#include <asm/ist.h>
+ #include "setup_arch_pre.h"
+ #include "mach_resources.h"
+@@ -63,10 +64,10 @@
+ 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);
+@@ -102,6 +103,7 @@
+       unsigned char table[0];
+ };
+ struct edid_info edid_info;
++struct ist_info ist_info;
+ struct e820map e820;
+ unsigned char aux_device_present;
+@@ -955,11 +957,12 @@
+       pre_setup_arch_hook();
+       early_cpu_init();
+-      ROOT_DEV = ORIG_ROOT_DEV;
++      ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+       drive_info = DRIVE_INFO;
+       screen_info = SCREEN_INFO;
+       edid_info = EDID_INFO;
+       apm_info.bios = APM_BIOS_INFO;
++      ist_info = IST_INFO;
+       saved_videomode = VIDEO_MODE;
+       printk("Video mode to be used for restore is %lx\n", saved_videomode);
+       if( SYS_DESC_TABLE.length != 0 ) {
+Index: linux-2.6.0-test5/arch/i386/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/signal.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/signal.c        2003-09-27 11:38:19.084627080 +0800
+@@ -128,25 +128,25 @@
+  */
+ 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 @@
+       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 @@
+  */
+ 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 @@
+       /* 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);
+Index: linux-2.6.0-test5/arch/i386/kernel/smpboot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/smpboot.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/smpboot.c       2003-09-27 11:38:19.092625864 +0800
+@@ -499,8 +499,8 @@
+ #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 @@
+       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;
+ }
+@@ -915,13 +915,13 @@
+               cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth;
+       }
+-      cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000;
++      cache_decay_ticks = (long)cacheflush_time/cpu_khz + 1;
+       printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n",
+               (long)cacheflush_time/(cpu_khz/1000),
+               ((long)cacheflush_time*100/(cpu_khz/1000)) % 100);
+       printk("task migration cache decay timeout: %ld msecs.\n",
+-              (cache_decay_ticks + 1) * 1000 / HZ);
++              cache_decay_ticks);
+ }
+ /*
+Index: linux-2.6.0-test5/arch/i386/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/smp.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/smp.c   2003-09-27 11:38:19.097625104 +0800
+@@ -327,10 +327,12 @@
+                
+       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 @@
+       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 @@
+       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 @@
+ {
+       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
+Index: linux-2.6.0-test5/arch/i386/kernel/srat.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/srat.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/srat.c  2003-09-27 11:38:19.105623888 +0800
+@@ -239,6 +239,11 @@
+               }
+       }
++      if (num_memory_chunks == 0) {
++              printk("could not finy any ACPI SRAT memory areas.\n");
++              goto out_fail;
++      }
++
+       /* Calculate total number of nodes in system from PXM bitmap and create
+        * a set of sequential node IDs starting at zero.  (ACPI doesn't seem
+        * to specify the range of _PXM values.)
+@@ -295,10 +300,12 @@
+                       }
+               }
+       }
++      return 1;
++out_fail:
+       return 0;
+ }
+-void __init get_memcfg_from_srat(void)
++int __init get_memcfg_from_srat(void)
+ {
+       struct acpi_table_header *header = NULL;
+       struct acpi_table_rsdp *rsdp = NULL;
+@@ -316,11 +323,11 @@
+                               (u32)rsdp_address->pointer.physical;
+       } else {
+               printk("%s: rsdp_address is not a physical pointer\n", __FUNCTION__);
+-              return;
++              goto out_err;
+       }
+       if (!rsdp) {
+               printk("%s: Didn't find ACPI root!\n", __FUNCTION__);
+-              return;
++              goto out_err;
+       }
+       printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
+@@ -328,7 +335,7 @@
+       if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
+               printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __FUNCTION__);
+-              return;
++              goto out_err;
+       }
+       rsdt = (struct acpi_table_rsdt *)
+@@ -338,14 +345,14 @@
+               printk(KERN_WARNING
+                      "%s: ACPI: Invalid root system description tables (RSDT)\n",
+                      __FUNCTION__);
+-              return;
++              goto out_err;
+       }
+       header = & rsdt->header;
+       if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
+               printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
+-              return;
++              goto out_err;
+       }
+       /* 
+@@ -356,15 +363,18 @@
+        */
+       tables = (header->length - sizeof(struct acpi_table_header)) / 4;
++      if (!tables)
++              goto out_err;
++
+       memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
+       if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
+               printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n",
+                      saved_rsdt.header.length);
+-              return;
++              goto out_err;
+       }
+-printk("Begin table scan....\n");
++      printk("Begin SRAT table scan....\n");
+       for (i = 0; i < tables; i++) {
+               /* Map in header, then map in full table length. */
+@@ -379,10 +389,13 @@
+               if (strncmp((char *) &header->signature, "SRAT", 4))
+                       continue;
+-              acpi20_parse_srat((struct acpi_table_srat *)header);
++
+               /* we've found the srat table. don't need to look at any more tables */
+-              break;
++              return acpi20_parse_srat((struct acpi_table_srat *)header);
+       }
++out_err:
++      printk("failed to get NUMA memory information from SRAT table\n");
++      return 0;
+ }
+ /* For each node run the memory list to determine whether there are
+Index: linux-2.6.0-test5/arch/i386/kernel/sysenter.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/sysenter.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/sysenter.c      2003-09-27 11:38:19.107623584 +0800
+@@ -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;
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/common.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/common.c    2003-09-27 11:38:18.434725880 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/common.c 2003-09-27 11:38:19.108623432 +0800
+@@ -0,0 +1,139 @@
++/*
++ *    Common functions used across the timers go here
++ */
++
++#include <linux/init.h>
++#include <linux/timex.h>
++#include <linux/errno.h>
++
++#include <asm/io.h>
++#include <asm/timer.h>
++#include <asm/hpet.h>
++
++#include "mach_timer.h"
++
++/* ------ Calibrate the TSC -------
++ * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
++ * Too much 64-bit arithmetic here to do this cleanly in C, and for
++ * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
++ * output busy loop as low as possible. We avoid reading the CTC registers
++ * directly because of the awkward 8-bit access mechanism of the 82C54
++ * device.
++ */
++
++#define CALIBRATE_TIME        (5 * 1000020/HZ)
++
++unsigned long __init calibrate_tsc(void)
++{
++      mach_prepare_counter();
++
++      {
++              unsigned long startlow, starthigh;
++              unsigned long endlow, endhigh;
++              unsigned long count;
++
++              rdtsc(startlow,starthigh);
++              mach_countup(&count);
++              rdtsc(endlow,endhigh);
++
++
++              /* Error: ECTCNEVERSET */
++              if (count <= 1)
++                      goto bad_ctc;
++
++              /* 64-bit subtract - gcc just messes up with long longs */
++              __asm__("subl %2,%0\n\t"
++                      "sbbl %3,%1"
++                      :"=a" (endlow), "=d" (endhigh)
++                      :"g" (startlow), "g" (starthigh),
++                       "0" (endlow), "1" (endhigh));
++
++              /* Error: ECPUTOOFAST */
++              if (endhigh)
++                      goto bad_ctc;
++
++              /* Error: ECPUTOOSLOW */
++              if (endlow <= CALIBRATE_TIME)
++                      goto bad_ctc;
++
++              __asm__("divl %2"
++                      :"=a" (endlow), "=d" (endhigh)
++                      :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));
++
++              return endlow;
++      }
++
++      /*
++       * The CTC wasn't reliable: we got a hit on the very first read,
++       * or the CPU was so fast/slow that the quotient wouldn't fit in
++       * 32 bits..
++       */
++bad_ctc:
++      return 0;
++}
++
++#ifdef CONFIG_HPET_TIMER
++/* ------ Calibrate the TSC using HPET -------
++ * Return 2^32 * (1 / (TSC clocks per usec)) for getting the CPU freq.
++ * Second output is parameter 1 (when non NULL)
++ * Set 2^32 * (1 / (tsc per HPET clk)) for delay_hpet().
++ * calibrate_tsc() calibrates the processor TSC by comparing
++ * it to the HPET timer of known frequency.
++ * Too much 64-bit arithmetic here to do this cleanly in C
++ */
++#define CALIBRATE_CNT_HPET    (5 * hpet_tick)
++#define CALIBRATE_TIME_HPET   (5 * KERNEL_TICK_USEC)
++
++unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
++{
++      unsigned long tsc_startlow, tsc_starthigh;
++      unsigned long tsc_endlow, tsc_endhigh;
++      unsigned long hpet_start, hpet_end;
++      unsigned long result, remain;
++
++      hpet_start = hpet_readl(HPET_COUNTER);
++      rdtsc(tsc_startlow, tsc_starthigh);
++      do {
++              hpet_end = hpet_readl(HPET_COUNTER);
++      } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET);
++      rdtsc(tsc_endlow, tsc_endhigh);
++
++      /* 64-bit subtract - gcc just messes up with long longs */
++      __asm__("subl %2,%0\n\t"
++              "sbbl %3,%1"
++              :"=a" (tsc_endlow), "=d" (tsc_endhigh)
++              :"g" (tsc_startlow), "g" (tsc_starthigh),
++               "0" (tsc_endlow), "1" (tsc_endhigh));
++
++      /* Error: ECPUTOOFAST */
++      if (tsc_endhigh)
++              goto bad_calibration;
++
++      /* Error: ECPUTOOSLOW */
++      if (tsc_endlow <= CALIBRATE_TIME_HPET)
++              goto bad_calibration;
++
++      ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET);
++      if (remain > (tsc_endlow >> 1))
++              result++; /* rounding the result */
++
++      if (tsc_hpet_quotient_ptr) {
++              unsigned long tsc_hpet_quotient;
++
++              ASM_DIV64_REG(tsc_hpet_quotient, remain, tsc_endlow, 0,
++                      CALIBRATE_CNT_HPET);
++              if (remain > (tsc_endlow >> 1))
++                      tsc_hpet_quotient++; /* rounding the result */
++              *tsc_hpet_quotient_ptr = tsc_hpet_quotient;
++      }
++
++      return result;
++bad_calibration:
++      /*
++       * the CPU was so fast/slow that the quotient wouldn't fit in
++       * 32 bits..
++       */
++      return 0;
++}
++#endif
++
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/Makefile    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/Makefile 2003-09-27 11:38:19.109623280 +0800
+@@ -2,7 +2,7 @@
+ # Makefile for x86 timers
+ #
+-obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o
++obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o common.o
+ obj-$(CONFIG_X86_CYCLONE_TIMER)       += timer_cyclone.o
+ obj-$(CONFIG_HPET_TIMER)      += timer_hpet.o
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/timer_cyclone.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/timer_cyclone.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/timer_cyclone.c  2003-09-27 11:38:19.111622976 +0800
+@@ -19,7 +19,6 @@
+ #include <asm/fixmap.h>
+ extern spinlock_t i8253_lock;
+-extern unsigned long calibrate_tsc(void);
+ /* Number of usecs that the last interrupt was delayed */
+ static int delay_at_last_interrupt;
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/timer_hpet.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/timer_hpet.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/timer_hpet.c     2003-09-27 11:38:19.114622520 +0800
+@@ -131,63 +131,6 @@
+       } while ((hpet_end - hpet_start) < (loops));
+ }
+-/* ------ Calibrate the TSC -------
+- * Return 2^32 * (1 / (TSC clocks per usec)) for getting the CPU freq.
+- * Set 2^32 * (1 / (tsc per HPET clk)) for delay_hpet().
+- * calibrate_tsc() calibrates the processor TSC by comparing
+- * it to the HPET timer of known frequency.
+- * Too much 64-bit arithmetic here to do this cleanly in C
+- */
+-#define CALIBRATE_CNT_HPET    (5 * hpet_tick)
+-#define CALIBRATE_TIME_HPET   (5 * KERNEL_TICK_USEC)
+-
+-static unsigned long __init calibrate_tsc(void)
+-{
+-      unsigned long tsc_startlow, tsc_starthigh;
+-      unsigned long tsc_endlow, tsc_endhigh;
+-      unsigned long hpet_start, hpet_end;
+-      unsigned long result, remain;
+-
+-      hpet_start = hpet_readl(HPET_COUNTER);
+-      rdtsc(tsc_startlow, tsc_starthigh);
+-      do {
+-              hpet_end = hpet_readl(HPET_COUNTER);
+-      } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET);
+-      rdtsc(tsc_endlow, tsc_endhigh);
+-
+-      /* 64-bit subtract - gcc just messes up with long longs */
+-      __asm__("subl %2,%0\n\t"
+-              "sbbl %3,%1"
+-              :"=a" (tsc_endlow), "=d" (tsc_endhigh)
+-              :"g" (tsc_startlow), "g" (tsc_starthigh),
+-               "0" (tsc_endlow), "1" (tsc_endhigh));
+-
+-      /* Error: ECPUTOOFAST */
+-      if (tsc_endhigh)
+-              goto bad_calibration;
+-
+-      /* Error: ECPUTOOSLOW */
+-      if (tsc_endlow <= CALIBRATE_TIME_HPET)
+-              goto bad_calibration;
+-
+-      ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET);
+-      if (remain > (tsc_endlow >> 1))
+-              result++; /* rounding the result */
+-
+-      ASM_DIV64_REG(tsc_hpet_quotient, remain, tsc_endlow, 0,
+-                      CALIBRATE_CNT_HPET);
+-      if (remain > (tsc_endlow >> 1))
+-              tsc_hpet_quotient++; /* rounding the result */
+-
+-      return result;
+-bad_calibration:
+-      /*
+-       * the CPU was so fast/slow that the quotient wouldn't fit in
+-       * 32 bits..
+-       */
+-      return 0;
+-}
+-
+ static int __init init_hpet(char* override)
+ {
+       unsigned long result, remain;
+@@ -201,7 +144,7 @@
+       printk("Using HPET for gettimeofday\n");
+       if (cpu_has_tsc) {
+-              unsigned long tsc_quotient = calibrate_tsc();
++              unsigned long tsc_quotient = calibrate_tsc_hpet(&tsc_hpet_quotient);
+               if (tsc_quotient) {
+                       /* report CPU clock rate in Hz.
+                        * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
+Index: linux-2.6.0-test5/arch/i386/kernel/timers/timer_tsc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/timers/timer_tsc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/timers/timer_tsc.c      2003-09-27 11:38:19.121621456 +0800
+@@ -39,7 +39,7 @@
+ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
+ static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */
+ static unsigned long long monotonic_base;
+-static rwlock_t monotonic_lock = RW_LOCK_UNLOCKED;
++static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
+ /* convert from cycles(64bits) => nanoseconds (64bits)
+  *  basic equation:
+@@ -111,12 +111,14 @@
+ static unsigned long long monotonic_clock_tsc(void)
+ {
+       unsigned long long last_offset, this_offset, base;
++      unsigned seq;
+       
+       /* atomically read monotonic base & last_offset */
+-      read_lock_irq(&monotonic_lock);
+-      last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+-      base = monotonic_base;
+-      read_unlock_irq(&monotonic_lock);
++      do {
++              seq = read_seqbegin(&monotonic_lock);
++              last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
++              base = monotonic_base;
++      } while (read_seqretry(&monotonic_lock, seq));
+       /* Read the Time Stamp Counter */
+       rdtscll(this_offset);
+@@ -125,6 +127,30 @@
+       return base + cycles_2_ns(this_offset - last_offset);
+ }
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ */
++unsigned long long sched_clock(void)
++{
++      unsigned long long this_offset;
++
++      /*
++       * In the NUMA case we dont use the TSC as they are not
++       * synchronized across all CPUs.
++       */
++#ifndef CONFIG_NUMA
++      if (unlikely(!cpu_has_tsc))
++#endif
++              return (unsigned long long)jiffies * (1000000000 / HZ);
++
++      /* Read the Time Stamp Counter */
++      rdtscll(this_offset);
++
++      /* return the value in ns */
++      return cycles_2_ns(this_offset);
++}
++
++
+ static void mark_offset_tsc(void)
+ {
+       unsigned long lost,delay;
+@@ -135,7 +161,7 @@
+       unsigned long long this_offset, last_offset;
+       static int lost_count = 0;
+       
+-      write_lock(&monotonic_lock);
++      write_seqlock(&monotonic_lock);
+       last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+       /*
+        * It is important that these two operations happen almost at
+@@ -204,7 +230,7 @@
+       /* update the monotonic base value */
+       this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+       monotonic_base += cycles_2_ns(this_offset - last_offset);
+-      write_unlock(&monotonic_lock);
++      write_sequnlock(&monotonic_lock);
+       /* calculate delay_at_last_interrupt */
+       count = ((LATCH-1) - count) * TICK_SIZE;
+@@ -230,74 +256,13 @@
+       } while ((now-bclock) < loops);
+ }
+-/* ------ Calibrate the TSC ------- 
+- * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
+- * Too much 64-bit arithmetic here to do this cleanly in C, and for
+- * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
+- * output busy loop as low as possible. We avoid reading the CTC registers
+- * directly because of the awkward 8-bit access mechanism of the 82C54
+- * device.
+- */
+-
+-#define CALIBRATE_TIME        (5 * 1000020/HZ)
+-
+-static unsigned long __init calibrate_tsc(void)
+-{
+-      mach_prepare_counter();
+-
+-      {
+-              unsigned long startlow, starthigh;
+-              unsigned long endlow, endhigh;
+-              unsigned long count;
+-
+-              rdtsc(startlow,starthigh);
+-              mach_countup(&count);
+-              rdtsc(endlow,endhigh);
+-
+-              last_tsc_low = endlow;
+-
+-              /* Error: ECTCNEVERSET */
+-              if (count <= 1)
+-                      goto bad_ctc;
+-
+-              /* 64-bit subtract - gcc just messes up with long longs */
+-              __asm__("subl %2,%0\n\t"
+-                      "sbbl %3,%1"
+-                      :"=a" (endlow), "=d" (endhigh)
+-                      :"g" (startlow), "g" (starthigh),
+-                       "0" (endlow), "1" (endhigh));
+-
+-              /* Error: ECPUTOOFAST */
+-              if (endhigh)
+-                      goto bad_ctc;
+-
+-              /* Error: ECPUTOOSLOW */
+-              if (endlow <= CALIBRATE_TIME)
+-                      goto bad_ctc;
+-
+-              __asm__("divl %2"
+-                      :"=a" (endlow), "=d" (endhigh)
+-                      :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));
+-
+-              return endlow;
+-      }
+-
+-      /*
+-       * The CTC wasn't reliable: we got a hit on the very first read,
+-       * or the CPU was so fast/slow that the quotient wouldn't fit in
+-       * 32 bits..
+-       */
+-bad_ctc:
+-      return 0;
+-}
+-
+ #ifdef CONFIG_HPET_TIMER
+ static void mark_offset_tsc_hpet(void)
+ {
+       unsigned long long this_offset, last_offset;
+       unsigned long offset, temp, hpet_current;
+-      write_lock(&monotonic_lock);
++      write_seqlock(&monotonic_lock);
+       last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+       /*
+        * It is important that these two operations happen almost at
+@@ -325,7 +290,7 @@
+       /* update the monotonic base value */
+       this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+       monotonic_base += cycles_2_ns(this_offset - last_offset);
+-      write_unlock(&monotonic_lock);
++      write_sequnlock(&monotonic_lock);
+       /* calculate delay_at_last_interrupt */
+       /*
+@@ -339,58 +304,6 @@
+       ASM_MUL64_REG(temp, delay_at_last_interrupt,
+                       hpet_usec_quotient, delay_at_last_interrupt);
+ }
+-
+-/* ------ Calibrate the TSC based on HPET timer -------
+- * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
+- * calibrate_tsc() calibrates the processor TSC by comparing
+- * it to the HPET timer of known frequency.
+- * Too much 64-bit arithmetic here to do this cleanly in C
+- */
+-
+-#define CALIBRATE_CNT_HPET    (5 * hpet_tick)
+-#define CALIBRATE_TIME_HPET   (5 * KERNEL_TICK_USEC)
+-
+-unsigned long __init calibrate_tsc_hpet(void)
+-{
+-      unsigned long tsc_startlow, tsc_starthigh;
+-      unsigned long tsc_endlow, tsc_endhigh;
+-      unsigned long hpet_start, hpet_end;
+-      unsigned long result, remain;
+-
+-      hpet_start = hpet_readl(HPET_COUNTER);
+-      rdtsc(tsc_startlow, tsc_starthigh);
+-      do {
+-              hpet_end = hpet_readl(HPET_COUNTER);
+-      } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET);
+-      rdtsc(tsc_endlow, tsc_endhigh);
+-
+-      /* 64-bit subtract - gcc just messes up with long longs */
+-      __asm__("subl %2,%0\n\t"
+-              "sbbl %3,%1"
+-              :"=a" (tsc_endlow), "=d" (tsc_endhigh)
+-              :"g" (tsc_startlow), "g" (tsc_starthigh),
+-               "0" (tsc_endlow), "1" (tsc_endhigh));
+-
+-      /* Error: ECPUTOOFAST */
+-      if (tsc_endhigh)
+-              goto bad_calibration;
+-
+-      /* Error: ECPUTOOSLOW */
+-      if (tsc_endlow <= CALIBRATE_TIME_HPET)
+-              goto bad_calibration;
+-
+-      ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET);
+-      if (remain > (tsc_endlow >> 1))
+-              result++; /* rounding the result */
+-
+-      return result;
+-bad_calibration:
+-      /*
+-       * the CPU was so fast/slow that the quotient wouldn't fit in
+-       * 32 bits..
+-       */
+-      return 0;
+-}
+ #endif
+ #ifdef CONFIG_CPU_FREQ
+@@ -425,6 +338,7 @@
+               if (use_tsc) {
+                       fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
+                       cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
++                      set_cyc2ns_scale(cpu_khz/1000);
+               }
+ #endif
+       }
+@@ -491,7 +405,7 @@
+               if (is_hpet_enabled()){
+                       unsigned long result, remain;
+                       printk("Using TSC for gettimeofday\n");
+-                      tsc_quotient = calibrate_tsc_hpet();
++                      tsc_quotient = calibrate_tsc_hpet(NULL);
+                       timer_tsc.mark_offset = &mark_offset_tsc_hpet;
+                       /*
+                        * Math to calculate hpet to usec multiplier
+Index: linux-2.6.0-test5/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/traps.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/traps.c 2003-09-27 11:38:19.128620392 +0800
+@@ -28,6 +28,7 @@
+ #ifdef CONFIG_EISA
+ #include <linux/ioport.h>
++#include <linux/eisa.h>
+ #endif
+ #ifdef CONFIG_MCA
+@@ -53,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;
+@@ -90,6 +87,43 @@
+ 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)
+@@ -172,8 +206,9 @@
+               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 +224,27 @@
+        * 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");
+@@ -252,12 +291,36 @@
+ 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 @@
+ #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 @@
+ #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 @@
+       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)
+@@ -527,10 +595,18 @@
+       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)
+@@ -550,8 +626,18 @@
+                * 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;
+       }
+@@ -563,6 +649,17 @@
+       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 +674,7 @@
+       __asm__("movl %0,%%db7"
+               : /* no output */
+               : "r" (0));
++      CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,)
+       return;
+ debug_vm86:
+@@ -772,19 +870,53 @@
+ #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));
+ }
+-#endif
++
++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 { \
+@@ -811,20 +943,26 @@
+       _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)
+ {
+@@ -832,10 +970,6 @@
+ }
+-#ifdef CONFIG_EISA
+-int EISA_bus;
+-#endif
+-
+ void __init trap_init(void)
+ {
+ #ifdef CONFIG_EISA
+@@ -847,11 +981,16 @@
+ #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);
+Index: linux-2.6.0-test5/arch/i386/kernel/vm86.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vm86.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vm86.c  2003-09-27 11:38:19.134619480 +0800
+@@ -117,7 +117,7 @@
+       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 @@
+       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();
+Index: linux-2.6.0-test5/arch/i386/kernel/vmlinux.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vmlinux.lds.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vmlinux.lds.S   2003-09-27 11:38:19.136619176 +0800
+@@ -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 @@
+ jiffies = jiffies_64;
+ SECTIONS
+ {
+-  . = 0xC0000000 + 0x100000;
++  . = __PAGE_OFFSET + 0x100000;
+   /* read-only */
+   _text = .;                  /* Text and read-only data */
+   .text : {
+@@ -19,6 +22,19 @@
+       *(.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 @@
+       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 @@
+   .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 @@
+      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 @@
+   __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 @@
+   .stab.index 0 : { *(.stab.index) }
+   .stab.indexstr 0 : { *(.stab.indexstr) }
+   .comment 0 : { *(.comment) }
++
++
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/vsyscall.lds
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vsyscall.lds       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vsyscall.lds    2003-09-27 11:38:19.144617960 +0800
+@@ -5,7 +5,7 @@
+  */
+ /* This must match <asm/fixmap.h>.  */
+-VSYSCALL_BASE = 0xffffe000;
++VSYSCALL_BASE = 0xffffd000;
+ SECTIONS
+ {
+Index: linux-2.6.0-test5/arch/i386/kernel/vsyscall-sysenter.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/vsyscall-sysenter.S        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/vsyscall-sysenter.S     2003-09-27 11:38:19.146617656 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/i386/lib/checksum.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/checksum.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/checksum.S 2003-09-27 11:38:19.149617200 +0800
+@@ -280,14 +280,14 @@
+       .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 @@
+ #define ARGBASE 12
+               
+-csum_partial_copy_generic:
++direct_csum_partial_copy_generic:
+       pushl %ebx
+       pushl %edi
+       pushl %esi
+Index: linux-2.6.0-test5/arch/i386/lib/dec_and_lock.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/dec_and_lock.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/dec_and_lock.c     2003-09-27 11:38:19.151616896 +0800
+@@ -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 @@
+       spin_unlock(lock);
+       return 0;
+ }
++#endif
++
+Index: linux-2.6.0-test5/arch/i386/lib/getuser.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/getuser.S     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/getuser.S  2003-09-27 11:38:19.152616744 +0800
+@@ -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 @@
+       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 @@
+       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
+Index: linux-2.6.0-test5/arch/i386/lib/kgdb_serial.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/kgdb_serial.c 2003-09-27 11:38:18.434725880 +0800
++++ linux-2.6.0-test5/arch/i386/lib/kgdb_serial.c      2003-09-27 11:38:19.154616440 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/i386/lib/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/Makefile      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/Makefile   2003-09-27 11:38:19.164614920 +0800
+@@ -9,4 +9,5 @@
+ 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
+Index: linux-2.6.0-test5/arch/i386/lib/usercopy.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/usercopy.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/usercopy.c 2003-09-27 11:38:19.170614008 +0800
+@@ -76,7 +76,7 @@
+  * 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 @@
+  * 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 @@
+  * 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 @@
+  * 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 @@
+  * 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 @@
+               n = __copy_user_zeroing_intel(to, (const void *) from, n);
+       return n;
+ }
++
+Index: linux-2.6.0-test5/arch/i386/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/Makefile  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/Makefile       2003-09-27 11:38:19.182612184 +0800
+@@ -21,11 +21,13 @@
+ CFLAGS += -pipe
+-check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+-
+ # prevent gcc from keeping the stack 16 byte aligned
+ CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,)
++# gcc 3.4/3.3-hammer support -funit-at-a-time mode, but the Kernel is not ready
++# for it yet
++CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
++
+ align := $(subst -functions=0,,$(call check_gcc,-falign-functions=0,-malign-functions=0))
+ cflags-$(CONFIG_M386)         += -march=i386
+@@ -86,6 +88,9 @@
+ # 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/
+@@ -96,6 +101,7 @@
+ drivers-$(CONFIG_PCI)                 += arch/i386/pci/
+ # must be linked after kernel/
+ drivers-$(CONFIG_OPROFILE)            += arch/i386/oprofile/
++drivers-$(CONFIG_PM)                  += arch/i386/power/
+ CFLAGS += $(mflags-y)
+ AFLAGS += $(mflags-y)
+Index: linux-2.6.0-test5/arch/i386/math-emu/fpu_system.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/math-emu/fpu_system.h     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/math-emu/fpu_system.h  2003-09-27 11:38:19.184611880 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/i386/mm/discontig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/discontig.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/discontig.c 2003-09-27 11:38:19.188611272 +0800
+@@ -30,6 +30,7 @@
+ #include <linux/initrd.h>
+ #include <asm/e820.h>
+ #include <asm/setup.h>
++#include <asm/mmzone.h>
+ struct pglist_data *node_data[MAX_NUMNODES];
+ bootmem_data_t node0_bdata;
+@@ -84,7 +85,7 @@
+  *        a single node with all available processors in it with a flat
+  *        memory map.
+  */
+-void __init get_memcfg_numa_flat(void)
++int __init get_memcfg_numa_flat(void)
+ {
+       int pfn;
+@@ -107,6 +108,7 @@
+          /* Indicate there is one node available. */
+       node_set_online(0);
+       numnodes = 1;
++      return 1;
+ }
+ /*
+@@ -355,17 +357,20 @@
+               unsigned long low = max_low_pfn;
+               unsigned long start = node_start_pfn[nid];
+               unsigned long high = node_end_pfn[nid];
+-              
++
+               max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+               if (start > low) {
+ #ifdef CONFIG_HIGHMEM
+-                zones_size[ZONE_HIGHMEM] = high - start;
++                      BUG_ON(start > high);
++                      zones_size[ZONE_HIGHMEM] = high - start;
+ #endif
+               } else {
+                       if (low < max_dma)
+                               zones_size[ZONE_DMA] = low;
+                       else {
++                              BUG_ON(max_dma > low);
++                              BUG_ON(low > high);
+                               zones_size[ZONE_DMA] = max_dma;
+                               zones_size[ZONE_NORMAL] = low - max_dma;
+ #ifdef CONFIG_HIGHMEM
+Index: linux-2.6.0-test5/arch/i386/mm/extable.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/extable.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/extable.c   2003-09-27 11:38:19.190610968 +0800
+@@ -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 @@
+ {
+         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;
+Index: linux-2.6.0-test5/arch/i386/mm/fault.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/fault.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/fault.c     2003-09-27 11:38:19.192610664 +0800
+@@ -55,6 +55,85 @@
+       console_loglevel = loglevel_save;
+ }
++/* Sometimes AMD K7/K8 reports invalid exceptions on prefetch.
++   Check that here and ignore.
++   Opcode checker based on code by Richard Brunner */
++static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
++{
++      unsigned char *instr = (unsigned char *)(regs->eip);
++      int scan_more;
++      int prefetch = 0;
++      int c;
++
++      /* Avoid recursive faults. This is just an optimization,
++         they must be handled correctly too */
++      if (regs->eip == addr)
++              return 0;
++
++      /* Don't check for LDT code segments because they could have
++         non zero bases. Better would be to add in the base in this case. */
++      if (regs->xcs & (1<<2))
++              return 0;
++
++      scan_more = 1;
++      for (c = 0; c < 15 && scan_more; c++) {
++              unsigned char opcode;
++              unsigned char instr_hi;
++              unsigned char instr_lo;
++
++              if (__get_user(opcode, 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.  In long mode, the CPU will signal
++                         invalid opcode if some of these prefixes are
++                         present so we will never get here anyway */
++                      scan_more = ((instr_lo & 7) == 0x6);
++                      break;
++
++              case 0x40:
++                      /* May be valid in long mode (REX prefixes) */
++                      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 (__get_user(opcode, instr))
++                              break;
++                      prefetch = (instr_lo == 0xF) &&
++                              (opcode == 0x0D || opcode == 0x18);
++                      break;
++              default:
++                      scan_more = 0;
++                      break;
++              }
++      }
++      return prefetch;
++}
++
++static inline int is_prefetch(struct pt_regs *regs, unsigned long addr)
++{
++      if (likely(boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
++                 boot_cpu_data.x86 < 6))
++              return 0;
++      return __is_prefetch(regs, addr);
++}
++
+ asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
+ /*
+@@ -110,7 +189,7 @@
+        * 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 +277,12 @@
+ bad_area:
+       up_read(&mm->mmap_sem);
++bad_area_nosemaphore:
+       /* User mode accesses just cause a SIGSEGV */
+       if (error_code & 4) {
++              if (is_prefetch(regs, address))
++                      return;
++
+               tsk->thread.cr2 = address;
+               tsk->thread.error_code = error_code;
+               tsk->thread.trap_no = 14;
+@@ -232,10 +315,19 @@
+       if (fixup_exception(regs))
+               return;
++      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 +378,13 @@
+ 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;
++
++      if (is_prefetch(regs, address))
++              return;
++
+       tsk->thread.cr2 = address;
+       tsk->thread.error_code = error_code;
+       tsk->thread.trap_no = 14;
+@@ -298,10 +393,6 @@
+       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:
+Index: linux-2.6.0-test5/arch/i386/mm/hugetlbpage.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/hugetlbpage.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/hugetlbpage.c       2003-09-27 11:38:19.196610056 +0800
+@@ -355,14 +355,21 @@
+                       + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+               page = find_get_page(mapping, idx);
+               if (!page) {
++                      /* charge the fs quota first */
++                      if (hugetlb_get_quota(mapping)) {
++                              ret = -ENOMEM;
++                              goto out;
++                      }
+                       page = alloc_hugetlb_page();
+                       if (!page) {
++                              hugetlb_put_quota(mapping);
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+                       unlock_page(page);
+                       if (ret) {
++                              hugetlb_put_quota(mapping);
+                               free_huge_page(page);
+                               goto out;
+                       }
+Index: linux-2.6.0-test5/arch/i386/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/init.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/init.c      2003-09-27 11:38:19.210607928 +0800
+@@ -38,125 +38,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)
+@@ -186,38 +74,14 @@
+       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 +96,8 @@
+               SetPageReserved(page);
+ }
++#ifdef CONFIG_HIGHMEM
++
+ #ifndef CONFIG_DISCONTIGMEM
+ void __init set_highmem_pages_init(int bad_ppro) 
+ {
+@@ -243,12 +109,9 @@
+ #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 +121,125 @@
+ 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;
+-      pgd_t *pgd_base = swapper_pg_dir;
++      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;
++      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 +247,64 @@
+        * 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 +408,7 @@
+ #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 +417,8 @@
+       int tmp;
+       int bad_ppro;
++      fixup_sort_exception_table();
++
+ #ifndef CONFIG_DISCONTIGMEM
+       if (!mem_map)
+               BUG();
+@@ -507,13 +494,18 @@
+ #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 +515,36 @@
+                                       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");
+ }
+Index: linux-2.6.0-test5/arch/i386/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/ioremap.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/ioremap.c   2003-09-27 11:38:19.213607472 +0800
+@@ -158,7 +158,7 @@
+               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;
+       }
+Index: linux-2.6.0-test5/arch/i386/mm/pgtable.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/pgtable.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/pgtable.c   2003-09-27 11:38:19.218606712 +0800
+@@ -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 @@
+       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 @@
+  * 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 @@
+       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 @@
+       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 @@
+ {
+       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);
+ }
++
+Index: linux-2.6.0-test5/arch/i386/pci/acpi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/pci/acpi.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/pci/acpi.c     2003-09-27 11:38:19.219606560 +0800
+@@ -15,10 +15,11 @@
+ 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");
+Index: linux-2.6.0-test5/arch/i386/power/cpu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/cpu.c       2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/cpu.c    2003-09-27 11:38:19.220606408 +0800
+@@ -0,0 +1,141 @@
++/*
++ * Suspend support specific for i386.
++ *
++ * Distribute under GPLv2
++ *
++ * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
++ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++#include <linux/poll.h>
++#include <linux/delay.h>
++#include <linux/sysrq.h>
++#include <linux/proc_fs.h>
++#include <linux/irq.h>
++#include <linux/pm.h>
++#include <linux/device.h>
++#include <linux/suspend.h>
++#include <linux/acpi.h>
++#include <asm/uaccess.h>
++#include <asm/acpi.h>
++#include <asm/tlbflush.h>
++
++static struct saved_context saved_context;
++static void fix_processor_context(void);
++
++unsigned long saved_context_eax, saved_context_ebx;
++unsigned long saved_context_ecx, saved_context_edx;
++unsigned long saved_context_esp, saved_context_ebp;
++unsigned long saved_context_esi, saved_context_edi;
++unsigned long saved_context_eflags;
++
++extern void enable_sep_cpu(void *);
++
++void save_processor_state(void)
++{
++      kernel_fpu_begin();
++
++      /*
++       * descriptor tables
++       */
++      asm volatile ("sgdt %0" : "=m" (saved_context.gdt_limit));
++      asm volatile ("sidt %0" : "=m" (saved_context.idt_limit));
++      asm volatile ("sldt %0" : "=m" (saved_context.ldt));
++      asm volatile ("str %0"  : "=m" (saved_context.tr));
++
++      /*
++       * segment registers
++       */
++      asm volatile ("movw %%es, %0" : "=m" (saved_context.es));
++      asm volatile ("movw %%fs, %0" : "=m" (saved_context.fs));
++      asm volatile ("movw %%gs, %0" : "=m" (saved_context.gs));
++      asm volatile ("movw %%ss, %0" : "=m" (saved_context.ss));
++
++      /*
++       * control registers 
++       */
++      asm volatile ("movl %%cr0, %0" : "=r" (saved_context.cr0));
++      asm volatile ("movl %%cr2, %0" : "=r" (saved_context.cr2));
++      asm volatile ("movl %%cr3, %0" : "=r" (saved_context.cr3));
++      asm volatile ("movl %%cr4, %0" : "=r" (saved_context.cr4));
++}
++
++static void
++do_fpu_end(void)
++{
++        /* restore FPU regs if necessary */
++      /* Do it out of line so that gcc does not move cr0 load to some stupid place */
++        kernel_fpu_end();
++}
++
++void restore_processor_state(void)
++{
++
++      /*
++       * control registers
++       */
++      asm volatile ("movl %0, %%cr4" :: "r" (saved_context.cr4));
++      asm volatile ("movl %0, %%cr3" :: "r" (saved_context.cr3));
++      asm volatile ("movl %0, %%cr2" :: "r" (saved_context.cr2));
++      asm volatile ("movl %0, %%cr0" :: "r" (saved_context.cr0));
++
++      /*
++       * segment registers
++       */
++      asm volatile ("movw %0, %%es" :: "r" (saved_context.es));
++      asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs));
++      asm volatile ("movw %0, %%gs" :: "r" (saved_context.gs));
++      asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss));
++
++      /*
++       * now restore the descriptor tables to their proper values
++       * ltr is done i fix_processor_context().
++       */
++      asm volatile ("lgdt %0" :: "m" (saved_context.gdt_limit));
++      asm volatile ("lidt %0" :: "m" (saved_context.idt_limit));
++      asm volatile ("lldt %0" :: "m" (saved_context.ldt));
++
++      /*
++       * sysenter MSRs
++       */
++      if (boot_cpu_has(X86_FEATURE_SEP))
++              enable_sep_cpu(NULL);
++
++      fix_processor_context();
++      do_fpu_end();
++}
++
++static void fix_processor_context(void)
++{
++      int cpu = smp_processor_id();
++      struct tss_struct * t = init_tss + cpu;
++
++      set_tss_desc(cpu,t);    /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
++        cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
++
++      load_TR_desc();                         /* This does ltr */
++      load_LDT(&current->active_mm->context); /* This does lldt */
++
++      /*
++       * Now maybe reload the debug registers
++       */
++      if (current->thread.debugreg[7]){
++                loaddebug(&current->thread, 0);
++                loaddebug(&current->thread, 1);
++                loaddebug(&current->thread, 2);
++                loaddebug(&current->thread, 3);
++                /* no 4 and 5 */
++                loaddebug(&current->thread, 6);
++                loaddebug(&current->thread, 7);
++      }
++
++}
++
++EXPORT_SYMBOL(save_processor_state);
++EXPORT_SYMBOL(restore_processor_state);
+Index: linux-2.6.0-test5/arch/i386/power/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/Makefile    2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/Makefile 2003-09-27 11:38:19.220606408 +0800
+@@ -0,0 +1,3 @@
++obj-$(CONFIG_PM)              += cpu.o
++obj-$(CONFIG_PM_DISK)         += pmdisk.o
++obj-$(CONFIG_SOFTWARE_SUSPEND)        += swsusp.o
+Index: linux-2.6.0-test5/arch/i386/power/pmdisk.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/pmdisk.S    2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/pmdisk.S 2003-09-27 11:38:19.221606256 +0800
+@@ -0,0 +1,94 @@
++.text
++
++/* Originally gcc generated, modified by hand */
++
++#include <linux/linkage.h>
++#include <asm/segment.h>
++#include <asm/page.h>
++
++      .text
++
++ENTRY(pmdisk_arch_suspend)
++      pushl %ebx
++      cmpl $0,8(%esp)
++      jne .L1450
++      call save_processor_state
++
++      movl %esp, saved_context_esp
++      movl %eax, saved_context_eax
++      movl %ebx, saved_context_ebx
++      movl %ecx, saved_context_ecx
++      movl %edx, saved_context_edx
++      movl %ebp, saved_context_ebp
++      movl %esi, saved_context_esi
++      movl %edi, saved_context_edi
++      pushfl ; popl saved_context_eflags
++
++      call pmdisk_suspend
++      jmp .L1449
++      .p2align 4,,7
++.L1450:
++      movl $swapper_pg_dir-__PAGE_OFFSET,%ecx
++      movl %ecx,%cr3
++
++      movl $0,loop
++      cmpl $0,pmdisk_pages
++      je .L1453
++      .p2align 4,,7
++.L1455:
++      movl $0,loop2
++      .p2align 4,,7
++.L1459:
++      movl pm_pagedir_nosave,%ecx
++      movl loop,%eax
++      movl loop2,%edx
++      sall $4,%eax
++      movl 4(%ecx,%eax),%ebx
++      movl (%ecx,%eax),%eax
++      movb (%edx,%eax),%al
++      movb %al,(%edx,%ebx)
++      movl %cr3, %eax;              
++      movl %eax, %cr3;  # flush TLB 
++
++      movl loop2,%eax
++      leal 1(%eax),%edx
++      movl %edx,loop2
++      movl %edx,%eax
++      cmpl $4095,%eax
++      jbe .L1459
++      movl loop,%eax
++      leal 1(%eax),%edx
++      movl %edx,loop
++      movl %edx,%eax
++      cmpl pmdisk_pages,%eax
++      jb .L1455
++      .p2align 4,,7
++.L1453:
++      movl $__USER_DS,%eax
++
++      movw %ax, %ds
++      movw %ax, %es
++      movl saved_context_esp, %esp
++      movl saved_context_ebp, %ebp
++      movl saved_context_eax, %eax
++      movl saved_context_ebx, %ebx
++      movl saved_context_ecx, %ecx
++      movl saved_context_edx, %edx
++      movl saved_context_esi, %esi
++      movl saved_context_edi, %edi
++      pushl saved_context_eflags ; popfl
++      call pmdisk_resume
++.L1449:
++      popl    %ebx
++      pushl   %eax
++      call    restore_processor_state
++      popl    %eax
++      ret
++
++       .section .data.nosave
++loop:
++       .quad 0
++loop2:
++       .quad 0
++       .previous
++
+Index: linux-2.6.0-test5/arch/i386/power/swsusp.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/power/swsusp.S    2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/i386/power/swsusp.S 2003-09-27 11:38:19.221606256 +0800
+@@ -0,0 +1,94 @@
++.text
++
++/* Originally gcc generated, modified by hand */
++
++#include <linux/linkage.h>
++#include <asm/segment.h>
++#include <asm/page.h>
++
++      .text
++
++ENTRY(do_magic)
++      pushl %ebx
++      cmpl $0,8(%esp)
++      jne .L1450
++      call do_magic_suspend_1
++      call save_processor_state
++
++      movl %esp, saved_context_esp
++      movl %eax, saved_context_eax
++      movl %ebx, saved_context_ebx
++      movl %ecx, saved_context_ecx
++      movl %edx, saved_context_edx
++      movl %ebp, saved_context_ebp
++      movl %esi, saved_context_esi
++      movl %edi, saved_context_edi
++      pushfl ; popl saved_context_eflags
++
++      call do_magic_suspend_2
++      jmp .L1449
++      .p2align 4,,7
++.L1450:
++      movl $swapper_pg_dir-__PAGE_OFFSET,%ecx
++      movl %ecx,%cr3
++
++      call do_magic_resume_1
++      movl $0,loop
++      cmpl $0,nr_copy_pages
++      je .L1453
++      .p2align 4,,7
++.L1455:
++      movl $0,loop2
++      .p2align 4,,7
++.L1459:
++      movl pagedir_nosave,%ecx
++      movl loop,%eax
++      movl loop2,%edx
++      sall $4,%eax
++      movl 4(%ecx,%eax),%ebx
++      movl (%ecx,%eax),%eax
++      movb (%edx,%eax),%al
++      movb %al,(%edx,%ebx)
++      movl %cr3, %eax;              
++      movl %eax, %cr3;  # flush TLB 
++
++      movl loop2,%eax
++      leal 1(%eax),%edx
++      movl %edx,loop2
++      movl %edx,%eax
++      cmpl $4095,%eax
++      jbe .L1459
++      movl loop,%eax
++      leal 1(%eax),%edx
++      movl %edx,loop
++      movl %edx,%eax
++      cmpl nr_copy_pages,%eax
++      jb .L1455
++      .p2align 4,,7
++.L1453:
++      movl $__USER_DS,%eax
++
++      movw %ax, %ds
++      movw %ax, %es
++      movl saved_context_esp, %esp
++      movl saved_context_ebp, %ebp
++      movl saved_context_eax, %eax
++      movl saved_context_ebx, %ebx
++      movl saved_context_ecx, %ecx
++      movl saved_context_edx, %edx
++      movl saved_context_esi, %esi
++      movl saved_context_edi, %edi
++      call restore_processor_state
++      pushl saved_context_eflags ; popfl
++      call do_magic_resume_2
++.L1449:
++      popl %ebx
++      ret
++
++       .section .data.nosave
++loop:
++       .quad 0
++loop2:
++       .quad 0
++       .previous
++      
+\ No newline at end of file
+Index: linux-2.6.0-test5/arch/ia64/hp/common/sba_iommu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/hp/common/sba_iommu.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/hp/common/sba_iommu.c  2003-09-27 11:38:19.242603064 +0800
+@@ -54,6 +54,11 @@
+ */
+ #define ALLOW_IOV_BYPASS
++#ifdef CONFIG_PROC_FS
++  /* turn it off for now; without per-CPU counters, it's too much of a scalability bottleneck: */
++# define SBA_PROC_FS 0
++#endif
++
+ /*
+ ** If a device prefetches beyond the end of a valid pdir entry, it will cause
+ ** a hard failure, ie. MCA.  Version 3.0 and later of the zx1 LBA should
+@@ -193,7 +198,7 @@
+       } saved[DELAYED_RESOURCE_CNT];
+ #endif
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ #define SBA_SEARCH_SAMPLE     0x100
+       unsigned long avg_search[SBA_SEARCH_SAMPLE];
+       unsigned long avg_idx;  /* current index into avg_search */
+@@ -227,12 +232,7 @@
+ static struct ioc *ioc_list;
+ static int reserve_sba_gart = 1;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ #define sba_sg_address(sg)    (page_address((sg)->page) + (sg)->offset)
+-#else
+-#define sba_sg_address(sg)    ((sg)->address ? (sg)->address : \
+-                                  page_address((sg)->page) + (sg)->offset)
+-#endif
+ #ifdef FULL_VALID_PDIR
+ static u64 prefetch_spill_page;
+@@ -522,7 +522,7 @@
+ sba_alloc_range(struct ioc *ioc, size_t size)
+ {
+       unsigned int pages_needed = size >> IOVP_SHIFT;
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       unsigned long itc_start = ia64_get_itc();
+ #endif
+       unsigned long pide;
+@@ -556,7 +556,7 @@
+               (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
+               ioc->res_bitshift );
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       {
+               unsigned long itc_end = ia64_get_itc();
+               unsigned long tmp = itc_end - itc_start;
+@@ -598,7 +598,7 @@
+               __FUNCTION__, (uint) iova, size,
+               bits_not_wanted, m, pide, res_ptr, *res_ptr);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       ioc->used_pages -= bits_not_wanted;
+ #endif
+@@ -790,7 +790,7 @@
+               ** Device is bit capable of DMA'ing to the buffer...
+               ** just return the PCI address of ptr
+               */
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+               spin_lock_irqsave(&ioc->res_lock, flags);
+               ioc->msingle_bypass++;
+               spin_unlock_irqrestore(&ioc->res_lock, flags);
+@@ -816,7 +816,7 @@
+               panic("Sanity check failed");
+ #endif
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       ioc->msingle_calls++;
+       ioc->msingle_pages += size >> IOVP_SHIFT;
+ #endif
+@@ -875,7 +875,7 @@
+               /*
+               ** Address does not fall w/in IOVA, must be bypassing
+               */
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+               spin_lock_irqsave(&ioc->res_lock, flags);
+               ioc->usingle_bypass++;
+               spin_unlock_irqrestore(&ioc->res_lock, flags);
+@@ -900,7 +900,7 @@
+       size = ROUNDUP(size, IOVP_SIZE);
+       spin_lock_irqsave(&ioc->res_lock, flags);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       ioc->usingle_calls++;
+       ioc->usingle_pages += size >> IOVP_SHIFT;
+ #endif
+@@ -962,20 +962,20 @@
+ /**
+- * sba_alloc_consistent - allocate/map shared mem for DMA
+- * @hwdev: instance of PCI owned by the driver that's asking.
++ * sba_alloc_coherent - allocate/map shared mem for DMA
++ * @dev: instance of PCI owned by the driver that's asking.
+  * @size:  number of bytes mapped in driver buffer.
+  * @dma_handle:  IOVA of new buffer.
+  *
+  * See Documentation/DMA-mapping.txt
+  */
+ void *
+-sba_alloc_coherent (struct device *hwdev, size_t size, dma_addr_t *dma_handle, int flags)
++sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+ {
+       struct ioc *ioc;
+       void *addr;
+-        addr = (void *) __get_free_pages(flags, get_order(size));
++      addr = (void *) __get_free_pages(flags, get_order(size));
+       if (!addr)
+               return NULL;
+@@ -983,7 +983,7 @@
+        * REVISIT: if sba_map_single starts needing more than dma_mask from the
+        * device, this needs to be updated.
+        */
+-      ioc = GET_IOC(hwdev);
++      ioc = GET_IOC(dev);
+       ASSERT(ioc);
+       *dma_handle = sba_map_single(&ioc->sac_only_dev->dev, addr, size, 0);
+@@ -993,17 +993,17 @@
+ /**
+- * sba_free_consistent - free/unmap shared mem for DMA
+- * @hwdev: instance of PCI owned by the driver that's asking.
++ * sba_free_coherent - free/unmap shared mem for DMA
++ * @dev: instance of PCI owned by the driver that's asking.
+  * @size:  number of bytes mapped in driver buffer.
+  * @vaddr:  virtual address IOVA of "consistent" buffer.
+  * @dma_handler:  IO virtual address of "consistent" buffer.
+  *
+  * See Documentation/DMA-mapping.txt
+  */
+-void sba_free_coherent (struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
++void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+ {
+-      sba_unmap_single(hwdev, dma_handle, size, 0);
++      sba_unmap_single(dev, dma_handle, size, 0);
+       free_pages((unsigned long) vaddr, get_order(size));
+ }
+@@ -1083,7 +1083,7 @@
+                       cnt += dma_offset;
+                       dma_offset=0;   /* only want offset on first chunk */
+                       cnt = ROUNDUP(cnt, IOVP_SIZE);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+                       ioc->msg_pages += cnt >> IOVP_SHIFT;
+ #endif
+                       do {
+@@ -1273,7 +1273,7 @@
+                       sg->dma_length = sg->length;
+                       sg->dma_address = virt_to_phys(sba_sg_address(sg));
+               }
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+               spin_lock_irqsave(&ioc->res_lock, flags);
+               ioc->msg_bypass++;
+               spin_unlock_irqrestore(&ioc->res_lock, flags);
+@@ -1286,7 +1286,7 @@
+               sglist->dma_length = sglist->length;
+               sglist->dma_address = sba_map_single(dev, sba_sg_address(sglist), sglist->length,
+                                                    dir);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+               /*
+               ** Should probably do some stats counting, but trying to
+               ** be precise quickly starts wasting CPU time.
+@@ -1305,7 +1305,7 @@
+       }
+ #endif
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       ioc->msg_calls++;
+ #endif
+@@ -1368,7 +1368,7 @@
+       ioc = GET_IOC(dev);
+       ASSERT(ioc);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       ioc->usg_calls++;
+ #endif
+@@ -1381,7 +1381,7 @@
+       while (nents && sglist->dma_length) {
+               sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir);
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+               /*
+               ** This leaves inconsistent data in the stats, but we can't
+               ** tell which sg lists were mapped by map_single and which
+@@ -1709,7 +1709,7 @@
+ **
+ **************************************************************************/
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+ static void *
+ ioc_start(struct seq_file *s, loff_t *pos)
+ {
+@@ -1763,7 +1763,7 @@
+               if (ioc->avg_search[i] > max) max = ioc->avg_search[i];
+               if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
+       }
+-      avg /= SBA_SEARCH_SAMPLE;
++      avg /= SBA_SEARCH_SAMPLE;
+       seq_printf(s, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", min, avg, max);
+       seq_printf(s, "pci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
+@@ -1864,7 +1864,7 @@
+ }
+ #endif
+-void
++static void
+ sba_connect_bus(struct pci_bus *bus)
+ {
+       acpi_handle handle, parent;
+@@ -1872,7 +1872,7 @@
+       struct ioc *ioc;
+       if (!PCI_CONTROLLER(bus))
+-              panic(PFX "no sysdata on bus %d!\n",bus->number);
++              panic(PFX "no sysdata on bus %d!\n", bus->number);
+       if (PCI_CONTROLLER(bus)->iommu)
+               return;
+@@ -1955,7 +1955,7 @@
+       }
+ #endif
+-#ifdef CONFIG_PROC_FS
++#if SBA_PROC_FS
+       ioc_proc_init();
+ #endif
+       return 0;
+Index: linux-2.6.0-test5/arch/ia64/hp/sim/boot/boot_head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/hp/sim/boot/boot_head.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/hp/sim/boot/boot_head.S        2003-09-27 11:38:19.244602760 +0800
+@@ -27,6 +27,14 @@
+       br.call.sptk.many rp=start_bootloader
+ END(_start)
++/*
++ * Set a break point on this function so that symbols are available to set breakpoints in
++ * the kernel being debugged.
++ */
++GLOBAL_ENTRY(debug_break)
++      br.ret.sptk.many b0
++END(debug_break)
++
+ GLOBAL_ENTRY(ssc)
+       .regstk 5,0,0,0
+       mov r15=in4
+Index: linux-2.6.0-test5/arch/ia64/hp/sim/boot/bootloader.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/hp/sim/boot/bootloader.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/hp/sim/boot/bootloader.c       2003-09-27 11:38:19.245602608 +0800
+@@ -37,15 +37,7 @@
+ extern void jmp_to_kernel (unsigned long bp, unsigned long e_entry);
+ extern struct ia64_boot_param *sys_fw_init (const char *args, int arglen);
+-
+-/*
+- * Set a break point on this function so that symbols are available to set breakpoints in
+- * the kernel being debugged.
+- */
+-static void
+-debug_break (void)
+-{
+-}
++extern void debug_break (void);
+ static void
+ cons_write (const char *buf)
+Index: linux-2.6.0-test5/arch/ia64/ia32/elfcore32.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/ia32/elfcore32.h  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/ia32/elfcore32.h       2003-09-27 11:38:19.247602304 +0800
+@@ -8,6 +8,8 @@
+ #ifndef _ELFCORE32_H_
+ #define _ELFCORE32_H_
++#include <asm/intrinsics.h>
++
+ #define USE_ELF_CORE_DUMP 1
+ /* Override elfcore.h */
+@@ -79,8 +81,7 @@
+       pr_reg[11] = regs->r1;                          \
+       pr_reg[12] = regs->cr_iip;                      \
+       pr_reg[13] = regs->r17 & 0xffff;                \
+-      asm volatile ("mov %0=ar.eflag ;;"              \
+-                    : "=r"(pr_reg[14]));              \
++      pr_reg[14] = ia64_getreg(_IA64_REG_AR_EFLAG);   \
+       pr_reg[15] = regs->r12;                         \
+       pr_reg[16] = (regs->r17 >> 16) & 0xffff;
+Index: linux-2.6.0-test5/arch/ia64/ia32/ia32priv.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/ia32/ia32priv.h   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/ia32/ia32priv.h        2003-09-27 11:38:19.251601696 +0800
+@@ -168,15 +168,15 @@
+ };
+ struct stat64 {
+-      unsigned short  st_dev;
+-      unsigned char   __pad0[10];
++      unsigned long long      st_dev;
++      unsigned char   __pad0[4];
+       unsigned int    __st_ino;
+       unsigned int    st_mode;
+       unsigned int    st_nlink;
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+-      unsigned short  st_rdev;
+-      unsigned char   __pad3[10];
++      unsigned long long      st_rdev;
++      unsigned char   __pad3[4];
+       unsigned int    st_size_lo;
+       unsigned int    st_size_hi;
+       unsigned int    st_blksize;
+Index: linux-2.6.0-test5/arch/ia64/ia32/sys_ia32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/ia32/sys_ia32.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/ia32/sys_ia32.c        2003-09-27 11:38:19.289595920 +0800
+@@ -76,6 +76,7 @@
+ #define OFFSET4K(a)           ((a) & 0xfff)
+ #define PAGE_START(addr)      ((addr) & PAGE_MASK)
++#define MINSIGSTKSZ_IA32      2048
+ #define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
+ #define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
+@@ -179,19 +180,21 @@
+ {
+       int err;
+-      if ((u64) stat->size > MAX_NON_LFS)
++      if ((u64) stat->size > MAX_NON_LFS ||
++          !old_valid_dev(stat->dev) ||
++          !old_valid_dev(stat->rdev))
+               return -EOVERFLOW;
+       if (clear_user(ubuf, sizeof(*ubuf)))
+               return -EFAULT;
+-      err  = __put_user(stat->dev, &ubuf->st_dev);
++      err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
+       err |= __put_user(stat->ino, &ubuf->st_ino);
+       err |= __put_user(stat->mode, &ubuf->st_mode);
+       err |= __put_user(stat->nlink, &ubuf->st_nlink);
+       err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
+       err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
+-      err |= __put_user(stat->rdev, &ubuf->st_rdev);
++      err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
+       err |= __put_user(stat->size, &ubuf->st_size);
+       err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
+       err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
+@@ -2262,10 +2265,18 @@
+                       return -EFAULT;
+       uss.ss_sp = (void *) (long) buf32.ss_sp;
+       uss.ss_flags = buf32.ss_flags;
+-      uss.ss_size = buf32.ss_size;
++      /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the 
++           check and set it to the user requested value later */
++      if (buf32.ss_size < MINSIGSTKSZ_IA32) {
++              ret = -ENOMEM;
++              goto out;
++      }
++      uss.ss_size = MINSIGSTKSZ;
+       set_fs(KERNEL_DS);
+       ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12);
++      current->sas_ss_size = buf32.ss_size;   
+       set_fs(old_fs);
++out:
+       if (ret < 0)
+               return(ret);
+       if (uoss32) {
+@@ -2479,7 +2490,7 @@
+       if (clear_user(ubuf, sizeof(*ubuf)))
+               return -EFAULT;
+-      err  = __put_user(kbuf->dev, &ubuf->st_dev);
++      err  = __put_user(huge_encode_dev(kbuf->dev), &ubuf->st_dev);
+       err |= __put_user(kbuf->ino, &ubuf->__st_ino);
+       err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
+       err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
+@@ -2487,7 +2498,7 @@
+       err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
+       err |= __put_user(kbuf->uid, &ubuf->st_uid);
+       err |= __put_user(kbuf->gid, &ubuf->st_gid);
+-      err |= __put_user(kbuf->rdev, &ubuf->st_rdev);
++      err |= __put_user(huge_encode_dev(kbuf->rdev), &ubuf->st_rdev);
+       err |= __put_user(kbuf->size, &ubuf->st_size_lo);
+       err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
+       err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
+Index: linux-2.6.0-test5/arch/ia64/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/Kconfig   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/Kconfig        2003-09-27 11:38:19.295595008 +0800
+@@ -267,7 +267,7 @@
+         unsure, answer Y.
+ config PM
+-      bool
++      bool "Power Management support"
+       depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+       default y
+       ---help---
+@@ -304,9 +304,6 @@
+       int
+       default "18"
+-config HUGETLB_PAGE
+-      bool "IA-64 Huge TLB Page Support"
+-
+ choice
+       prompt "IA-64 Huge TLB Page Size"
+       depends on HUGETLB_PAGE
+@@ -413,6 +410,16 @@
+         To use this option, you have to ensure that the "/proc file system
+         support" (CONFIG_PROC_FS) is enabled, too.
++config IA64_SALINFO
++      tristate "/proc/sal support"
++      help
++        The /proc/sal directory exports the SAL (system abstraction layer)
++        feature bits, like whether the platform is subject to ITC drift.  It
++        is intended to be used by user programs that care about such things.
++
++        To use this option, you have to ensure that the "/proc file system
++        support" (CONFIG_PROC_FS) is enabled, too.
++
+ config EFI_VARS
+       tristate "/proc/efi/vars support"
+       help
+@@ -424,9 +431,15 @@
+         support" (CONFIG_PROC_FS) is enabled, too.
+ config NR_CPUS
+-      int "Maximum number of CPUs (2-64)"
++      int "Maximum number of CPUs"
+       depends on SMP
+       default "64"
++      help
++        You should set this to the number of CPUs in your system, but
++        keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but
++        only use 2 CPUs on a >2 CPU system.  Setting this to a value larger
++        than 64 will cause the use of a CPU mask array, causing a small
++        performance hit.
+ source "fs/Kconfig.binfmt"
+@@ -569,6 +582,7 @@
+ source "arch/ia64/hp/sim/Kconfig"
++source "arch/ia64/oprofile/Kconfig"
+ menu "Kernel hacking"
+Index: linux-2.6.0-test5/arch/ia64/kernel/acpi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/acpi.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/acpi.c  2003-09-27 11:38:19.310592728 +0800
+@@ -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 @@
+ 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)
+@@ -331,7 +332,7 @@
+ #ifdef CONFIG_ACPI_NUMA
+-#define SLIT_DEBUG
++#undef SLIT_DEBUG
+ #define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
+@@ -341,7 +342,7 @@
+ #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;
+ /*
+@@ -603,11 +604,13 @@
+               printk(KERN_ERR PREFIX "Can't find FADT\n");
+ #ifdef CONFIG_SMP
+-      smp_boot_data.cpu_count = available_cpus;
+       if (available_cpus == 0) {
+               printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
++              printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
++              smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id();
+               available_cpus = 1; /* We've got at least one of these, no? */
+       }
++      smp_boot_data.cpu_count = available_cpus;
+       smp_build_cpu_map();
+ # ifdef CONFIG_NUMA
+Index: linux-2.6.0-test5/arch/ia64/kernel/efi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/efi.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/efi.c   2003-09-27 11:38:19.328589992 +0800
+@@ -324,7 +324,7 @@
+                               check_md = q;
+                               if (check_md->attribute & EFI_MEMORY_WB)
+-                                      trim_bottom(md, granule_addr);
++                                      trim_bottom(check_md, granule_addr);
+                               if (check_md->phys_addr < granule_addr)
+                                       continue;
+@@ -446,10 +446,12 @@
+                       panic("Woah!  PAL code size bigger than a granule!");
+               mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
++#if EFI_DEBUG
+               printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
+                      smp_processor_id(), md->phys_addr,
+                      md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
+                      vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
++#endif
+               /*
+                * Cannot write to CRx with PSR.ic=1
+Index: linux-2.6.0-test5/arch/ia64/kernel/entry.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/entry.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/entry.S 2003-09-27 11:38:19.345587408 +0800
+@@ -1448,7 +1448,7 @@
+       data8 sys_sched_setaffinity
+       data8 sys_sched_getaffinity
+       data8 sys_set_tid_address
+-      data8 sys_fadvise64
++      data8 sys_fadvise64_64
+       data8 sys_tgkill                        // 1235
+       data8 sys_exit_group
+       data8 sys_lookup_dcookie
+@@ -1473,7 +1473,7 @@
+       data8 sys_clock_nanosleep
+       data8 sys_fstatfs64
+       data8 sys_statfs64
+-      data8 sys_fadvise64_64
++      data8 ia64_ni_syscall
+       data8 ia64_ni_syscall                   // 1260
+       data8 ia64_ni_syscall
+       data8 ia64_ni_syscall
+Index: linux-2.6.0-test5/arch/ia64/kernel/fsys.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/fsys.S     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/fsys.S  2003-09-27 11:38:19.351586496 +0800
+@@ -655,7 +655,7 @@
+       data8 0                         // sched_setaffinity
+       data8 0                         // sched_getaffinity
+       data8 fsys_set_tid_address      // set_tid_address
+-      data8 0                         // fadvise64
++      data8 0                         // fadvise64_64
+       data8 0                         // tgkill               // 1235
+       data8 0                         // exit_group
+       data8 0                         // lookup_dcookie
+@@ -680,7 +680,7 @@
+       data8 0                         // clock_nanosleep
+       data8 0                         // fstatfs64
+       data8 0                         // statfs64
+-      data8 0                         // fadvise64_64
++      data8 0
+       data8 0                                                 // 1260
+       data8 0
+       data8 0
+Index: linux-2.6.0-test5/arch/ia64/kernel/init_task.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/init_task.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/init_task.c     2003-09-27 11:38:19.352586344 +0800
+@@ -28,15 +28,13 @@
+  */
+ #define init_thread_info      init_task_mem.s.thread_info
+-static union {
++union {
+       struct {
+               struct task_struct task;
+               struct thread_info thread_info;
+       } s;
+       unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
+-} init_task_mem asm ("init_task_mem") __attribute__((section(".data.init_task"))) = {{
++} init_task_mem asm ("init_task") __attribute__((section(".data.init_task"))) = {{
+       .task =         INIT_TASK(init_task_mem.s.task),
+       .thread_info =  INIT_THREAD_INFO(init_task_mem.s.task)
+ }};
+-
+-extern struct task_struct init_task __attribute__ ((alias("init_task_mem")));
+Index: linux-2.6.0-test5/arch/ia64/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/Makefile   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/Makefile        2003-09-27 11:38:19.353586192 +0800
+@@ -14,6 +14,7 @@
+ obj-$(CONFIG_IA64_HP_ZX1)     += acpi-ext.o
+ obj-$(CONFIG_IA64_MCA)                += mca.o mca_asm.o
+ obj-$(CONFIG_IA64_PALINFO)    += palinfo.o
++obj-$(CONFIG_IA64_SALINFO)    += salinfo.o
+ obj-$(CONFIG_IOSAPIC)         += iosapic.o
+ obj-$(CONFIG_MODULES)         += module.o
+ obj-$(CONFIG_SMP)             += smp.o smpboot.o
+Index: linux-2.6.0-test5/arch/ia64/kernel/mca.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/mca.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/mca.c   2003-09-27 11:38:19.380582088 +0800
+@@ -1193,7 +1193,7 @@
+ ia64_mca_cmc_poll (unsigned long dummy)
+ {
+       /* Trigger a CMC interrupt cascade  */
+-      platform_send_ipi(__ffs(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
++      platform_send_ipi(first_cpu(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
+ }
+ /*
+@@ -1260,7 +1260,7 @@
+ ia64_mca_cpe_poll (unsigned long dummy)
+ {
+       /* Trigger a CPE interrupt cascade  */
+-      platform_send_ipi(__ffs(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
++      platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
+ }
+ /*
+Index: linux-2.6.0-test5/arch/ia64/kernel/perfmon.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/perfmon.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/perfmon.c       2003-09-27 11:38:19.436573576 +0800
+@@ -58,23 +58,8 @@
+ #define PFM_CTX_ZOMBIE                4       /* owner of the context is closing it */
+ #define PFM_CTX_TERMINATED    5       /* the task the context was loaded onto is gone */
+-#define CTX_LOADED(c)        (c)->ctx_state = PFM_CTX_LOADED
+-#define CTX_UNLOADED(c)      (c)->ctx_state = PFM_CTX_UNLOADED
+-#define CTX_ZOMBIE(c)        (c)->ctx_state = PFM_CTX_ZOMBIE
+-#define CTX_DESTROYED(c)     (c)->ctx_state = PFM_CTX_DESTROYED
+-#define CTX_MASKED(c)        (c)->ctx_state = PFM_CTX_MASKED
+-#define CTX_TERMINATED(c)    (c)->ctx_state = PFM_CTX_TERMINATED
+-
+-#define CTX_IS_UNLOADED(c)   ((c)->ctx_state == PFM_CTX_UNLOADED)
+-#define CTX_IS_LOADED(c)     ((c)->ctx_state == PFM_CTX_LOADED)
+-#define CTX_IS_ZOMBIE(c)     ((c)->ctx_state == PFM_CTX_ZOMBIE)
+-#define CTX_IS_MASKED(c)     ((c)->ctx_state == PFM_CTX_MASKED)
+-#define CTX_IS_TERMINATED(c) ((c)->ctx_state == PFM_CTX_TERMINATED)
+-#define CTX_IS_DEAD(c)             ((c)->ctx_state == PFM_CTX_TERMINATED || (c)->ctx_state == PFM_CTX_ZOMBIE)
+-
+ #define PFM_INVALID_ACTIVATION        (~0UL)
+-
+ /*
+  * depth of message queue
+  */
+@@ -155,7 +140,7 @@
+  * in UP:
+  *    - we need to protect against PMU overflow interrupts (local_irq_disable)
+  *
+- * spin_lock_irqsave()/spin_lock_irqrestore():
++ * spin_lock_irqsave()/spin_unlock_irqrestore():
+  *    in SMP: local_irq_disable + spin_lock
+  *    in UP : local_irq_disable
+  *
+@@ -649,6 +634,7 @@
+ DEFINE_PER_CPU(pfm_context_t  *, pmu_ctx);
+ DEFINE_PER_CPU(unsigned long, pmu_activation_number);
++
+ /* forward declaration */
+ static struct file_operations pfm_file_ops;
+@@ -659,7 +645,13 @@
+ static void pfm_lazy_save_regs (struct task_struct *ta);
+ #endif
+-#if   defined(CONFIG_ITANIUM)
++/*
++ * the HP simulator must be first because
++ * CONFIG_IA64_HP_SIM is independent of CONFIG_MCKINLEY or CONFIG_ITANIUM
++ */
++#if defined(CONFIG_IA64_HP_SIM)
++#include "perfmon_hpsim.h"
++#elif   defined(CONFIG_ITANIUM)
+ #include "perfmon_itanium.h"
+ #elif defined(CONFIG_MCKINLEY)
+ #include "perfmon_mckinley.h"
+@@ -953,13 +945,15 @@
+       struct thread_struct *th = &task->thread;
+       unsigned long mask;
+       unsigned long psr, val;
+-      int i;
++      int i, is_system;
++
++      is_system = ctx->ctx_fl_system;
+       if (task != current) {
+               printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
+               return;
+       }
+-      if (CTX_IS_MASKED(ctx) == 0) {
++      if (ctx->ctx_state != PFM_CTX_MASKED) {
+               printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
+                       task->pid, current->pid, ctx->ctx_state);
+               return;
+@@ -975,7 +969,7 @@
+        *
+        * system-wide session are pinned and self-monitoring
+        */
+-      if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
++      if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+               /* disable dcr pp */
+               ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
+               pfm_clear_psr_pp();
+@@ -1022,7 +1016,7 @@
+       /*
+        * now restore PSR
+        */
+-      if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
++      if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+               /* enable dcr pp */
+               ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
+               ia64_srlz_i();
+@@ -1825,6 +1819,7 @@
+       void *smpl_buf_vaddr = NULL;
+       void *smpl_buf_addr = NULL;
+       int free_possible = 1;
++      int state, is_system;
+       { u64 psr = pfm_get_psr();
+         BUG_ON((psr & IA64_PSR_I) == 0UL);
+@@ -1850,6 +1845,11 @@
+       PROTECT_CTX(ctx, flags);
++      state     = ctx->ctx_state;
++      is_system = ctx->ctx_fl_system;
++
++      task = PFM_CTX_TASK(ctx);
++
+       /*
+        * remove our file from the async queue, if we use it
+        */
+@@ -1859,11 +1859,10 @@
+               DPRINT(("[%d] after async_queue=%p\n", current->pid, ctx->ctx_async_queue));
+       }
+-      task = PFM_CTX_TASK(ctx);
+-      DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
++      DPRINT(("[%d] ctx_state=%d\n", current->pid, state));
+-      if (CTX_IS_UNLOADED(ctx) || CTX_IS_TERMINATED(ctx)) {
++      if (state == PFM_CTX_UNLOADED || state == PFM_CTX_TERMINATED) {
+               goto doit;
+       }
+@@ -1884,7 +1883,7 @@
+                *
+                * We need to release the resource on the ORIGINAL cpu.
+                */
+-              if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++              if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+                       DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+@@ -1900,9 +1899,10 @@
+                       task->thread.pfm_context = NULL;
+                       ctx->ctx_task            = NULL;
+-                      CTX_UNLOADED(ctx);
++                      ctx->ctx_state = state = PFM_CTX_UNLOADED;
+                       pfm_unreserve_session(ctx, 1 , ctx->ctx_cpu);
++
+               } else
+ #endif /* CONFIG_SMP */
+               {
+@@ -1914,19 +1914,20 @@
+                       */
+                       pfm_context_unload(ctx, NULL, 0, regs);
+-                      CTX_TERMINATED(ctx);
++                      ctx->ctx_state = PFM_CTX_TERMINATED;
+-                      DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
++                      DPRINT(("[%d] ctx_state=%d\n", current->pid, state));
+               }
+               goto doit;
+       }
++
+       /*
+        * The task is currently blocked or will block after an overflow.
+        * we must force it to wakeup to get out of the
+        * MASKED state and transition to the unloaded state by itself
+        */
+-      if (CTX_IS_MASKED(ctx) && CTX_OVFL_NOBLOCK(ctx) == 0) {
++      if (state == PFM_CTX_MASKED && CTX_OVFL_NOBLOCK(ctx) == 0) {
+               /*
+                * set a "partial" zombie state to be checked
+@@ -1949,7 +1950,7 @@
+                */
+               up(&ctx->ctx_restart_sem);
+-              DPRINT(("waking up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
++              DPRINT(("waking up ctx_state=%d for [%d]\n", state, current->pid));
+               /*
+                * put ourself to sleep waiting for the other
+@@ -1971,24 +1972,24 @@
+                */
+                       schedule();
+-              DPRINT(("woken up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
+               PROTECT_CTX(ctx, flags);
++
+               remove_wait_queue(&ctx->ctx_zombieq, &wait);
+               set_current_state(TASK_RUNNING);
+               /*
+                * context is terminated at this point
+                */
+-              DPRINT(("after zombie wakeup ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
++              DPRINT(("after zombie wakeup ctx_state=%d for [%d]\n", state, current->pid));
+       }
+       else {
+ #ifdef CONFIG_SMP
+               /*
+                * switch context to zombie state
+                */
+-              CTX_ZOMBIE(ctx);
++              ctx->ctx_state = PFM_CTX_ZOMBIE;
+               DPRINT(("zombie ctx for [%d]\n", task->pid));
+               /*
+@@ -2002,6 +2003,10 @@
+       }
+ doit: /* cannot assume task is defined from now on */
++
++      /* reload state, may have changed during  opening of critical section */
++      state = ctx->ctx_state;
++
+       /*
+        * the context is still attached to a task (possibly current)
+        * we cannot destroy it right now
+@@ -2032,10 +2037,9 @@
+               ctx->ctx_smpl_hdr = NULL;
+       }
+-
+       DPRINT(("[%d] ctx_state=%d free_possible=%d vaddr=%p addr=%p size=%lu\n",
+               current->pid,
+-              ctx->ctx_state,
++              state,
+               free_possible,
+               smpl_buf_vaddr,
+               smpl_buf_addr,
+@@ -2047,7 +2051,7 @@
+        * UNLOADED and TERMINATED mean that the session has already been
+        * unreserved.
+        */
+-      if (CTX_IS_ZOMBIE(ctx)) {
++      if (state == PFM_CTX_ZOMBIE) {
+               pfm_unreserve_session(ctx, ctx->ctx_fl_system , ctx->ctx_cpu);
+       }
+@@ -2360,10 +2364,23 @@
+ static int
+ pfm_bad_permissions(struct task_struct *task)
+ {
+-      /* stolen from bad_signal() */
+-      return (current->session != task->session)
+-          && (current->euid ^ task->suid) && (current->euid ^ task->uid)
+-          && (current->uid ^ task->suid) && (current->uid ^ task->uid);
++      /* inspired by ptrace_attach() */
++      DPRINT(("[%d] cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
++              current->pid,
++              current->uid,
++              current->gid,
++              task->euid,
++              task->suid,
++              task->uid,
++              task->egid,
++              task->sgid));
++
++      return ((current->uid != task->euid)
++          || (current->uid != task->suid)
++          || (current->uid != task->uid)
++          || (current->gid != task->egid)
++          || (current->gid != task->sgid)
++          || (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE);
+ }
+ static int
+@@ -2655,7 +2672,7 @@
+       /*
+        * context is unloaded
+        */
+-      CTX_UNLOADED(ctx);
++      ctx->ctx_state = PFM_CTX_UNLOADED;
+       /*
+        * initialization of context's flags
+@@ -2787,7 +2804,7 @@
+       if (flag == PFM_PMD_NO_RESET) return;
+-      if (CTX_IS_MASKED(ctx)) {
++      if (ctx->ctx_state == PFM_CTX_MASKED) {
+               pfm_reset_regs_masked(ctx, ovfl_regs, flag);
+               return;
+       }
+@@ -2836,27 +2853,30 @@
+       unsigned long value;
+       unsigned long smpl_pmds, reset_pmds;
+       unsigned int cnum, reg_flags, flags;
+-      int i, can_access_pmu = 0, is_loaded;
+-      int is_monitor, is_counting;
++      int i, can_access_pmu = 0, is_loaded, is_system;
++      int is_monitor, is_counting, state;
+       int ret = -EINVAL;
+ #define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
+-      if (CTX_IS_DEAD(ctx)) return -EINVAL;
++      state     = ctx->ctx_state;
++      is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++      is_system = ctx->ctx_fl_system;
++
++      if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
+-      is_loaded = CTX_IS_LOADED(ctx);
+       if (is_loaded) {
+               thread = &ctx->ctx_task->thread;
+-              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+               /*
+                * In system wide and when the context is loaded, access can only happen
+                * when the caller is running on the CPU being monitored by the session.
+                * It does not have to be the owner (ctx_task) of the context per se.
+                */
+-              if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++              if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+                       DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+                       return -EBUSY;
+               }
++              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
+       }
+       for (i = 0; i < count; i++, req++) {
+@@ -2885,7 +2905,7 @@
+                *      - system-wide session: PMCx.pm=1 (privileged monitor)
+                *      - per-task           : PMCx.pm=0 (user monitor)
+                */
+-              if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
++              if ((is_monitor || is_counting) && value != PMC_DFL_VAL(cnum) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
+                       DPRINT(("pmc%u pmc_pm=%ld fl_system=%d\n",
+                               cnum,
+                               PMC_PM(cnum, value),
+@@ -2893,7 +2913,6 @@
+                       goto error;
+               }
+-
+               if (is_counting) {
+                       pfm_monitor_t *p = (pfm_monitor_t *)&value;
+                       /*
+@@ -2975,7 +2994,7 @@
+                        * make sure we do not try to reset on
+                        * restart because we have established new values
+                        */
+-                      if (CTX_IS_MASKED(ctx)) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
++                      if (state == PFM_CTX_MASKED) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
+               }
+               /*
+                * Needed in case the user does not initialize the equivalent
+@@ -3007,7 +3026,7 @@
+                       /*
+                        * write thread state
+                        */
+-                      if (ctx->ctx_fl_system == 0) thread->pmcs[cnum] = value;
++                      if (is_system == 0) thread->pmcs[cnum] = value;
+                       /*
+                        * write hardware register if we can
+@@ -3067,13 +3086,16 @@
+       pfarg_reg_t *req = (pfarg_reg_t *)arg;
+       unsigned long value, hw_value;
+       unsigned int cnum;
+-      int i, can_access_pmu = 0;
+-      int is_counting, is_loaded;
++      int i, can_access_pmu = 0, state;
++      int is_counting, is_loaded, is_system;
+       int ret = -EINVAL;
+-      if (CTX_IS_DEAD(ctx)) return -EINVAL;
+-      is_loaded = CTX_IS_LOADED(ctx);
++      state     = ctx->ctx_state;
++      is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++      is_system = ctx->ctx_fl_system;
++
++      if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
+       /*
+        * on both UP and SMP, we can only write to the PMC when the task is
+@@ -3081,16 +3103,16 @@
+        */
+       if (is_loaded) {
+               thread = &ctx->ctx_task->thread;
+-              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+               /*
+                * In system wide and when the context is loaded, access can only happen
+                * when the caller is running on the CPU being monitored by the session.
+                * It does not have to be the owner (ctx_task) of the context per se.
+                */
+-              if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++              if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+                       DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+                       return -EBUSY;
+               }
++              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
+       }
+       for (i = 0; i < count; i++, req++) {
+@@ -3179,7 +3201,7 @@
+                * make sure we do not try to reset on
+                * restart because we have established new values
+                */
+-              if (is_counting && CTX_IS_MASKED(ctx)) {
++              if (is_counting && state == PFM_CTX_MASKED) {
+                       ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
+               }
+@@ -3187,7 +3209,7 @@
+                       /*
+                        * write thread state
+                        */
+-                      if (ctx->ctx_fl_system == 0) thread->pmds[cnum] = hw_value;
++                      if (is_system == 0) thread->pmds[cnum] = hw_value;
+                       /*
+                        * write hardware register if we can
+@@ -3265,35 +3287,40 @@
+       unsigned long val = 0UL, lval ;
+       pfarg_reg_t *req = (pfarg_reg_t *)arg;
+       unsigned int cnum, reg_flags = 0;
+-      int i, is_loaded, can_access_pmu = 0;
++      int i, can_access_pmu = 0, state;
++      int is_loaded, is_system;
+       int ret = -EINVAL;
+-      if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
+-
+       /*
+        * access is possible when loaded only for
+        * self-monitoring tasks or in UP mode
+        */
+-      is_loaded = CTX_IS_LOADED(ctx);
++
++      state     = ctx->ctx_state;
++      is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++      is_system = ctx->ctx_fl_system;
++
++      if (state == PFM_CTX_ZOMBIE) return -EINVAL;
+       if (is_loaded) {
+               thread = &ctx->ctx_task->thread;
+               /*
+-               * this can be true when not self-monitoring only in UP
+-               */
+-              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task? 1 : 0;
+-
+-              if (can_access_pmu) ia64_srlz_d();
+-              /*
+                * In system wide and when the context is loaded, access can only happen
+                * when the caller is running on the CPU being monitored by the session.
+                * It does not have to be the owner (ctx_task) of the context per se.
+                */
+-              if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++              if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+                       DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+                       return -EBUSY;
+               }
++              /*
++               * this can be true when not self-monitoring only in UP
++               */
++              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
++
++              if (can_access_pmu) ia64_srlz_d();
+       }
++
+       DPRINT(("enter loaded=%d access_pmu=%d ctx_state=%d\n",
+               is_loaded,
+               can_access_pmu,
+@@ -3334,7 +3361,7 @@
+                        * if context is zombie, then task does not exist anymore.
+                        * In this case, we use the full value saved in the context (pfm_flush_regs()).
+                        */
+-                      val = CTX_IS_LOADED(ctx) ? thread->pmds[cnum] : 0UL;
++                      val = state == PFM_CTX_LOADED ? thread->pmds[cnum] : 0UL;
+               }
+               if (PMD_IS_COUNTING(cnum)) {
+@@ -3628,7 +3655,7 @@
+                       if (rst_ctrl.bits.mask_monitoring == 0) {
+                               DPRINT(("resuming monitoring for [%d]\n", task->pid));
+-                              if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(task);
++                              if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
+                       } else {
+                               DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
+@@ -3643,7 +3670,7 @@
+               /*
+                * back to LOADED state
+                */
+-              CTX_LOADED(ctx);
++              ctx->ctx_state = PFM_CTX_LOADED;
+               return 0;
+       }
+@@ -3706,30 +3733,34 @@
+       dbreg_t dbreg;
+       unsigned int rnum;
+       int first_time;
+-      int ret = 0;
+-      int i, can_access_pmu = 0, is_loaded;
++      int ret = 0, state;
++      int i, can_access_pmu = 0;
++      int is_system, is_loaded;
+       if (pmu_conf.use_rr_dbregs == 0) return -EINVAL;
+-      if (CTX_IS_DEAD(ctx)) return -EINVAL;
++      state     = ctx->ctx_state;
++      is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
++      is_system = ctx->ctx_fl_system;
++
++      if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
+-      is_loaded = CTX_IS_LOADED(ctx);
+       /*
+        * on both UP and SMP, we can only write to the PMC when the task is
+        * the owner of the local PMU.
+        */
+       if (is_loaded) {
+               thread = &ctx->ctx_task->thread;
+-              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+               /*
+                * In system wide and when the context is loaded, access can only happen
+                * when the caller is running on the CPU being monitored by the session.
+                * It does not have to be the owner (ctx_task) of the context per se.
+                */
+-              if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++              if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+                       DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+                       return -EBUSY;
+               }
++              can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
+       }
+       /*
+@@ -3758,7 +3789,7 @@
+        */
+       LOCK_PFS();
+-      if (first_time && ctx->ctx_fl_system) {
++      if (first_time && is_system) {
+               if (pfm_sessions.pfs_ptrace_use_dbregs)
+                       ret = -EBUSY;
+               else
+@@ -3906,16 +3937,19 @@
+ {
+       struct pt_regs *tregs;
+       struct task_struct *task = PFM_CTX_TASK(ctx);
++      int state, is_system;
++      state     = ctx->ctx_state;
++      is_system = ctx->ctx_fl_system;
+-      if (CTX_IS_LOADED(ctx) == 0 && CTX_IS_MASKED(ctx) == 0) return -EINVAL;
++      if (state != PFM_CTX_LOADED && state != PFM_CTX_MASKED) return -EINVAL;
+       /*
+        * In system wide and when the context is loaded, access can only happen
+        * when the caller is running on the CPU being monitored by the session.
+        * It does not have to be the owner (ctx_task) of the context per se.
+        */
+-      if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++      if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+               DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+               return -EBUSY;
+       }
+@@ -3925,7 +3959,7 @@
+        * and the user level state of the caller, which may not
+        * necessarily be the creator of the context.
+        */
+-      if (ctx->ctx_fl_system) {
++      if (is_system) {
+               /*
+                * Update local PMU first
+                *
+@@ -3985,15 +4019,19 @@
+ pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+ {
+       struct pt_regs *tregs;
++      int state, is_system;
++
++      state     = ctx->ctx_state;
++      is_system = ctx->ctx_fl_system;
+-      if (CTX_IS_LOADED(ctx) == 0) return -EINVAL;
++      if (state != PFM_CTX_LOADED) return -EINVAL;
+       /*
+        * In system wide and when the context is loaded, access can only happen
+        * when the caller is running on the CPU being monitored by the session.
+        * It does not have to be the owner (ctx_task) of the context per se.
+        */
+-      if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
++      if (is_system && ctx->ctx_cpu != smp_processor_id()) {
+               DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+               return -EBUSY;
+       }
+@@ -4003,7 +4041,7 @@
+        * and the user level state of the caller, which may not
+        * necessarily be the creator of the context.
+        */
+-      if (ctx->ctx_fl_system) {
++      if (is_system) {
+               /*
+                * set user level psr.pp for the caller
+@@ -4055,7 +4093,6 @@
+                */
+               ia64_psr(tregs)->up = 1;
+       }
+-
+       return 0;
+ }
+@@ -4121,11 +4158,14 @@
+       unsigned long *pmcs_source, *pmds_source;
+       int the_cpu;
+       int ret = 0;
++      int state, is_system;
++      state     = ctx->ctx_state;
++      is_system = ctx->ctx_fl_system;
+       /*
+        * can only load from unloaded or terminated state
+        */
+-      if (CTX_IS_UNLOADED(ctx) == 0 && CTX_IS_TERMINATED(ctx) == 0) {
++      if (state != PFM_CTX_UNLOADED && state != PFM_CTX_TERMINATED) {
+               DPRINT(("[%d] cannot load to [%d], invalid ctx_state=%d\n",
+                       current->pid,
+                       req->load_pid,
+@@ -4151,7 +4191,7 @@
+       /*
+        * system wide is self monitoring only
+        */
+-      if (ctx->ctx_fl_system && task != current) {
++      if (is_system && task != current) {
+               DPRINT(("system wide is self monitoring only current=%d load_pid=%d\n",
+                       current->pid,
+                       req->load_pid));
+@@ -4191,7 +4231,7 @@
+       /*
+        * now reserve the session
+        */
+-      ret = pfm_reserve_session(current, ctx->ctx_fl_system, the_cpu);
++      ret = pfm_reserve_session(current, is_system, the_cpu);
+       if (ret) goto error;
+       ret = -EBUSY;
+@@ -4216,15 +4256,14 @@
+       pfm_reset_msgq(ctx);
+-      CTX_LOADED(ctx);
++      ctx->ctx_state = PFM_CTX_LOADED;
+       /*
+        * link context to task
+        */
+       ctx->ctx_task = task;
+-      if (ctx->ctx_fl_system) {
+-
++      if (is_system) {
+               /*
+                * we load as stopped
+                */
+@@ -4250,7 +4289,7 @@
+        */
+       if (task == current) {
+-              if (ctx->ctx_fl_system == 0) {
++              if (is_system == 0) {
+                       /* allow user level control */
+                       ia64_psr(regs)->sp = 0;
+@@ -4318,14 +4357,14 @@
+       /*
+        * release task, there is now a link with the context
+        */
+-      if (ctx->ctx_fl_system == 0 && task != current) {
++      if (is_system == 0 && task != current) {
+               pfm_put_task(task);
+               if (ret == 0) {
+                       ret = pfm_check_task_exist(ctx);
+                       if (ret) {
+-                              CTX_UNLOADED(ctx);
+-                              ctx->ctx_task = NULL;
++                              ctx->ctx_state = PFM_CTX_UNLOADED;
++                              ctx->ctx_task  = NULL;
+                       }
+               }
+       }
+@@ -4347,40 +4386,34 @@
+ {
+       struct task_struct *task = PFM_CTX_TASK(ctx);
+       struct pt_regs *tregs;
++      int state, is_system;
+       DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
++      state     = ctx->ctx_state;
++      is_system = ctx->ctx_fl_system;
++
+       /*
+        * unload only when necessary
+        */
+-      if (CTX_IS_TERMINATED(ctx) || CTX_IS_UNLOADED(ctx)) {
++      if (state == PFM_CTX_TERMINATED || state == PFM_CTX_UNLOADED) {
+               DPRINT(("[%d] ctx_state=%d, nothing to do\n", current->pid, ctx->ctx_state));
+               return 0;
+       }
+       /*
+-       * In system wide and when the context is loaded, access can only happen
+-       * when the caller is running on the CPU being monitored by the session.
+-       * It does not have to be the owner (ctx_task) of the context per se.
+-       */
+-      if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+-              DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+-              return -EBUSY;
+-      }
+-
+-      /*
+        * clear psr and dcr bits
+        */
+       pfm_stop(ctx, NULL, 0, regs);
+-      CTX_UNLOADED(ctx);
++      ctx->ctx_state = state = PFM_CTX_UNLOADED;
+       /*
+        * in system mode, we need to update the PMU directly
+        * and the user level state of the caller, which may not
+        * necessarily be the creator of the context.
+        */
+-      if (ctx->ctx_fl_system) {
++      if (is_system) {
+               /*
+                * Update cpuinfo
+@@ -4524,7 +4557,7 @@
+                       if (ret) {
+                               printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, ctx->ctx_state, ret);
+                       }
+-                      CTX_TERMINATED(ctx);
++                      ctx->ctx_state = PFM_CTX_TERMINATED;
+                       DPRINT(("ctx terminated by [%d]\n", task->pid));
+                       pfm_end_notify_user(ctx);
+@@ -4606,16 +4639,19 @@
+ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
+ {
+       struct task_struct *task;
++      int state;
++
++      state = ctx->ctx_state;
+       task = PFM_CTX_TASK(ctx);
+       if (task == NULL) {
+-              DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, ctx->ctx_state));
++              DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, state));
+               return 0;
+       }
+       DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
+                               ctx->ctx_fd,
+-                              ctx->ctx_state,
++                              state,
+                               task->pid,
+                               task->state, PFM_CMD_STOPPED(cmd)));
+@@ -4631,9 +4667,9 @@
+       /*
+        * context is UNLOADED, MASKED, TERMINATED we are safe to go
+        */
+-      if (CTX_IS_LOADED(ctx) == 0) return 0;
++      if (state != PFM_CTX_LOADED == 0) return 0;
+-      if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
++      if (state == PFM_CTX_ZOMBIE) return -EINVAL;
+       /*
+        * context is loaded, we must make sure the task is stopped
+@@ -4653,6 +4689,7 @@
+       pfm_wait_task_inactive(task);
+       PROTECT_CTX(ctx, flags);
++
+       return 0;
+ }
+@@ -4830,12 +4867,12 @@
+               }
+               if (rst_ctrl.bits.mask_monitoring == 0) {
+                       DPRINT(("resuming monitoring\n"));
+-                      if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(current);
++                      if (ctx->ctx_state == PFM_CTX_MASKED) pfm_restore_monitoring(current);
+               } else {
+                       DPRINT(("stopping monitoring\n"));
+                       //pfm_stop_monitoring(current, regs);
+               }
+-              CTX_LOADED(ctx);
++              ctx->ctx_state = PFM_CTX_LOADED;
+       }
+ }
+@@ -4869,7 +4906,7 @@
+       /*
+        * switch to terminated state
+        */
+-      CTX_TERMINATED(ctx);
++      ctx->ctx_state = PFM_CTX_TERMINATED;
+       DPRINT(("context <%d> terminated for [%d]\n", ctx->ctx_fd, current->pid));
+@@ -4922,7 +4959,7 @@
+       /*
+        * must be done before we check non-blocking mode
+        */
+-      if (ctx->ctx_fl_going_zombie || CTX_IS_ZOMBIE(ctx)) goto do_zombie;
++      if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) goto do_zombie;
+       ovfl_regs = ctx->ctx_ovfl_regs[0];
+@@ -4966,7 +5003,7 @@
+ static int
+ pfm_notify_user(pfm_context_t *ctx, pfm_msg_t *msg)
+ {
+-      if (CTX_IS_ZOMBIE(ctx)) {
++      if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
+               DPRINT(("ignoring overflow notification, owner is zombie\n"));
+               return 0;
+       }
+@@ -5049,13 +5086,13 @@
+       pfm_ovfl_arg_t ovfl_arg;
+       unsigned long mask;
+       unsigned long old_val;
+-      unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
++      unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL;
+       unsigned long tstamp;
+       pfm_ovfl_ctrl_t ovfl_ctrl;
+       unsigned int i, has_smpl;
+       int must_notify = 0;
+-      if (unlikely(CTX_IS_ZOMBIE(ctx))) goto stop_monitoring;
++      if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) goto stop_monitoring;
+       /*
+        * sanity test. Should never happen
+@@ -5106,10 +5143,9 @@
+                       if (PMC_OVFL_NOTIFY(ctx, i)) ovfl_notify |= 1UL << i;
+               }
+-              DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx "
+-                           "ovfl_notify=0x%lx\n",
+-                           i, ctx->ctx_pmds[i].val, old_val,
+-                           ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify));
++              DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx smpl_pmds=0x%lx\n",
++                      i, ctx->ctx_pmds[i].val, old_val,
++                      ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify, smpl_pmds));
+       }
+       /*
+@@ -5128,7 +5164,7 @@
+        */
+       if (has_smpl) {
+               unsigned long start_cycles, end_cycles;
+-              unsigned long pmd_mask, smpl_pmds;
++              unsigned long pmd_mask;
+               int j, k, ret = 0;
+               int this_cpu = smp_processor_id();
+@@ -5257,7 +5293,7 @@
+        */
+       if (ovfl_ctrl.bits.mask_monitoring) {
+               pfm_mask_monitoring(task);
+-              CTX_MASKED(ctx);
++              ctx->ctx_state = PFM_CTX_MASKED;
+       }
+       /*
+@@ -5553,19 +5589,18 @@
+               pfm_set_psr_pp();
+               ia64_srlz_i();
+       }
+-      { unsigned long val;
+-              val = ia64_get_pmc(4);
+-              if ((val & (1UL<<23)) == 0UL) printk("perfmon: PMU off: pmc4=0x%lx\n", val);
+-      }
+ }
+ void
+ pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin)
+ {
+       unsigned long start, end;
++
+       pfm_stats[smp_processor_id()].pfm_sysupdt_count++;
+       start = ia64_get_itc();
++
+       pfm_do_syst_wide_update_task(task, info, is_ctxswin);
++
+       end = ia64_get_itc();
+       pfm_stats[smp_processor_id()].pfm_sysupdt_cycles += end-start;
+ }
+@@ -5591,7 +5626,7 @@
+        */
+       flags = pfm_protect_ctx_ctxsw(ctx);
+-      if (CTX_IS_ZOMBIE(ctx)) {
++      if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
+               struct pt_regs *regs = ia64_task_regs(task);
+               pfm_clear_psr_up();
+@@ -5840,7 +5875,7 @@
+       BUG_ON(psr & IA64_PSR_I);
+ #endif
+-      if (unlikely(CTX_IS_ZOMBIE(ctx))) {
++      if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) {
+               struct pt_regs *regs = ia64_task_regs(task);
+               BUG_ON(ctx->ctx_smpl_hdr);
+Index: linux-2.6.0-test5/arch/ia64/kernel/perfmon_hpsim.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/perfmon_hpsim.h    2003-09-27 11:38:18.435725728 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/perfmon_hpsim.h 2003-09-27 11:38:19.437573424 +0800
+@@ -0,0 +1,75 @@
++/*
++ * This file contains the HP SKI Simulator PMU register description tables
++ * and pmc checkers used by perfmon.c.
++ *
++ * Copyright (C) 2002-2003  Hewlett Packard Co
++ *               Stephane Eranian <eranian@hpl.hp.com>
++ *
++ * File mostly contributed by Ian Wienand <ianw@gelato.unsw.edu.au>
++ *
++ * This file is included as a dummy template so the kernel does not
++ * try to initalize registers the simulator can't handle.
++ *
++ * Note the simulator does not (currently) implement these registers, i.e.,
++ * they do not count anything. But you can read/write them.
++ */
++
++#define RDEP(x)       (1UL<<(x))
++
++#ifndef CONFIG_IA64_HP_SIM
++#error "This file should only be included for the HP Simulator"
++#endif
++
++static pfm_reg_desc_t pfm_hpsim_pmc_desc[PMU_MAX_PMCS]={
++/* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc3  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc4  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(4), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc5  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc6  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc7  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc8  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc9  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(9), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(10), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(11), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(12), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(13), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(14), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmc15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(15), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++          { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
++};
++
++static pfm_reg_desc_t pfm_hpsim_pmd_desc[PMU_MAX_PMDS]={
++/* pmd0  */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd1  */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd2  */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd3  */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
++/* pmd4  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
++/* pmd5  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
++/* pmd6  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
++/* pmd7  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
++/* pmd8  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(8),0UL, 0UL, 0UL}},
++/* pmd9  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(9),0UL, 0UL, 0UL}},
++/* pmd10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
++/* pmd11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
++/* pmd12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
++/* pmd13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(13),0UL, 0UL, 0UL}},
++/* pmd14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(14),0UL, 0UL, 0UL}},
++/* pmd15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(15),0UL, 0UL, 0UL}},
++          { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
++};
++
++/*
++ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
++ */
++static pmu_config_t pmu_conf={
++      .pmu_name   = "hpsim",
++      .pmu_family = 0x7, /* ski emulator reports as Itanium */
++      .enabled    = 0,
++      .ovfl_val   = (1UL << 32) - 1,
++      .num_ibrs   = 0, /* does not use */
++      .num_dbrs   = 0, /* does not use */
++      .pmd_desc   = pfm_hpsim_pmd_desc,
++      .pmc_desc   = pfm_hpsim_pmc_desc
++};
+Index: linux-2.6.0-test5/arch/ia64/kernel/salinfo.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/salinfo.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/salinfo.c       2003-09-27 11:38:19.439573120 +0800
+@@ -5,6 +5,7 @@
+  *
+  * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+  *
++ * 09/11/2003 jbarnes@sgi.com         updated for 2.6
+  * 10/30/2001 jbarnes@sgi.com         copied much of Stephane's palinfo
+  *                                    code to create this file
+  */
+@@ -59,7 +60,7 @@
+               *sdir = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
+                                                 salinfo_read, (void *)salinfo_entries[i].feature);
+               if (*sdir)
+-                      *sdir->owner = THIS_MODULE;
++                      (*sdir)->owner = THIS_MODULE;
+               sdir++;
+       }
+       *sdir++ = salinfo_dir;
+Index: linux-2.6.0-test5/arch/ia64/kernel/smpboot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/smpboot.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/smpboot.c       2003-09-27 11:38:19.443572512 +0800
+@@ -534,8 +534,8 @@
+               printk(KERN_INFO "SMP mode deactivated.\n");
+               cpus_clear(cpu_online_map);
+               cpus_clear(phys_cpu_present_map);
+-              cpu_set(1, cpu_online_map);
+-              cpu_set(1, phys_cpu_present_map);
++              cpu_set(0, cpu_online_map);
++              cpu_set(0, phys_cpu_present_map);
+               return;
+       }
+ }
+Index: linux-2.6.0-test5/arch/ia64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/time.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/time.c  2003-09-27 11:38:19.447571904 +0800
+@@ -17,6 +17,7 @@
+ #include <linux/time.h>
+ #include <linux/interrupt.h>
+ #include <linux/efi.h>
++#include <linux/profile.h>
+ #include <linux/timex.h>
+ #include <asm/delay.h>
+@@ -39,29 +40,6 @@
+ #endif
+ static void
+-do_profile (unsigned long ip)
+-{
+-      extern cpumask_t prof_cpu_mask;
+-
+-      if (!prof_buffer)
+-              return;
+-
+-      if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
+-              return;
+-
+-      ip -= (unsigned long) _stext;
+-      ip >>= prof_shift;
+-      /*
+-       * Don't ignore out-of-bounds IP values silently, put them into the last
+-       * histogram slot, so if present, they will show up as a sharp peak.
+-       */
+-      if (ip > prof_len - 1)
+-              ip = prof_len - 1;
+-
+-      atomic_inc((atomic_t *) &prof_buffer[ip]);
+-}
+-
+-static void
+ itc_reset (void)
+ {
+ }
+@@ -199,6 +177,52 @@
+       tv->tv_usec = usec;
+ }
++/*
++ * The profiling function is SMP safe. (nothing can mess
++ * around with "current", and the profiling counters are
++ * updated with atomic operations). This is especially
++ * useful with a profiling multiplier != 1
++ */
++static inline void
++ia64_do_profile (struct pt_regs * regs)
++{
++      unsigned long ip, slot;
++      extern cpumask_t prof_cpu_mask;
++
++      profile_hook(regs);
++
++      if (user_mode(regs))
++              return;
++
++      if (!prof_buffer)
++              return;
++
++      ip = instruction_pointer(regs);
++      /* Conserve space in histogram by encoding slot bits in address
++       * bits 2 and 3 rather than bits 0 and 1.
++       */
++      slot = ip & 3;
++      ip = (ip & ~3UL) + 4*slot;
++
++      /*
++       * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
++       * (default is all CPUs.)
++       */
++      if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
++              return;
++
++      ip -= (unsigned long) &_stext;
++      ip >>= prof_shift;
++      /*
++       * Don't ignore out-of-bounds IP values silently,
++       * put them into the last histogram slot, so if
++       * present, they will show up as a sharp peak.
++       */
++      if (ip > prof_len-1)
++              ip = prof_len-1;
++      atomic_inc((atomic_t *)&prof_buffer[ip]);
++}
++
+ static irqreturn_t
+ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+ {
+@@ -210,14 +234,9 @@
+               printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
+                      ia64_get_itc(), new_itm);
++      ia64_do_profile(regs);
++
+       while (1) {
+-              /*
+-               * Do kernel PC profiling here.  We multiply the instruction number by
+-               * four so that we can use a prof_shift of 2 to get instruction-level
+-               * instead of just bundle-level accuracy.
+-               */
+-              if (!user_mode(regs))
+-                      do_profile(regs->cr_iip + 4*ia64_psr(regs)->ri);
+ #ifdef CONFIG_SMP
+               smp_do_timer(regs);
+Index: linux-2.6.0-test5/arch/ia64/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/traps.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/traps.c 2003-09-27 11:38:19.452571144 +0800
+@@ -568,10 +568,10 @@
+               }
+               siginfo.si_signo = SIGTRAP;
+               siginfo.si_errno = 0;
+-              siginfo.si_flags = 0;
+-              siginfo.si_isr = 0;
+-              siginfo.si_addr = (void *) ifa;
+-              siginfo.si_imm = 0;
++              siginfo.si_addr  = (void *) ifa;
++              siginfo.si_imm   = 0;
++              siginfo.si_flags = __ISR_VALID;
++              siginfo.si_isr   = isr;
+               force_sig_info(SIGTRAP, &siginfo, current);
+               return;
+Index: linux-2.6.0-test5/arch/ia64/kernel/unwind.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/kernel/unwind.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/kernel/unwind.c        2003-09-27 11:38:19.474567800 +0800
+@@ -1171,9 +1171,10 @@
+ static inline unw_hash_index_t
+ hash (unsigned long ip)
+ {
+-#     define magic    0x9e3779b97f4a7c16      /* based on (sqrt(5)/2-1)*2^64 */
++#     define hashmagic        0x9e3779b97f4a7c16      /* based on (sqrt(5)/2-1)*2^64 */
+-      return (ip >> 4)*magic >> (64 - UNW_LOG_HASH_SIZE);
++      return (ip >> 4)*hashmagic >> (64 - UNW_LOG_HASH_SIZE);
++#undef hashmagic
+ }
+ static inline long
+Index: linux-2.6.0-test5/arch/ia64/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/Makefile  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/Makefile       2003-09-27 11:38:19.475567648 +0800
+@@ -65,6 +65,7 @@
+ 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/
++drivers-$(CONFIG_OPROFILE)    += arch/ia64/oprofile/
+ boot := arch/ia64/hp/sim/boot
+Index: linux-2.6.0-test5/arch/ia64/mm/discontig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/mm/discontig.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/mm/discontig.c 2003-09-27 11:38:19.479567040 +0800
+@@ -13,7 +13,6 @@
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/bootmem.h>
+-#include <linux/mmzone.h>
+ #include <linux/acpi.h>
+ #include <linux/efi.h>
+@@ -23,10 +22,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;
+ extern int  filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
+Index: linux-2.6.0-test5/arch/ia64/mm/hugetlbpage.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/mm/hugetlbpage.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/mm/hugetlbpage.c       2003-09-27 11:38:19.482566584 +0800
+@@ -297,14 +297,21 @@
+                       + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+               page = find_get_page(mapping, idx);
+               if (!page) {
++                      /* charge the fs quota first */
++                      if (hugetlb_get_quota(mapping)) {
++                              ret = -ENOMEM;
++                              goto out;
++                      }
+                       page = alloc_hugetlb_page();
+                       if (!page) {
++                              hugetlb_put_quota(mapping);
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+                       unlock_page(page);
+                       if (ret) {
++                              hugetlb_put_quota(mapping);
+                               free_huge_page(page);
+                               goto out;
+                       }
+Index: linux-2.6.0-test5/arch/ia64/mm/numa.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/mm/numa.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/mm/numa.c      2003-09-27 11:38:19.484566280 +0800
+@@ -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 @@
+  * 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
+Index: linux-2.6.0-test5/arch/ia64/oprofile/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/oprofile/init.c   2003-09-27 11:38:18.436725576 +0800
++++ linux-2.6.0-test5/arch/ia64/oprofile/init.c        2003-09-27 11:38:19.484566280 +0800
+@@ -0,0 +1,25 @@
++/**
++ * @file init.c
++ *
++ * @remark Copyright 2002 OProfile authors
++ * @remark Read the file COPYING
++ *
++ * @author John Levon <levon@movementarian.org>
++ */
++
++#include <linux/kernel.h>
++#include <linux/oprofile.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++ 
++extern void timer_init(struct oprofile_operations ** ops);
++
++int __init oprofile_arch_init(struct oprofile_operations ** ops)
++{
++      return -ENODEV;
++}
++
++
++void oprofile_arch_exit(void)
++{
++}
+Index: linux-2.6.0-test5/arch/ia64/oprofile/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/oprofile/Kconfig  2003-09-27 11:38:18.436725576 +0800
++++ linux-2.6.0-test5/arch/ia64/oprofile/Kconfig       2003-09-27 11:38:19.484566280 +0800
+@@ -0,0 +1,22 @@
++
++menu "Profiling support"
++      depends on EXPERIMENTAL
++
++config PROFILING
++      bool "Profiling support (EXPERIMENTAL)"
++      help
++        Say Y here to enable the extended profiling support mechanisms used
++        by profilers such as OProfile.
++
++config OPROFILE
++      tristate "OProfile system profiling (EXPERIMENTAL)"
++      depends on PROFILING
++      help
++        OProfile is a profiling system capable of profiling the
++        whole system, include the kernel, kernel modules, libraries,
++        and applications.
++
++        If unsure, say N.
++
++endmenu
++
+Index: linux-2.6.0-test5/arch/ia64/oprofile/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/oprofile/Makefile 2003-09-27 11:38:18.436725576 +0800
++++ linux-2.6.0-test5/arch/ia64/oprofile/Makefile      2003-09-27 11:38:19.485566128 +0800
+@@ -0,0 +1,9 @@
++obj-$(CONFIG_OPROFILE) += oprofile.o
++
++DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
++              oprof.o cpu_buffer.o buffer_sync.o \
++              event_buffer.o oprofile_files.o \
++              oprofilefs.o oprofile_stats.o \
++              timer_int.o )
++
++oprofile-y := $(DRIVER_OBJS) init.o
+Index: linux-2.6.0-test5/arch/ia64/scripts/toolchain-flags
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/scripts/toolchain-flags   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/scripts/toolchain-flags        2003-09-27 11:38:19.486565976 +0800
+@@ -20,7 +20,7 @@
+ EOF
+ fi
+-if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep -q 'attribute directive ignored'
++if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep  __model__ | grep -q attrib
+ then
+     CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
+ fi
+Index: linux-2.6.0-test5/arch/ia64/sn/io/drivers/ioconfig_bus.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/drivers/ioconfig_bus.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/drivers/ioconfig_bus.c   2003-09-27 11:38:19.490565368 +0800
+@@ -24,7 +24,7 @@
+ #include <asm/sn/invent.h>
+ #include <asm/sn/hcl.h>
+ #include <asm/sn/labelcl.h>
+-#include <asm//sn/sn_sal.h>
++#include <asm/sn/sn_sal.h>
+ #include <asm/sn/addrs.h>
+ #include <asm/sn/ioconfig_bus.h>
+@@ -157,7 +157,7 @@
+       char *name;
+       char *temp;
+       char *next;
+-      char *current;
++      char *curr;
+       char *line;
+       struct ascii_moduleid *moduleid;
+@@ -166,10 +166,10 @@
+       name = kmalloc(125, GFP_KERNEL);
+       memset(name, 0, 125);
+       moduleid = table;
+-      current = file_contents;
+-      while (nextline(current, &next, line)){
++      curr = file_contents;
++      while (nextline(curr, &next, line)){
+-              DBG("current 0x%lx next 0x%lx\n", current, next);
++              DBG("curr 0x%lx next 0x%lx\n", curr, next);
+               temp = line;
+               /*
+@@ -182,7 +182,7 @@
+                               break;
+               if (*temp == '\n') {
+-                      current = next;
++                      curr = next;
+                       memset(line, 0, 256);
+                       continue;
+               }
+@@ -191,7 +191,7 @@
+                * Skip comment lines
+                */
+               if (*temp == '#') {
+-                      current = next;
++                      curr = next;
+                       memset(line, 0, 256);
+                       continue;
+               }
+@@ -204,7 +204,7 @@
+               DBG("Found %s\n", name);
+               moduleid++;
+               free_entry++;
+-              current = next;
++              curr = next;
+               memset(line, 0, 256);
+       }
+Index: linux-2.6.0-test5/arch/ia64/sn/io/machvec/iomv.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/machvec/iomv.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/machvec/iomv.c   2003-09-27 11:38:19.491565216 +0800
+@@ -6,13 +6,13 @@
+  * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+  */
+-#include <linux/pci.h>
+ #include <linux/module.h>
+ #include <asm/io.h>
+ #include <asm/delay.h>
+ #include <asm/sn/simulator.h>
+ #include <asm/sn/pda.h>
+ #include <asm/sn/sn_cpuid.h>
++#include <asm/sn/sn2/shub_mmr.h>
+ /**
+  * sn_io_addr - convert an in/out port to an i/o address
+Index: linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/machvec/pci_bus_cvlink.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2003-09-27 11:38:19.498564152 +0800
+@@ -544,7 +544,7 @@
+               pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN,
+                                    (unsigned char *)&lines);
+        
+-              irqpdaindr->current = device_dev;
++              irqpdaindr->curr = device_dev;
+               intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
+               irq = intr_handle->pi_irq;
+Index: linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_dma.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/machvec/pci_dma.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/machvec/pci_dma.c        2003-09-27 11:38:19.504563240 +0800
+@@ -597,7 +597,7 @@
+       if (!sn_dma_supported(dev, dma_mask))
+               return 0;
+-      dev->dma_mask = dma_mask;
++      *dev->dma_mask = dma_mask;
+       return 1;
+ }
+ EXPORT_SYMBOL(sn_dma_set_mask);
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/ml_SN_intr.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/ml_SN_intr.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/ml_SN_intr.c 2003-09-27 11:38:19.507562784 +0800
+@@ -39,6 +39,7 @@
+ #include <asm/sn/sn2/shubio.h>
+ #include <asm/sal.h>
+ #include <asm/sn/sn_sal.h>
++#include <asm/sn/sn2/shub_mmr.h>
+ extern irqpda_t       *irqpdaindr;
+ extern cnodeid_t master_node_get(vertex_hdl_t vhdl);
+@@ -174,8 +175,8 @@
+                       min_shared = 256;
+                       for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+                               /* Share with the same device class */
+-                              if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor &&
+-                                      irqpdaindr->current->device == irqpdaindr->device_dev[i]->device &&
++                              if (irqpdaindr->curr->vendor == irqpdaindr->device_dev[i]->vendor &&
++                                      irqpdaindr->curr->device == irqpdaindr->device_dev[i]->device &&
+                                       irqpdaindr->share_count[i] < min_shared) {
+                                               min_shared = irqpdaindr->share_count[i];
+                                               bit = i;
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c    2003-09-27 11:38:19.511562176 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c 2003-09-27 11:38:19.514561720 +0800
+@@ -27,7 +27,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c    2003-09-27 11:38:19.547556704 +0800
+@@ -31,7 +31,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c  2003-09-27 11:38:19.563554272 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c  2003-09-27 11:38:19.565553968 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c   2003-09-27 11:38:19.579551840 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c    2003-09-27 11:38:19.586550776 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c   2003-09-27 11:38:19.602548344 +0800
+@@ -27,7 +27,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/pic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/pic.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/pic.c        2003-09-27 11:38:19.605547888 +0800
+@@ -26,7 +26,6 @@
+ #include <asm/sn/pci/pci_defs.h>
+ #include <asm/sn/prio.h>
+ #include <asm/sn/xtalk/xbow.h>
+-#include <asm/sn/ioc3.h>
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+Index: linux-2.6.0-test5/arch/ia64/sn/io/sn2/shub.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/io/sn2/shub.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/io/sn2/shub.c       2003-09-27 11:38:19.610547128 +0800
+@@ -34,6 +34,8 @@
+ #include <asm/sal.h>
+ #include <asm/sn/sn_sal.h>
+ #include <asm/sn/sndrv.h>
++#include <asm/sn/sn2/shubio.h>
++#include <asm/sn/sn2/shub_mmr.h>
+ /*
+  * Shub WAR for Xbridge Little Endian problem:
+@@ -491,7 +493,7 @@
+       spin_lock_init(&sn_linkstats_lock);
+       sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL);
+       sn_linkstats_reset(60000UL); /* default 60 second update interval */
+-      kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      kernel_thread(linkstatd_thread, NULL, CLONE_KERNEL);
+       return 0;                                                                       
+ }
+Index: linux-2.6.0-test5/arch/ia64/sn/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ia64/sn/kernel/irq.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ia64/sn/kernel/irq.c        2003-09-27 11:38:19.613546672 +0800
+@@ -35,7 +35,6 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ #include <linux/vmalloc.h>
+-#include <asm/current.h>
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+ #include <linux/slab.h>
+@@ -44,7 +43,6 @@
+ #include <asm/sn/sgi.h>
+ #include <asm/sn/iograph.h>
+ #include <asm/sn/invent.h>
+-#include <linux/devfs_fs_kernel.h>
+ #include <asm/sn/hcl.h>
+ #include <asm/sn/types.h>
+ #include <asm/sn/pci/bridge.h>
+@@ -62,6 +60,7 @@
+ #include <asm/processor.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
++#include <asm/sn/sn2/shub_mmr.h>
+ int irq_to_bit_pos(int irq);
+ static void force_interrupt(int irq);
+Index: linux-2.6.0-test5/arch/m68k/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/m68k/kernel/signal.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/m68k/kernel/signal.c        2003-09-27 11:38:19.621545456 +0800
+@@ -1082,7 +1082,7 @@
+                               continue;
+                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
+-                              if (is_orphaned_pgrp(current->pgrp))
++                              if (is_orphaned_pgrp(process_group(current)))
+                                       continue;
+                               /* FALLTHRU */
+Index: linux-2.6.0-test5/arch/m68knommu/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/m68knommu/kernel/signal.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/m68knommu/kernel/signal.c   2003-09-27 11:38:19.628544392 +0800
+@@ -841,7 +841,7 @@
+                               continue;
+                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
+-                              if (is_orphaned_pgrp(current->pgrp))
++                              if (is_orphaned_pgrp(process_group(current)))
+                                       continue;
+                               /* FALLTHRU */
+Index: linux-2.6.0-test5/arch/mips/jazz/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/jazz/setup.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/jazz/setup.c   2003-09-27 11:38:19.632543784 +0800
+@@ -9,6 +9,7 @@
+  * Copyright (C) 2001 MIPS Technologies, Inc.
+  */
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/hdreg.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+Index: linux-2.6.0-test5/arch/mips/kernel/irixelf.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/irixelf.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/irixelf.c       2003-09-27 11:38:19.641542416 +0800
+@@ -1088,6 +1088,7 @@
+       elf.e_ident[EI_CLASS] = ELFCLASS32;
+       elf.e_ident[EI_DATA] = ELFDATA2LSB;
+       elf.e_ident[EI_VERSION] = EV_CURRENT;
++      elf.e_ident[EI_OSABI] = ELF_OSABI;
+       memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+       elf.e_type = ET_CORE;
+@@ -1129,7 +1130,7 @@
+       prstatus.pr_sighold = current->blocked.sig[0];
+       psinfo.pr_pid = prstatus.pr_pid = current->pid;
+       psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
+-      psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
++      psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current);
+       psinfo.pr_sid = prstatus.pr_sid = current->session;
+       prstatus.pr_utime.tv_sec = CT_TO_SECS(current->utime);
+       prstatus.pr_utime.tv_usec = CT_TO_USECS(current->utime);
+Index: linux-2.6.0-test5/arch/mips/kernel/irixsig.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/irixsig.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/irixsig.c       2003-09-27 11:38:19.646541656 +0800
+@@ -582,7 +582,7 @@
+               p = list_entry(_p,struct task_struct,sibling);
+               if ((type == P_PID) && p->pid != pid)
+                       continue;
+-              if ((type == P_PGID) && p->pgrp != pid)
++              if ((type == P_PGID) && process_group(p) != pid)
+                       continue;
+               if ((p->exit_signal != SIGCHLD))
+                       continue;
+Index: linux-2.6.0-test5/arch/mips/kernel/linux32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/linux32.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/linux32.c       2003-09-27 11:38:19.658539832 +0800
+@@ -71,14 +71,17 @@
+ {
+       struct compat_stat tmp;
++      if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++
+       memset(&tmp, 0, sizeof(tmp));
+-      tmp.st_dev = stat->dev;
++      tmp.st_dev = new_encode_dev(stat->dev);
+       tmp.st_ino = stat->ino;
+       tmp.st_mode = stat->mode;
+       tmp.st_nlink = stat->nlink;
+       SET_STAT_UID(tmp, stat->uid);
+       SET_STAT_GID(tmp, stat->gid);
+-      tmp.st_rdev = stat->rdev;
++      tmp.st_rdev = new_encode_dev(stat->rdev);
+       tmp.st_size = stat->size;
+       tmp.st_atime = stat->atime.tv_sec;
+       tmp.st_mtime = stat->mtime.tv_sec;
+Index: linux-2.6.0-test5/arch/mips/kernel/mips_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/mips_ksyms.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/mips_ksyms.c    2003-09-27 11:38:19.660539528 +0800
+@@ -43,10 +43,6 @@
+ EXPORT_SYMBOL(mips_machtype);
+-#ifdef CONFIG_EISA
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+-
+ /*
+  * String functions
+  */
+Index: linux-2.6.0-test5/arch/mips/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/setup.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/setup.c 2003-09-27 11:38:19.665538768 +0800
+@@ -44,15 +44,6 @@
+ struct screen_info screen_info;
+ #endif
+-/*
+- * Set if box has EISA slots.
+- */
+-#ifdef CONFIG_EISA
+-int EISA_bus;
+-
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+-
+ #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
+ extern struct fd_ops no_fd_ops;
+ struct fd_ops *fd_ops;
+Index: linux-2.6.0-test5/arch/mips/kernel/sysirix.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/kernel/sysirix.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/kernel/sysirix.c       2003-09-27 11:38:19.679536640 +0800
+@@ -803,11 +803,11 @@
+       printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
+ #endif
+       if(!flags)
+-              error = current->pgrp;
++              error = process_group(current);
+       else
+               error = sys_setsid();
+ #ifdef DEBUG_PROCGRPS
+-      printk("returning %d\n", current->pgrp);
++      printk("returning %d\n", process_group(current));
+ #endif
+       return error;
+@@ -1187,13 +1187,7 @@
+ #undef DEBUG_XSTAT
+-static inline u32
+-linux_to_irix_dev_t (dev_t t)
+-{
+-      return MAJOR (t) << 18 | MINOR (t);
+-}
+-
+-static inline int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
++static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
+ {
+       struct xstat32 {
+               u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
+@@ -1206,13 +1200,15 @@
+               u32 st_pad4[8];
+       } ub;
+-      ub.st_dev     = linux_to_irix_dev_t(stat->dev);
++      if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++      ub.st_dev     = sysv_encode_dev(stat->dev);
+       ub.st_ino     = stat->ino;
+       ub.st_mode    = stat->mode;
+       ub.st_nlink   = stat->nlink;
+       SET_STAT_UID(ub, stat->uid);
+       SET_STAT_GID(ub, stat->gid);
+-      ub.st_rdev    = linux_to_irix_dev_t(stat->rdev);
++      ub.st_rdev    = sysv_encode_dev(stat->rdev);
+ #if BITS_PER_LONG == 32
+       if (stat->size > MAX_NON_LFS)
+               return -EOVERFLOW;
+@@ -1231,7 +1227,7 @@
+       return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
+ }
+-static inline void irix_xstat64_xlate(struct kstat *stat, void *ubuf)
++static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
+ {
+       struct xstat64 {
+               u32 st_dev; s32 st_pad1[3];
+@@ -1248,14 +1244,17 @@
+               s32 st_pad4[8];
+       } ks;
+-      ks.st_dev = linux_to_irix_dev_t(stat->dev);
++      if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++
++      ks.st_dev = sysv_encode_dev(stat->dev);
+       ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
+       ks.st_ino = (unsigned long long) stat->ino;
+       ks.st_mode = (u32) stat->mode;
+       ks.st_nlink = (u32) stat->nlink;
+       ks.st_uid = (s32) stat->uid;
+       ks.st_gid = (s32) stat->gid;
+-      ks.st_rdev = linux_to_irix_dev_t (stat->rdev);
++      ks.st_rdev = sysv_encode_dev (stat->rdev);
+       ks.st_pad2[0] = ks.st_pad2[1] = 0;
+       ks.st_size = (long long) stat->size;
+       ks.st_pad3 = 0;
+@@ -1275,7 +1274,7 @@
+       ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
+       /* Now write it all back. */
+-      copy_to_user(ubuf, &ks, sizeof(struct xstat64));
++      return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
+ }
+ asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
+@@ -1295,8 +1294,7 @@
+                               retval = irix_xstat32_xlate(&stat, statbuf);
+                               break;
+                       case 3:
+-                              irix_xstat64_xlate(&stat, statbuf);
+-                              retval = 0; /* Really? */
++                              retval = irix_xstat64_xlate(&stat, statbuf);
+                               break;
+                       default:
+                               retval = -EINVAL;
+@@ -1323,8 +1321,7 @@
+                               error = irix_xstat32_xlate(&stat, statbuf);
+                               break;
+                       case 3:
+-                              irix_xstat64_xlate(&stat, statbuf);
+-                              error = 0;
++                              error = irix_xstat64_xlate(&stat, statbuf);
+                               break;
+                       default:
+                               error = -EINVAL;
+@@ -1350,8 +1347,7 @@
+                               error = irix_xstat32_xlate(&stat, statbuf);
+                               break;
+                       case 3:
+-                              irix_xstat64_xlate(&stat, statbuf);
+-                              error = 0;
++                              error = irix_xstat64_xlate(&stat, statbuf);
+                               break;
+                       default:
+                               error = -EINVAL;
+@@ -1360,17 +1356,17 @@
+       return error;
+ }
+-extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
++extern asmlinkage int sys_mknod(const char * filename, int mode, unsigned dev);
+-asmlinkage int irix_xmknod(int ver, char *filename, int mode, dev_t dev)
++asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
+ {
+       int retval;
+-
+       printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
+-             current->comm, current->pid, ver, filename, mode, (int) dev);
++             current->comm, current->pid, ver, filename, mode, dev);
+       switch(ver) {
+       case 2:
++              /* shouldn't we convert here as well as on stat()? */
+               retval = sys_mknod(filename, mode, dev);
+               break;
+Index: linux-2.6.0-test5/arch/mips/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/Makefile  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/Makefile       2003-09-27 11:38:19.685535728 +0800
+@@ -58,7 +58,6 @@
+ cflags-$(CONFIG_KGDB)         += -g
+ cflags-$(CONFIG_SB1XXX_CORELIS)       += -mno-sched-prolog -fno-omit-frame-pointer
+-check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+ check_warning = $(shell if $(CC) $(1) -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+ #
+Index: linux-2.6.0-test5/arch/mips/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/mm/ioremap.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/mm/ioremap.c   2003-09-27 11:38:19.687535424 +0800
+@@ -162,7 +162,7 @@
+       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;
+       }
+Index: linux-2.6.0-test5/arch/mips/sgi-ip22/ip22-eisa.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/sgi-ip22/ip22-eisa.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/sgi-ip22/ip22-eisa.c   2003-09-27 11:38:19.689535120 +0800
+@@ -20,6 +20,7 @@
+  */
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/types.h>
+ #include <linux/init.h>
+ #include <linux/irq.h>
+Index: linux-2.6.0-test5/arch/mips/sni/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/mips/sni/setup.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/mips/sni/setup.c    2003-09-27 11:38:19.691534816 +0800
+@@ -8,6 +8,7 @@
+  * Copyright (C) 1996, 1997, 1998, 2000, 2003 by Ralf Baechle
+  */
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/hdreg.h>
+ #include <linux/ioport.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/arch/parisc/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/defconfig       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/defconfig    2003-09-27 11:38:19.695534208 +0800
+@@ -150,24 +150,25 @@
+ CONFIG_SCSI_LASI700=y
+ CONFIG_53C700_MEM_MAPPED=y
+ CONFIG_53C700_LE_ON_BE=y
+-# CONFIG_SCSI_NCR53C7xx is not set
+-# CONFIG_SCSI_SYM53C8XX_2 is not set
++CONFIG_SCSI_SYM53C8XX_2=y
++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_ZALON=y
+-# CONFIG_SCSI_NCR53C8XX is not set
+-CONFIG_SCSI_SYM53C8XX=y
+ CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+ CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+ CONFIG_SCSI_NCR53C8XX_SYNC=20
+ # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+-# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+ # CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+ # CONFIG_SCSI_PCI2000 is not set
+ # CONFIG_SCSI_PCI2220I 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_SIM710 is not set
++# CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+-# CONFIG_SCSI_U14_34F is not set
+ # CONFIG_SCSI_NSP32 is not set
+ # CONFIG_SCSI_DEBUG is not set
+@@ -374,7 +375,6 @@
+ # CONFIG_SERIO_CT82C710 is not set
+ # CONFIG_SERIO_PARKBD is not set
+ CONFIG_HP_SDC=y
+-CONFIG_HIL_MLC=y
+ #
+ # Input Device Drivers
+Index: linux-2.6.0-test5/arch/parisc/hpux/fs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/hpux/fs.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/hpux/fs.c    2003-09-27 11:38:19.697533904 +0800
+@@ -123,14 +123,19 @@
+ {
+       struct hpux_stat64 tmp;
++      /* we probably want a different split here - is hpux 12:20? */
++
++      if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++
+       memset(&tmp, 0, sizeof(tmp));
+-      tmp.st_dev = stat->dev;
++      tmp.st_dev = new_encode_dev(stat->dev);
+       tmp.st_ino = stat->ino;
+       tmp.st_mode = stat->mode;
+       tmp.st_nlink = stat->nlink;
+       tmp.st_uid = stat->uid;
+       tmp.st_gid = stat->gid;
+-      tmp.st_rdev = stat->rdev;
++      tmp.st_rdev = new_encode_dev(stat->rdev);
+       tmp.st_size = stat->size;
+       tmp.st_atime = stat->atime.tv_sec;
+       tmp.st_mtime = stat->mtime.tv_sec;
+Index: linux-2.6.0-test5/arch/parisc/hpux/sys_hpux.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/hpux/sys_hpux.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/hpux/sys_hpux.c      2003-09-27 11:38:19.704532840 +0800
+@@ -272,7 +272,7 @@
+               break ;
+       case 2:
+               /*  ustat():  */
+-              return( hpux_ustat((dev_t)n, (struct hpux_ustat *)ubuf) );
++              return( hpux_ustat(new_decode_dev(n), (struct hpux_ustat *)ubuf) );
+               break ;
+       case 3:
+               /*  setuname():
+Index: linux-2.6.0-test5/arch/parisc/hpux/wrappers.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/hpux/wrappers.S 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/hpux/wrappers.S      2003-09-27 11:38:19.707532384 +0800
+@@ -21,17 +21,20 @@
+  */
+ #ifdef __LP64__
+-#warning Must be changed for PA64
++#warning PA64 support needs more work...did first cut
+ #endif
+ #include <asm/offsets.h>
++#include <asm/assembly.h>
++#include <asm/signal.h>
++#ifdef __LP64__
++      .level          2.0w
++#else
+       .level          1.1
++#endif
+       .text
+-#include <asm/assembly.h>
+-#include <asm/signal.h>
+-
+       /* These should probably go in a header file somewhere.
+        * They are duplicated in kernel/wrappers.S
+        * Possibly we should consider consolidating these
+@@ -41,41 +44,41 @@
+ #ifdef __LP64__
+ #warning NEEDS WORK for 64-bit
+ #endif
+-      stw     %r3, PT_GR3(\regs)
+-      stw     %r4, PT_GR4(\regs)
+-      stw     %r5, PT_GR5(\regs)
+-      stw     %r6, PT_GR6(\regs)
+-      stw     %r7, PT_GR7(\regs)
+-      stw     %r8, PT_GR8(\regs)
+-      stw     %r9, PT_GR9(\regs)
+-      stw    %r10,PT_GR10(\regs)
+-      stw    %r11,PT_GR11(\regs)
+-      stw    %r12,PT_GR12(\regs)
+-      stw    %r13,PT_GR13(\regs)
+-      stw    %r14,PT_GR14(\regs)
+-      stw    %r15,PT_GR15(\regs)
+-      stw    %r16,PT_GR16(\regs)
+-      stw    %r17,PT_GR17(\regs)
+-      stw    %r18,PT_GR18(\regs)
++      STREG   %r3, PT_GR3(\regs)
++      STREG   %r4, PT_GR4(\regs)
++      STREG   %r5, PT_GR5(\regs)
++      STREG   %r6, PT_GR6(\regs)
++      STREG   %r7, PT_GR7(\regs)
++      STREG   %r8, PT_GR8(\regs)
++      STREG   %r9, PT_GR9(\regs)
++      STREG   %r10,PT_GR10(\regs)
++      STREG   %r11,PT_GR11(\regs)
++      STREG   %r12,PT_GR12(\regs)
++      STREG   %r13,PT_GR13(\regs)
++      STREG   %r14,PT_GR14(\regs)
++      STREG   %r15,PT_GR15(\regs)
++      STREG   %r16,PT_GR16(\regs)
++      STREG   %r17,PT_GR17(\regs)
++      STREG   %r18,PT_GR18(\regs)
+       .endm
+       .macro  reg_restore regs
+-      ldw     PT_GR3(\regs), %r3
+-      ldw     PT_GR4(\regs), %r4
+-      ldw     PT_GR5(\regs), %r5
+-      ldw     PT_GR6(\regs), %r6
+-      ldw     PT_GR7(\regs), %r7
+-      ldw     PT_GR8(\regs), %r8
+-      ldw     PT_GR9(\regs), %r9
+-      ldw    PT_GR10(\regs),%r10
+-      ldw    PT_GR11(\regs),%r11
+-      ldw    PT_GR12(\regs),%r12
+-      ldw    PT_GR13(\regs),%r13
+-      ldw    PT_GR14(\regs),%r14
+-      ldw    PT_GR15(\regs),%r15
+-      ldw    PT_GR16(\regs),%r16
+-      ldw    PT_GR17(\regs),%r17
+-      ldw    PT_GR18(\regs),%r18
++      LDREG   PT_GR3(\regs), %r3
++      LDREG   PT_GR4(\regs), %r4
++      LDREG   PT_GR5(\regs), %r5
++      LDREG   PT_GR6(\regs), %r6
++      LDREG   PT_GR7(\regs), %r7
++      LDREG   PT_GR8(\regs), %r8
++      LDREG   PT_GR9(\regs), %r9
++      LDREG   PT_GR10(\regs),%r10
++      LDREG   PT_GR11(\regs),%r11
++      LDREG   PT_GR12(\regs),%r12
++      LDREG   PT_GR13(\regs),%r13
++      LDREG   PT_GR14(\regs),%r14
++      LDREG   PT_GR15(\regs),%r15
++      LDREG   PT_GR16(\regs),%r16
++      LDREG   PT_GR17(\regs),%r17
++      LDREG   PT_GR18(\regs),%r18
+       .endm
+@@ -88,18 +91,18 @@
+                                                           ;! pointer in task
+       reg_save %r1
+-      stw     %r2,-20(%r30)
++      STREG   %r2,-20(%r30)
+       ldo     64(%r30),%r30
+-      stw     %r2,PT_GR19(%r1)        ;! save for child
+-      stw     %r30,PT_GR21(%r1)       ;! save for child
++      STREG   %r2,PT_GR19(%r1)        ;! save for child
++      STREG   %r30,PT_GR21(%r1)       ;! save for child
+-      ldw     PT_GR30(%r1),%r25
+-      mtctl   %r25,%cr29
++      LDREG   PT_GR30(%r1),%r25
++      mtctl   %r25,%cr29
+       copy    %r1,%r24
+       bl      sys_clone,%r2
+       ldi     SIGCHLD,%r26
+-      ldw -84(%r30),%r2
++      LDREG   -84(%r30),%r2
+ fork_return:
+       ldo     -64(%r30),%r30
+       ldo     TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1         ;! get pt regs
+@@ -116,14 +119,14 @@
+        * know the difference. We can fix this later if necessary.
+        */
+-      ldo -1024(%r0),%r1
++      ldo     -1024(%r0),%r1
+       comb,>>=,n %r28,%r1,fork_exit  /* just let the syscall exit handle it */
+-      or,= %r28,%r0,%r0
+-      or,tr %r0,%r0,%r29      /* r28 <> 0, we are parent, set r29 to 0 */
+-      ldo 1(%r0),%r29         /* r28 == 0, we are child,  set r29 to 1 */
++      or,=    %r28,%r0,%r0
++      or,tr   %r0,%r0,%r29    /* r28 <> 0, we are parent, set r29 to 0 */
++      ldo     1(%r0),%r29     /* r28 == 0, we are child,  set r29 to 1 */
+ fork_exit:
+-      bv %r0(%r2)
++      bv      %r0(%r2)
+       nop
+       /* Set the return value for the child */
+@@ -134,7 +137,7 @@
+       nop
+ #endif
+-      ldw TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
++      LDREG   TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
+       b fork_return
+       copy %r0,%r28
+@@ -157,17 +160,17 @@
+       /* Store arg0, arg1 and arg2 so that hpux_execve will find them */
+-      stw %r26,PT_GR26(%r1)
+-      stw %r25,PT_GR25(%r1)
+-      stw %r24,PT_GR24(%r1)
++      STREG %r26,PT_GR26(%r1)
++      STREG %r25,PT_GR25(%r1)
++      STREG %r24,PT_GR24(%r1)
+-      stw %r2,-20(%r30)
++      STREG %r2,-20(%r30)
+       ldo 64(%r30),%r30
+       bl hpux_execve,%r2
+       copy %r1,%arg0
+       ldo -64(%r30),%r30
+-      ldw -20(%r30),%r2
++      LDREG   -20(%r30),%r2
+       /* If exec succeeded we need to load the args */
+@@ -175,10 +178,10 @@
+       comb,>>= %r28,%r1,exec_error
+       copy %r2,%r19
+       ldo     -TASK_SZ_ALGN-64(%r30),%r1         ;! get task ptr
+-      ldw TASK_PT_GR26(%r1),%r26
+-      ldw TASK_PT_GR25(%r1),%r25
+-      ldw TASK_PT_GR24(%r1),%r24
+-      ldw TASK_PT_GR23(%r1),%r23
++      LDREG   TASK_PT_GR26(%r1),%r26
++      LDREG   TASK_PT_GR25(%r1),%r25
++      LDREG   TASK_PT_GR24(%r1),%r24
++      LDREG   TASK_PT_GR23(%r1),%r23
+       copy %r0,%r2    /* Flag to syscall_exit not to clear args */
+ exec_error:
+@@ -191,7 +194,7 @@
+       /* HP-UX expects pipefd's returned in r28 & r29 */
+ hpux_pipe_wrapper:
+-      stw %r2,-20(%r30)
++      STREG %r2,-20(%r30)
+       ldo 64(%r30),%r30
+       bl hpux_pipe,%r2
+       ldo -56(%r30),%r26 /* pass local array to hpux_pipe */
+@@ -199,12 +202,12 @@
+       ldo -1024(%r0),%r1
+       comb,>>= %r28,%r1,pipe_exit /* let syscall exit handle it */
+-      ldw -84(%r30),%r2
++      LDREG   -84(%r30),%r2
+       /* if success, load fd's from stack array */
+-      ldw -56(%r30),%r28
+-      ldw -52(%r30),%r29
++      LDREG   -56(%r30),%r28
++      LDREG   -52(%r30),%r29
+ pipe_exit:
+       bv %r0(%r2)
+@@ -251,4 +254,4 @@
+ hpux_unimplemented_wrapper:
+       b hpux_unimplemented
+-      stw %r22,-64(%r30)  /* overwrite arg8 with syscall number */
++      STREG %r22,-64(%r30)  /* overwrite arg8 with syscall number */
+Index: linux-2.6.0-test5/arch/parisc/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/Kconfig      2003-09-27 11:38:19.709532080 +0800
+@@ -184,7 +184,7 @@
+ source "drivers/md/Kconfig"
+-#source drivers/message/fusion/Kconfig
++source drivers/message/fusion/Kconfig
+ #source drivers/ieee1394/Kconfig
+Index: linux-2.6.0-test5/arch/parisc/kernel/cache.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/cache.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/cache.c       2003-09-27 11:38:19.712531624 +0800
+@@ -232,7 +232,8 @@
+       if (!page->mapping)
+               return;
+-
++      /* check shared list first if it's not empty...it's usually
++       * the shortest */
+       list_for_each(l, &page->mapping->i_mmap_shared) {
+               struct vm_area_struct *mpnt;
+               unsigned long off;
+@@ -257,6 +258,33 @@
+               /* All user shared mappings should be equivalently mapped,
+                * so once we've flushed one we should be ok
+                */
++              return;
++      }
++
++      /* then check private mapping list for read only shared mappings
++       * which are flagged by VM_MAYSHARE */
++      list_for_each(l, &page->mapping->i_mmap) {
++              struct vm_area_struct *mpnt;
++              unsigned long off;
++
++              mpnt = list_entry(l, struct vm_area_struct, shared);
++
++
++              if (mpnt->vm_mm != mm || !(mpnt->vm_flags & VM_MAYSHARE))
++                      continue;
++
++              if (page->index < mpnt->vm_pgoff)
++                      continue;
++
++              off = page->index - mpnt->vm_pgoff;
++              if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
++                      continue;
++
++              flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
++
++              /* All user shared mappings should be equivalently mapped,
++               * so once we've flushed one we should be ok
++               */
+               break;
+       }
+ }
+Index: linux-2.6.0-test5/arch/parisc/kernel/drivers.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/drivers.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/drivers.c     2003-09-27 11:38:19.717530864 +0800
+@@ -447,7 +447,7 @@
+ #define MAX_NATIVE_DEVICES 64
+ #define NATIVE_DEVICE_OFFSET 0x1000
+-#define FLEX_MASK     (unsigned long)0xfffffffffffc0000
++#define FLEX_MASK     F_EXTEND(0xfffc0000)
+ #define IO_IO_LOW     offsetof(struct bc_module, io_io_low)
+ #define IO_IO_HIGH    offsetof(struct bc_module, io_io_high)
+ #define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_LOW)
+@@ -514,7 +514,7 @@
+       } while(!devices_found && hpa < io_io_high);
+ }
+-#define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000
++#define CENTRAL_BUS_ADDR F_EXTEND(0xfff80000)
+ /**
+  * walk_central_bus - Find devices attached to the central bus
+Index: linux-2.6.0-test5/arch/parisc/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/irq.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/irq.c 2003-09-27 11:38:19.723529952 +0800
+@@ -22,7 +22,7 @@
+  */
+ #include <linux/bitops.h>
+ #include <linux/config.h>
+-#include <asm/pdc.h>
++#include <linux/eisa.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/signal.h>
+@@ -39,6 +39,7 @@
+ #include <linux/spinlock.h>
+ #include <asm/cache.h>
++#include <asm/pdc.h>
+ #undef DEBUG_IRQ
+ #undef PARISC_IRQ_CR16_COUNTS
+@@ -842,6 +843,10 @@
+       return irq_found;
+ }
++unsigned int probe_irq_mask(unsigned long irqs)
++{
++      return 0;
++}
+ void __init init_IRQ(void)
+ {
+Index: linux-2.6.0-test5/arch/parisc/kernel/module.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/module.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/module.c      2003-09-27 11:38:19.729529040 +0800
+@@ -41,6 +41,13 @@
+               return -ENOEXEC;                        \
+       }
++/* Maximum number of GOT entries. We use a long displacement ldd from
++ * the bottom of the table, which has a maximum signed displacement of
++ * 0x3fff; however, since we're only going forward, this becomes
++ * 0x1fff, and thus, since each GOT entry is 8 bytes long we can have
++ * at most 1023 entries */
++#define MAX_GOTS      1023
++
+ /* three functions to determine where in the module core
+  * or init pieces the location is */
+ static inline int is_init(struct module *me, void *loc)
+@@ -300,11 +307,14 @@
+       got = me->module_core + me->arch.got_offset;
+       for (i = 0; got[i].addr; i++)
+               if (got[i].addr == value)
+-                      return i * sizeof(struct got_entry);
++                      goto out;
+       BUG_ON(++me->arch.got_count > me->arch.got_max);
+       got[i].addr = value;
++ out:
++      DEBUGP("GOT ENTRY %d[%x] val %lx\n", i, i*sizeof(struct got_entry),
++             value);
+       return i * sizeof(struct got_entry);
+ }
+ #endif /* __LP64__ */
+@@ -387,7 +397,7 @@
+               stub->insns[2] = 0xe820d000;    /* bve (%r1)            */
+               stub->insns[3] = 0x537b0030;    /* ldd 18(%dp),%dp      */
+-              stub->insns[0] |= reassemble_14(rrsel(get_got(me, value, addend),0));
++              stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff);
+       }
+       else
+       {
+@@ -516,6 +526,9 @@
+               case R_PARISC_PCREL22F:
+                       /* 22-bit PC relative address; only defined for pa20 */
+                       val = get_stub(me, val, addend, 0, is_init(me, loc));
++                      DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", 
++                             strtab + sym->st_name, (unsigned long)loc, addend, 
++                             val)
+                       val = (val - dot - 8)/4;
+                       CHECK_RELOC(val, 22);
+                       *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
+@@ -618,6 +631,9 @@
+                                       val = get_stub(me, val, addend, 0,
+                                                      is_init(me, loc));
+                       }
++                      DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", 
++                             strtab + sym->st_name, loc, sym->st_value,
++                             addend, val);
+                       /* FIXME: local symbols work as long as the
+                        * core and init pieces aren't separated too
+                        * far.  If this is ever broken, you will trip
+@@ -646,6 +662,9 @@
+                       /* 64-bit function address */
+                       if(is_local(me, (void *)(val + addend))) {
+                               *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);
+                       } else {
+                               /* if the symbol is not local to this
+                                * module then val+addend is a pointer
+@@ -711,8 +730,13 @@
+               }
+       }
+-      printk("module %s: strtab %p, symhdr %p\n",
++      DEBUGP("module %s: strtab %p, symhdr %p\n",
+              me->name, strtab, symhdr);
++
++      if(me->arch.got_count > MAX_GOTS) {
++              printk(KERN_ERR "%s: Global Offset Table overflow (used %ld, allowed %d\n", me->name, me->arch.got_count, MAX_GOTS);
++              return -EINVAL;
++      }
+       
+       /* no symbol table */
+       if(symhdr == NULL)
+Index: linux-2.6.0-test5/arch/parisc/kernel/parisc_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/parisc_ksyms.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/parisc_ksyms.c        2003-09-27 11:38:19.731528736 +0800
+@@ -37,13 +37,11 @@
+ #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);
+-#ifdef CONFIG_EISA
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+ #include <linux/pm.h>
+ EXPORT_SYMBOL(pm_power_off);
+@@ -201,6 +199,9 @@
+ EXPORT_SYMBOL(__lshrdi3);
+ EXPORT_SYMBOL(__muldi3);
++asmlinkage void * __canonicalize_funcptr_for_compare(void *);
++EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
++
+ #ifdef __LP64__
+ extern void __divdi3(void);
+ extern void __udivdi3(void);
+Index: linux-2.6.0-test5/arch/parisc/kernel/pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/pci.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/pci.c 2003-09-27 11:38:19.736527976 +0800
+@@ -10,6 +10,7 @@
+  * Copyright (C) 1999-2001 Grant Grundler
+  */
+ #include <linux/config.h>
++#include <linux/eisa.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -25,7 +26,7 @@
+ #define DEBUG_CONFIG 0
+ #if DEBUG_CONFIG
+-# define DBGC(x...)     printk(KERN_DEBUG x)
++# define DBGC(x...)   printk(KERN_DEBUG x)
+ #else
+ # define DBGC(x...)
+ #endif
+@@ -38,13 +39,15 @@
+ #endif
+ /* To be used as: mdelay(pci_post_reset_delay);
+-**
+-** post_reset is the time the kernel should stall to prevent anyone from
+-** accessing the PCI bus once #RESET is de-asserted. 
+-** PCI spec somewhere says 1 second but with multi-PCI bus systems,
+-** this makes the boot time much longer than necessary.
+-** 20ms seems to work for all the HP PCI implementations to date.
+-*/
++ *
++ * post_reset is the time the kernel should stall to prevent anyone from
++ * accessing the PCI bus once #RESET is de-asserted. 
++ * PCI spec somewhere says 1 second but with multi-PCI bus systems,
++ * this makes the boot time much longer than necessary.
++ * 20ms seems to work for all the HP PCI implementations to date.
++ *
++ * XXX: turn into a #defined constant in <asm/pci.h> ?
++ */
+ int pci_post_reset_delay = 50;
+ struct pci_port_ops *pci_port;
+@@ -52,9 +55,7 @@
+ int pci_hba_count = 0;
+-/*
+-** parisc_pci_hba used by pci_port->in/out() ops to lookup bus data.
+-*/
++/* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data.  */
+ #define PCI_HBA_MAX 32
+ struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX];
+@@ -129,8 +130,6 @@
+ /* Called from pci_do_scan_bus() *after* walking a bus but before walking PPBs. */
+ void pcibios_fixup_bus(struct pci_bus *bus)
+ {
+-      ASSERT(pci_bios != NULL);
+-
+       if (pci_bios->fixup_bus) {
+               pci_bios->fixup_bus(bus);
+       } else {
+@@ -145,64 +144,26 @@
+ }
+-/*
+-** Used in drivers/pci/quirks.c
+-*/
++/* Used in drivers/pci/quirks.c */
+ struct pci_fixup pcibios_fixups[] = { {0} };
+ /*
+-** called by drivers/pci/setup.c:pdev_fixup_irq()
+-*/
+-void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
+-{
+-/*
+-** updates IRQ_LINE cfg register to reflect PCI-PCI bridge skewing.
+-**
+-** Calling path for Alpha is:
+-**  alpha/kernel/pci.c:common_init_pci(swizzle_func, pci_map_irq_func )
+-**    drivers/pci/setup.c:pci_fixup_irqs()
+-**        drivers/pci/setup.c:pci_fixup_irq() (for each PCI device)
+-**            invoke swizzle and map functions
+-**            alpha/kernel/pci.c:pcibios_update_irq()
+-**
+-** Don't need this for PA legacy PDC systems.
+-**
+-** On PAT PDC systems, We only support one "swizzle" for any number
+-** of PCI-PCI bridges deep. That's how bit3 PCI expansion chassis
+-** are implemented. The IRQ lines are "skewed" for all devices but
+-** *NOT* routed through the PCI-PCI bridge. Ie any device "0" will
+-** share an IRQ line. Legacy PDC is expecting this IRQ line routing
+-** as well.
+-**
+-** Unfortunately, PCI spec allows the IRQ lines to be routed
+-** around the PCI bridge as long as the IRQ lines are skewed
+-** based on the device number...<sigh>...
+-**
+-** Lastly, dino.c might be able to use pci_fixup_irq() to
+-** support RS-232 and PS/2 children. Not sure how but it's
+-** something to think about.
+-*/
+-}
+-
+-
+-/*
+-** Called by pci_set_master() - a driver interface.
+-**
+-** Legacy PDC guarantees to set:
+-**      Map Memory BAR's into PA IO space.
+-**      Map Expansion ROM BAR into one common PA IO space per bus.
+-**      Map IO BAR's into PCI IO space.
+-**      Command (see below)
+-**      Cache Line Size
+-**      Latency Timer
+-**      Interrupt Line
+-**    PPB: secondary latency timer, io/mmio base/limit,
+-**            bus numbers, bridge control
+-**
+-*/
+-void
+-pcibios_set_master(struct pci_dev *dev)
++ * Called by pci_set_master() - a driver interface.
++ *
++ * Legacy PDC guarantees to set:
++ *    Map Memory BAR's into PA IO space.
++ *    Map Expansion ROM BAR into one common PA IO space per bus.
++ *    Map IO BAR's into PCI IO space.
++ *    Command (see below)
++ *    Cache Line Size
++ *    Latency Timer
++ *    Interrupt Line
++ *    PPB: secondary latency timer, io/mmio base/limit,
++ *            bus numbers, bridge control
++ *
++ */
++void pcibios_set_master(struct pci_dev *dev)
+ {
+       u8 lat;
+@@ -214,43 +175,36 @@
+       ** HP generally has fewer devices on the bus than other architectures.
+       ** upper byte is PCI_LATENCY_TIMER.
+       */
+-        pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
++      pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
+                               (0x80 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
+ }
+-void __init
+-pcibios_init_bus(struct pci_bus *bus)
++void __init pcibios_init_bus(struct pci_bus *bus)
+ {
+       struct pci_dev *dev = bus->self;
++      unsigned short bridge_ctl;
+       /* We deal only with pci controllers and pci-pci bridges. */
+-      if (dev && (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
++      if (!dev || (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+               return;
+-      
+-      if (dev) {
+-              unsigned short bridge_ctl;
+-
+-              /* PCI-PCI bridge - set the cache line and default latency
+-                 (32) for primary and secondary buses. */
+-              pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
+-
+-              /* Read bridge control */
+-              pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
+-              pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl
+-                              | PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR);
+-      }
++      /* PCI-PCI bridge - set the cache line and default latency
++         (32) for primary and secondary buses. */
++      pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
++
++      pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
++      bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
++      pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
+ }
+-/*
+-** KLUGE: Link the child and parent resources - generic PCI didn't
+-*/
++/* KLUGE: Link the child and parent resources - generic PCI didn't */
+ static void
+ pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
+ {
+       if (!r->parent) {
++              printk(KERN_EMERG "PCI: Tell willy he's wrong\n");
+               r->parent = hba_res;
+               /* reverse link is harder *sigh*  */
+@@ -268,14 +222,9 @@
+       }
+ }
+-/*
+-** called by drivers/pci/setup-res.c:pci_setup_bridge().
+-*/
+-void __devinit pcibios_resource_to_bus(
+-      struct pci_dev *dev,
+-      struct pci_bus_region *region,
+-      struct resource *res
+-      )
++/* called by drivers/pci/setup-bus.c:pci_setup_bridge().  */
++void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
++              struct pci_bus_region *region, struct resource *res)
+ {
+       struct pci_bus *bus = dev->bus;
+       struct pci_hba_data *hba = HBA_DATA(bus->dev->platform_data);
+@@ -313,17 +262,16 @@
+ #endif
+ /*
+-** pcibios align resources() is called everytime generic PCI code
+-** wants to generate a new address. The process of looking for
+-** an available address, each candidate is first "aligned" and
+-** then checked if the resource is available until a match is found.
+-**
+-** Since we are just checking candidates, don't use any fields other
+-** than res->start.
+-*/
+-void __devinit
+-pcibios_align_resource(void *data, struct resource *res,
+-                     unsigned long size, unsigned long alignment)
++ * pcibios align resources() is called every time generic PCI code
++ * wants to generate a new address. The process of looking for
++ * an available address, each candidate is first "aligned" and
++ * then checked if the resource is available until a match is found.
++ *
++ * Since we are just checking candidates, don't use any fields other
++ * than res->start.
++ */
++void pcibios_align_resource(void *data, struct resource *res,
++                              unsigned long size, unsigned long alignment)
+ {
+       unsigned long mask, align;
+@@ -332,10 +280,6 @@
+               res->parent, res->start, res->end,
+               (int) res->flags, size, alignment);
+-      /* has resource already been aligned/assigned? */
+-      if (res->parent)
+-              return;
+-
+       /* If it's not IO, then it's gotta be MEM */
+       align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
+@@ -344,32 +288,26 @@
+       res->start += mask;
+       res->start &= ~mask;
+-      /*
+-      ** WARNING : caller is expected to update "end" field.
+-      ** We can't since it might really represent the *size*.
+-      ** The difference is "end = start + size" vs "end += start".
+-      */
++      /* The caller updates the end field, we don't.  */
+ }
+-int __devinit
+-pcibios_enable_device(struct pci_dev *dev, int mask)
++/*
++ * A driver is enabling the device.  We make sure that all the appropriate
++ * bits are set to allow the device to operate as the driver is expecting.
++ * We enable the port IO and memory IO bits if the device has any BARs of
++ * that type, and we enable the PERR and SERR bits unconditionally.
++ * Drivers that do not need parity (eg graphics and possibly networking)
++ * can clear these bits if they want.
++ */
++int pcibios_enable_device(struct pci_dev *dev, int mask)
+ {
+       u16 cmd;
+       int idx;
+-      /*
+-      ** The various platform PDC's (aka "BIOS" for PCs) don't
+-      ** enable all the same bits. We just make sure they are here.
+-      */
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+-      /*
+-      ** See if any resources have been allocated
+-      ** While "regular" PCI devices only use 0-5, Bridges use a few
+-      ** beyond that for window registers.
+-      */
+-        for (idx=0; idx<DEVICE_COUNT_RESOURCE; idx++) {
++      for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
+               struct resource *r = &dev->resource[idx];
+               /* only setup requested resources */
+@@ -382,14 +320,6 @@
+                       cmd |= PCI_COMMAND_MEMORY;
+       }
+-      /*
+-      ** Enable System error and Parity Error reporting by default.
+-      ** Devices that do NOT want those behaviors should clear them
+-      ** (eg PCI graphics, possibly networking).
+-      ** Interfaces like SCSI certainly should not. We want the
+-      ** system to crash if a system or parity error is detected.
+-      ** At least until the device driver can recover from such an error.
+-      */
+       cmd |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+ #if 0
+@@ -402,30 +332,15 @@
+       return 0;
+ }
+-void __init
+-pcibios_setup_host_bridge(struct pci_bus *bus)
+-{
+-      ASSERT(pci_bios != NULL);
+-#if 0
+-      if (pci_bios)
+-      {
+-              if (pci_bios->setup_host_bridge) {
+-                      (*pci_bios->setup_host_bridge)(bus);
+-              }
+-      }
+-#endif
+-}
+-
+-
+-/*
+-** PARISC specific (unfortunately)
+-*/
++/* PA-RISC specific */
+ void pcibios_register_hba(struct pci_hba_data *hba)
+ {
+-      ASSERT(pci_hba_count < PCI_HBA_MAX);
++      if (pci_hba_count >= PCI_HBA_MAX) {
++              printk(KERN_ERR "PCI: Too many Host Bus Adapters\n");
++              return;
++      }
+-      /* pci_port->in/out() uses parisc_pci_hba to lookup parameter. */
+       parisc_pci_hba[pci_hba_count] = hba;
+       hba->hba_num = pci_hba_count++;
+ }
+Index: linux-2.6.0-test5/arch/parisc/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/process.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/process.c     2003-09-27 11:38:19.738527672 +0800
+@@ -19,7 +19,6 @@
+ #include <linux/sched.h>
+ #include <linux/stddef.h>
+ #include <linux/unistd.h>
+-#include <linux/version.h>
+ #include <asm/io.h>
+ #include <asm/offsets.h>
+Index: linux-2.6.0-test5/arch/parisc/kernel/real2.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/real2.S  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/real2.S       2003-09-27 11:38:19.740527368 +0800
+@@ -123,7 +123,7 @@
+       nop
+ restore_control_regs:
+-      load32  PA(save_cr_space + (N_SAVED_REGS * REG_SZ)), %r26
++      load32  PA(save_cr_space+(N_SAVED_REGS*REG_SZ)), %r26
+       POP_CR(%cr15, %r26)
+       POP_CR(%cr31, %r26)
+       POP_CR(%cr30, %r26)
+@@ -275,6 +275,7 @@
+       nop
+ #endif
++
+       .export pc_in_user_space
+       .text
+       /* Doesn't belong here but I couldn't find a nicer spot. */
+@@ -283,3 +284,17 @@
+       bv,n    0(%rp)
+       nop
++
++      .export __canonicalize_funcptr_for_compare
++      .text
++      /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
++      **      GCC 3.3 and later has a new function in libgcc.a for
++      **      comparing function pointers.
++      */
++__canonicalize_funcptr_for_compare:
++#ifdef __LP64__
++      bve (%r2)
++#else
++      bv %r0(%r2)
++#endif
++      copy %r26,%r28
+Index: linux-2.6.0-test5/arch/parisc/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/setup.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/setup.c       2003-09-27 11:38:19.744526760 +0800
+@@ -52,10 +52,6 @@
+ struct proc_dir_entry * proc_runway_root = NULL;
+ struct proc_dir_entry * proc_gsc_root = NULL;
+-#ifdef CONFIG_EISA
+-int EISA_bus; /* This has to go somewhere in architecture specific code. */
+-#endif
+-
+ void __init setup_cmdline(char **cmdline_p)
+ {
+       extern unsigned int boot_args[];
+Index: linux-2.6.0-test5/arch/parisc/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/signal.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/signal.c      2003-09-27 11:38:19.748526152 +0800
+@@ -13,7 +13,6 @@
+  *  arch/parisc/hpux/signal.c when we figure out how to do them.
+  */
+-#include <linux/version.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+ #include <linux/smp.h>
+@@ -458,6 +457,8 @@
+               if (in_syscall) {
+                       /* Check the return code */
+                       switch (regs->gr[28]) {
++                      case -ERESTART_RESTARTBLOCK:
++                              current_thread_info()->restart_block.fn = do_no_restart_syscall;
+                       case -ERESTARTNOHAND:
+                               DBG(("ERESTARTNOHAND: returning -EINTR\n"));
+                               regs->gr[28] = -EINTR;
+@@ -495,7 +496,8 @@
+       /* Did we come from a system call? */
+       if (in_syscall) {
+               /* Restart the system call - no handlers present */
+-              if (regs->gr[28] == -ERESTARTNOHAND ||
++              if (regs->gr[28] == -ERESTART_RESTARTBLOCK ||
++                  regs->gr[28] == -ERESTARTNOHAND ||
+                   regs->gr[28] == -ERESTARTSYS ||
+                   regs->gr[28] == -ERESTARTNOINTR) {
+                       /* Hooray for delayed branching.  We don't
+Index: linux-2.6.0-test5/arch/parisc/kernel/syscall.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/syscall.S        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/syscall.S     2003-09-27 11:38:19.753525392 +0800
+@@ -483,7 +483,7 @@
+       ENTRY_SAME(madvise)
+       ENTRY_SAME(clone_wrapper)       /* 120 */
+       ENTRY_SAME(setdomainname)
+-      ENTRY_SAME(sendfile)
++      ENTRY_DIFF(sendfile)
+       /* struct sockaddr... */
+       ENTRY_SAME(recvfrom)
+       /* struct timex contains longs */
+@@ -592,7 +592,7 @@
+       ENTRY_SAME(ni_syscall)
+       ENTRY_SAME(ni_syscall)          /* 205 */
+       ENTRY_SAME(gettid)             
+-      ENTRY_SAME(readahead)          
++      ENTRY_OURS(readahead)          
+       ENTRY_SAME(ni_syscall)          /* tkill */
+       ENTRY_SAME(sendfile64)
+Index: linux-2.6.0-test5/arch/parisc/kernel/sys_parisc32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/sys_parisc32.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/sys_parisc32.c        2003-09-27 11:38:19.762524024 +0800
+@@ -46,6 +46,7 @@
+ #include <linux/namei.h>
+ #include <linux/vfs.h>
+ #include <linux/ptrace.h>
++#include <linux/swap.h>
+ #include <asm/types.h>
+ #include <asm/uaccess.h>
+@@ -373,18 +374,16 @@
+       return copy_to_user(u, &t32, sizeof t32);
+ }
+-static int
+-get_compat_timeval(struct compat_timeval *u, struct timeval *t)
++static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+ {
+-      int err;
+-      struct compat_timeval t32;
++      long usec;
+-      if ((err = copy_from_user(&t32, u, sizeof t32)) == 0)
+-      {
+-          t->tv_sec = t32.tv_sec;
+-          t->tv_usec = t32.tv_usec;
+-      }
+-      return err;
++      if (__get_user(o->tv_sec, &i->tv_sec))
++              return -EFAULT;
++      if (__get_user(usec, &i->tv_usec))
++              return -EFAULT;
++      o->tv_nsec = usec * 1000;
++      return 0;
+ }
+ asmlinkage long sys32_time(compat_time_t *tloc)
+@@ -418,39 +417,39 @@
+     return 0;
+ }
+-asmlinkage int
+-sys32_settimeofday(struct compat_timespec *tv, struct timezone *tz)
++asmlinkage 
++int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+ {
+-    struct timeval ktv;
+-    struct timezone ktz;
+-    extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
++      struct timespec kts;
++      struct timezone ktz;
+-    if (tv) {
+-          if (get_compat_timeval(tv, &ktv))
+-                  return -EFAULT;
+-    }
+-    if (tz) {
+-          if (copy_from_user(&ktz, tz, sizeof(ktz)))
+-                  return -EFAULT;
+-    }
++      if (tv) {
++              if (get_ts32(&kts, tv))
++                      return -EFAULT;
++      }
++      if (tz) {
++              if (copy_from_user(&ktz, tz, sizeof(ktz)))
++                      return -EFAULT;
++      }
+-    return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
++      return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+ }
+ int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+ {
+       int err;
+-      if (stat->size > MAX_NON_LFS)
++      if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
++          !new_valid_dev(stat->rdev))
+               return -EOVERFLOW;
+-      err  = put_user(stat->dev, &statbuf->st_dev);
++      err  = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
+       err |= put_user(stat->ino, &statbuf->st_ino);
+       err |= put_user(stat->mode, &statbuf->st_mode);
+       err |= put_user(stat->nlink, &statbuf->st_nlink);
+       err |= put_user(0, &statbuf->st_reserved1);
+       err |= put_user(0, &statbuf->st_reserved2);
+-      err |= put_user(stat->rdev, &statbuf->st_rdev);
++      err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
+       err |= put_user(stat->size, &statbuf->st_size);
+       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+       err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+@@ -1089,6 +1088,27 @@
+       return err;
+ }
++
++extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
++asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count)
++{
++        mm_segment_t old_fs = get_fs();
++        int ret;
++        off_t of;
++
++        if (offset && get_user(of, offset))
++                return -EFAULT;
++
++        set_fs(KERNEL_DS);
++        ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
++        set_fs(old_fs);
++
++        if (offset && put_user(of, offset))
++                return -EFAULT;
++
++        return ret;
++}
++
+ /* EXPORT/UNEXPORT */
+ struct nfsctl_export32 {
+       char            ex_client[NFSCLNT_IDMAX+1];
+Index: linux-2.6.0-test5/arch/parisc/kernel/sys_parisc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/sys_parisc.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/sys_parisc.c  2003-09-27 11:38:19.766523416 +0800
+@@ -30,8 +30,6 @@
+ {
+       struct vm_area_struct *vma;
+-      if (!addr)
+-              addr = TASK_UNMAPPED_BASE;
+       addr = PAGE_ALIGN(addr);
+       for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+@@ -46,17 +44,38 @@
+ #define DCACHE_ALIGN(addr) (((addr) + (SHMLBA - 1)) &~ (SHMLBA - 1))
+-static unsigned long get_shared_area(struct inode *inode, unsigned long addr,
+-              unsigned long len, unsigned long pgoff)
++/*
++ * We need to know the offset to use.  Old scheme was to look for
++ * existing mapping and use the same offset.  New scheme is to use the
++ * address of the kernel data structure as the seed for the offset.
++ * We'll see how that works...
++ */
++#if 0
++static int get_offset(struct address_space *mapping)
++{
++      struct vm_area_struct *vma = list_entry(mapping->i_mmap_shared.next,
++                      struct vm_area_struct, shared);
++      return (vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT)) &
++              (SHMLBA - 1);
++}
++#else
++/* The mapping is cacheline aligned, so there's no information in the bottom
++ * few bits of the address.  We're looking for 10 bits (4MB / 4k), so let's
++ * drop the bottom 8 bits and use bits 8-17.  
++ */
++static int get_offset(struct address_space *mapping)
+ {
+-      struct vm_area_struct *vma, *first_vma;
+-      int offset;
++      int offset = (int) mapping << (PAGE_SHIFT - 8);
++      return offset & 0x3FF000;
++}
++#endif
+-      first_vma = list_entry(inode->i_mapping->i_mmap_shared.next, struct vm_area_struct, shared);
+-      offset = (first_vma->vm_start + ((pgoff - first_vma->vm_pgoff) << PAGE_SHIFT)) & (SHMLBA - 1);
++static unsigned long get_shared_area(struct address_space *mapping,
++              unsigned long addr, unsigned long len, unsigned long pgoff)
++{
++      struct vm_area_struct *vma;
++      int offset = get_offset(mapping);
+-      if (!addr)
+-              addr = TASK_UNMAPPED_BASE;
+       addr = DCACHE_ALIGN(addr - offset) + offset;
+       for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+@@ -74,17 +93,17 @@
+ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+               unsigned long len, unsigned long pgoff, unsigned long flags)
+ {
+-      struct inode *inode = NULL;
++      struct inode *inode;
+       if (len > TASK_SIZE)
+               return -ENOMEM;
++      if (!addr)
++              addr = TASK_UNMAPPED_BASE;
+-      if (filp) {
+-              inode = filp->f_dentry->d_inode;
+-      }
++      inode = filp ? filp->f_dentry->d_inode : NULL;
+-      if (inode && (flags & MAP_SHARED) && (!list_empty(&inode->i_mapping->i_mmap_shared))) {
+-              addr = get_shared_area(inode, addr, len, pgoff);
++      if (inode && (flags & MAP_SHARED)) {
++              addr = get_shared_area(inode->i_mapping, addr, len, pgoff);
+       } else {
+               addr = get_unshared_area(addr, len);
+       }
+@@ -185,6 +204,7 @@
+                                       size_t count, loff_t pos);
+ extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char *buf,
+                                       size_t count, loff_t pos);
++extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
+ asmlinkage ssize_t parisc_pread64(unsigned int fd, char *buf, size_t count,
+                                       unsigned int high, unsigned int low)
+@@ -198,6 +218,11 @@
+       return sys_pwrite64(fd, buf, count, (loff_t)high << 32 | low);
+ }
++asmlinkage ssize_t parisc_readahead(int fd, unsigned int high, unsigned int low,
++                                  size_t count)
++{
++      return sys_readahead(fd, (loff_t)high << 32 | low, count);
++}
+ /*
+  * FIXME, please remove this crap as soon as possible
+@@ -271,7 +296,7 @@
+       tbuf.shm_cpid = sbuf->shm_cpid;
+       tbuf.shm_lpid = sbuf->shm_lpid;
+       tbuf.shm_nattch = sbuf->shm_nattch;
+-      return copy_to_user(buf, &tbuf, sizeof tbuf);
++      return copy_to_user(buf, &tbuf, sizeof tbuf) ? -EFAULT : 0;
+ }
+ int sys_msgctl_broken(int msqid, int cmd, struct msqid_ds *buf)
+Index: linux-2.6.0-test5/arch/parisc/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/traps.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/traps.c       2003-09-27 11:38:19.771522656 +0800
+@@ -221,6 +221,8 @@
+               return;
+       }
++      oops_in_progress = 1;
++
+       /* Amuse the user in a SPARC fashion */
+       printk(
+ "      _______________________________ \n"
+@@ -414,6 +416,8 @@
+ {
+       static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED;
++      oops_in_progress = 1;
++
+       set_eiem(0);
+       local_irq_disable();
+       spin_lock(&terminate_lock);
+Index: linux-2.6.0-test5/arch/parisc/kernel/vmlinux.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/kernel/vmlinux.lds.S    2003-09-27 11:38:18.438725272 +0800
++++ linux-2.6.0-test5/arch/parisc/kernel/vmlinux.lds.S 2003-09-27 11:38:19.772522504 +0800
+@@ -0,0 +1,125 @@
++#include <linux/config.h>
++#include <asm-generic/vmlinux.lds.h>
++      
++/* ld script to make hppa Linux kernel */
++#ifndef CONFIG_PARISC64
++OUTPUT_FORMAT("elf32-hppa-linux")
++OUTPUT_ARCH(hppa)
++#else
++OUTPUT_FORMAT("elf64-hppa-linux")
++OUTPUT_ARCH(hppa:hppa2.0w)
++#endif
++
++ENTRY(_stext)
++#ifndef CONFIG_PARISC64
++jiffies = jiffies_64 + 4;
++#else
++jiffies = jiffies_64;
++#endif
++SECTIONS
++{
++
++  . = 0x10100000;
++
++  _text = .;                  /* Text and read-only data */
++  .text BLOCK(16) : {
++      *(.text*)
++      *(.PARISC.unwind)
++      *(.fixup)
++      *(.lock.text)           /* out-of-line lock text */
++      *(.gnu.warning)
++      } = 0
++
++  _etext = .;                 /* End of text section */
++
++  . = ALIGN(16);              /* Exception table */
++  __start___ex_table = .;
++  __ex_table : { *(__ex_table) }
++  __stop___ex_table = .;
++
++  RODATA
++
++  .data BLOCK(8192) : {                       /* Data without special */
++      data_start = .;
++      *(.data)
++      }
++
++#ifdef CONFIG_PARISC64
++  . = ALIGN(16);               /* Linkage tables */
++  .opd : { *(.opd) } PROVIDE (__gp = .); 
++  .plt : { *(.plt) } 
++  .dlt : { *(.dlt) }
++#endif
++
++  . = ALIGN(16384);
++  __init_begin = .;
++  .init.text : { 
++      _sinittext = .;
++      *(.init.text)
++      _einittext = .;
++  }
++  .init.data : { *(.init.data) }
++  . = ALIGN(16);
++  __setup_start = .;
++  .init.setup : { *(.init.setup) }
++  __setup_end = .;
++  __start___param =.; 
++  __param : { *(__param) }
++  __stop___param = .;
++  __initcall_start = .;
++  .initcall.init : {
++      *(.initcall1.init) 
++      *(.initcall2.init) 
++      *(.initcall3.init) 
++      *(.initcall4.init) 
++      *(.initcall5.init) 
++      *(.initcall6.init) 
++      *(.initcall7.init)
++  }
++  __initcall_end = .;
++  __con_initcall_start = .;
++  .con_initcall.init : { *(.con_initcall.init) }
++  __con_initcall_end = .;
++  SECURITY_INIT
++  . = ALIGN(4096);
++  __initramfs_start = .;
++  .init.ramfs : { *(.init.ramfs) }
++  __initramfs_end = .;
++  . = ALIGN(32);
++  __per_cpu_start = .;
++  .data.percpu  : { *(.data.percpu) }
++  __per_cpu_end = .;
++  . = ALIGN(4096);
++  __init_end = .;
++
++  init_task BLOCK(16384) : { *(init_task) }  /* The initial task and kernel stack */
++
++  _edata = .;                 /* End of data section */
++
++
++  .bss : { *(.bss) *(COMMON) }                /* BSS */
++
++
++  _end = . ;
++
++  /* Stabs debugging sections.  */
++  .stab 0 : { *(.stab) }
++  .stabstr 0 : { *(.stabstr) }
++  .stab.excl 0 : { *(.stab.excl) }
++  .stab.exclstr 0 : { *(.stab.exclstr) }
++  .stab.index 0 : { *(.stab.index) }
++  .stab.indexstr 0 : { *(.stab.indexstr) }
++  .comment 0 : { *(.comment) }
++  .note 0 : { *(.note) }      
++
++#ifdef CONFIG_PARISC64
++  /* temporary hack until binutils is fixed to not emit these
++     for static binaries */
++  /DISCARD/ : {
++    *(.dynsym)
++    *(.dynstr)
++    *(.dynamic)
++    *(.hash)
++  }
++#endif
++}
+Index: linux-2.6.0-test5/arch/parisc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/Makefile        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/Makefile     2003-09-27 11:38:19.773522352 +0800
+@@ -16,7 +16,7 @@
+ # Modified for PA-RISC Linux by Paul Lahaie, Alex deVries, 
+ # Mike Shaver, Helge Deller and Martin K. Petersen
+ #
+-
++NM            = sh arch/parisc/nm
+ ifdef CONFIG_PARISC64
+ CROSS_COMPILE := hppa64-linux-
+ UTS_MACHINE   := parisc64
+Index: linux-2.6.0-test5/arch/parisc/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/mm/ioremap.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/parisc/mm/ioremap.c 2003-09-27 11:38:19.775522048 +0800
+@@ -159,7 +159,7 @@
+       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;
+       }
+Index: linux-2.6.0-test5/arch/parisc/nm
+===================================================================
+--- linux-2.6.0-test5.orig/arch/parisc/nm      2003-09-27 11:38:18.438725272 +0800
++++ linux-2.6.0-test5/arch/parisc/nm   2003-09-27 11:38:19.776521896 +0800
+@@ -0,0 +1,6 @@
++#!/bin/sh
++##
++# Hack to have an nm which removes the local symbols.  We also rely
++# on this nm being hidden out of the ordinarily executable path
++##
++${CROSS_COMPILE}nm $* | grep -v '.LC*[0-9]*$'
+Index: linux-2.6.0-test5/arch/ppc64/boot/install.sh
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/boot/install.sh  2003-09-27 11:38:18.438725272 +0800
++++ linux-2.6.0-test5/arch/ppc64/boot/install.sh       2003-09-27 11:38:19.776521896 +0800
+@@ -0,0 +1,41 @@
++#!/bin/sh
++#
++# arch/ppc64/boot/install.sh
++#
++# 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) 1995 by Linus Torvalds
++#
++# Blatantly stolen from in arch/i386/boot/install.sh by Dave Hansen 
++#
++# "make install" script for ppc64 architecture
++#
++# Arguments:
++#   $1 - kernel version
++#   $2 - kernel image file
++#   $3 - kernel map file
++#   $4 - default install path (blank if root directory)
++#
++
++# User may have a custom install script
++
++if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
++if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
++
++# Default install
++
++# this should work for both the pSeries zImage and the iSeries vmlinux.sm
++image_name=`basename $2`
++
++if [ -f $4/$image_name ]; then
++      mv $4/$image_name $4/$image_name.old
++fi
++
++if [ -f $4/System.map ]; then
++      mv $4/System.map $4/System.old
++fi
++
++cat $2 > $4/$image_name
++cp $3 $4/System.map
+Index: linux-2.6.0-test5/arch/ppc64/boot/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/boot/Makefile    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/boot/Makefile 2003-09-27 11:38:19.779521440 +0800
+@@ -122,5 +122,7 @@
+       awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \
+               >> $(obj)/imagesize.c
++install: $(CONFIGURE) $(obj)/$(BOOTIMAGE)
++      sh -x $(src)/install.sh "$(KERNELRELEASE)" "$(obj)/$(BOOTIMAGE)" "$(TOPDIR)/System.map" "$(INSTALL_PATH)"
+ clean-files := $(patsubst $(obj)/%,%, $(obj-boot))
+Index: linux-2.6.0-test5/arch/ppc64/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/defconfig        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/defconfig     2003-09-27 11:38:19.783520832 +0800
+@@ -8,11 +8,13 @@
+ CONFIG_EARLY_PRINTK=y
+ CONFIG_COMPAT=y
+ CONFIG_FRAME_POINTER=y
++CONFIG_FORCE_MAX_ZONEORDER=13
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
++# CONFIG_BROKEN is not set
+ #
+ # General setup
+@@ -21,11 +23,14 @@
+ CONFIG_SYSVIPC=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+-CONFIG_LOG_BUF_SHIFT=15
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
+ # 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
+@@ -72,7 +77,6 @@
+ #
+ # Generic Driver Options
+ #
+-# CONFIG_FW_LOADER is not set
+ #
+ # Memory Technology Devices (MTD)
+@@ -99,7 +103,7 @@
+ # CONFIG_BLK_DEV_UMEM is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+-CONFIG_BLK_DEV_NBD=y
++CONFIG_BLK_DEV_NBD=m
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ CONFIG_BLK_DEV_INITRD=y
+@@ -127,9 +131,9 @@
+ #
+ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ #
+-# CONFIG_SCSI_MULTI_LUN is not set
+-# CONFIG_SCSI_REPORT_LUNS is not set
+-# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_MULTI_LUN=y
++CONFIG_SCSI_REPORT_LUNS=y
++CONFIG_SCSI_CONSTANTS=y
+ # CONFIG_SCSI_LOGGING is not set
+ #
+@@ -178,7 +182,8 @@
+ CONFIG_MD_RAID1=y
+ CONFIG_MD_RAID5=y
+ # CONFIG_MD_MULTIPATH is not set
+-# CONFIG_BLK_DEV_DM is not set
++CONFIG_BLK_DEV_DM=y
++CONFIG_DM_IOCTL_V4=y
+ #
+ # Fusion MPT device support
+@@ -206,9 +211,8 @@
+ CONFIG_PACKET=y
+ # CONFIG_PACKET_MMAP is not set
+ # CONFIG_NETLINK_DEV is not set
+-# CONFIG_NETFILTER is not set
+ CONFIG_UNIX=y
+-# CONFIG_NET_KEY is not set
++CONFIG_NET_KEY=m
+ CONFIG_INET=y
+ CONFIG_IP_MULTICAST=y
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+@@ -217,13 +221,17 @@
+ # CONFIG_NET_IPGRE is not set
+ # CONFIG_IP_MROUTE is not set
+ # CONFIG_ARPD is not set
+-# CONFIG_INET_ECN is not set
++CONFIG_INET_ECN=y
+ CONFIG_SYN_COOKIES=y
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
++CONFIG_INET_AH=m
++CONFIG_INET_ESP=m
++CONFIG_INET_IPCOMP=m
+ # CONFIG_IPV6 is not set
+-# CONFIG_XFRM_USER is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NETFILTER is not set
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -233,8 +241,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
+@@ -258,10 +264,10 @@
+ # ARCnet devices
+ #
+ # CONFIG_ARCNET is not set
+-# CONFIG_DUMMY is not set
+-# CONFIG_BONDING is not set
++CONFIG_DUMMY=m
++CONFIG_BONDING=m
+ # CONFIG_EQUALIZER is not set
+-# CONFIG_TUN is not set
++CONFIG_TUN=m
+ # CONFIG_ETHERTAP is not set
+ #
+@@ -312,6 +318,7 @@
+ # 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 is not set
+@@ -321,7 +328,14 @@
+ # CONFIG_IXGB is not set
+ # CONFIG_FDDI is not set
+ # CONFIG_HIPPI is not set
+-# CONFIG_PPP is not set
++CONFIG_PPP=m
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++CONFIG_PPP_ASYNC=m
++CONFIG_PPP_SYNC_TTY=m
++CONFIG_PPP_DEFLATE=m
++CONFIG_PPP_BSDCOMP=m
++CONFIG_PPPOE=m
+ # CONFIG_SLIP is not set
+ #
+@@ -489,26 +503,32 @@
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+-# CONFIG_EXT2_FS_XATTR is not set
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++# CONFIG_EXT2_FS_SECURITY is not set
+ CONFIG_EXT3_FS=y
+-# CONFIG_EXT3_FS_XATTR is not set
++CONFIG_EXT3_FS_XATTR=y
++CONFIG_EXT3_FS_POSIX_ACL=y
++# 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_JFS_FS=y
+-# CONFIG_JFS_POSIX_ACL is not set
++CONFIG_JFS_POSIX_ACL=y
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
+-CONFIG_XFS_FS=y
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=m
+ # CONFIG_XFS_RT is not set
+ # CONFIG_XFS_QUOTA is not set
+-# CONFIG_XFS_POSIX_ACL is not set
++CONFIG_XFS_POSIX_ACL=y
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
+ # CONFIG_QUOTA is not set
+-CONFIG_AUTOFS_FS=y
++CONFIG_AUTOFS_FS=m
+ # CONFIG_AUTOFS4_FS is not set
+ #
+@@ -517,7 +537,7 @@
+ CONFIG_ISO9660_FS=y
+ # CONFIG_JOLIET is not set
+ # CONFIG_ZISOFS is not set
+-# CONFIG_UDF_FS is not set
++CONFIG_UDF_FS=m
+ #
+ # DOS/FAT/NT Filesystems
+@@ -533,8 +553,9 @@
+ CONFIG_PROC_FS=y
+ # CONFIG_DEVFS_FS is not set
+ CONFIG_DEVPTS_FS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
+-# CONFIG_TMPFS is not set
++CONFIG_DEVPTS_FS_XATTR=y
++# CONFIG_DEVPTS_FS_SECURITY is not set
++CONFIG_TMPFS=y
+ CONFIG_RAMFS=y
+ #
+@@ -546,7 +567,7 @@
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-# CONFIG_CRAMFS is not set
++CONFIG_CRAMFS=y
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
+@@ -561,15 +582,16 @@
+ CONFIG_NFS_V4=y
+ CONFIG_NFSD=y
+ CONFIG_NFSD_V3=y
+-# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_V4=y
+ CONFIG_NFSD_TCP=y
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+ CONFIG_EXPORTFS=y
+ CONFIG_SUNRPC=y
+-# CONFIG_SUNRPC_GSS is not set
++CONFIG_SUNRPC_GSS=m
++CONFIG_RPCSEC_GSS_KRB5=m
+ # CONFIG_SMB_FS is not set
+-CONFIG_CIFS=y
++CONFIG_CIFS=m
+ # CONFIG_NCP_FS is not set
+ # CONFIG_CODA_FS is not set
+ # CONFIG_INTERMEZZO_FS is not set
+@@ -705,6 +727,7 @@
+ CONFIG_XMON=y
+ CONFIG_XMON_DEFAULT=y
+ # CONFIG_PPCDBG is not set
++# CONFIG_DEBUG_INFO is not set
+ #
+ # Security options
+@@ -714,9 +737,27 @@
+ #
+ # Cryptographic options
+ #
+-# CONFIG_CRYPTO is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=m
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
++CONFIG_CRYPTO_DES=m
++CONFIG_CRYPTO_BLOWFISH=m
++CONFIG_CRYPTO_TWOFISH=m
++CONFIG_CRYPTO_SERPENT=m
++CONFIG_CRYPTO_AES=m
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_TEST=m
+ #
+ # Library routines
+ #
+ CONFIG_CRC32=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=m
+Index: linux-2.6.0-test5/arch/ppc64/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/asm-offsets.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/asm-offsets.c  2003-09-27 11:38:19.787520224 +0800
+@@ -83,9 +83,7 @@
+         DEFINE(PACALPQUEUE, offsetof(struct paca_struct, lpQueuePtr));
+       DEFINE(PACATOC, offsetof(struct paca_struct, xTOC));
+       DEFINE(PACAEXCSP, offsetof(struct paca_struct, exception_sp));
+-      DEFINE(PACAHRDWINTSTACK, offsetof(struct paca_struct, xHrdIntStack));
+       DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, xProcEnabled));
+-      DEFINE(PACAHRDWINTCOUNT, offsetof(struct paca_struct, xHrdIntCount));
+       DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
+       DEFINE(PACAPROFENABLED, offsetof(struct paca_struct, prof_enabled));
+       DEFINE(PACAPROFLEN, offsetof(struct paca_struct, prof_len));
+Index: linux-2.6.0-test5/arch/ppc64/kernel/chrp_setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/chrp_setup.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/chrp_setup.c   2003-09-27 11:38:19.790519768 +0800
+@@ -72,6 +72,7 @@
+ extern void find_and_init_phbs(void);
++extern void pSeries_get_boot_time(struct rtc_time *rtc_time);
+ extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
+ extern int  pSeries_set_rtc_time(struct rtc_time *rtc_time);
+ void pSeries_calibrate_decr(void);
+@@ -256,7 +257,7 @@
+       ppc_md.power_off      = rtas_power_off;
+       ppc_md.halt           = rtas_halt;
+-      ppc_md.get_boot_time  = pSeries_get_rtc_time;
++      ppc_md.get_boot_time  = pSeries_get_boot_time;
+       ppc_md.get_rtc_time   = pSeries_get_rtc_time;
+       ppc_md.set_rtc_time   = pSeries_set_rtc_time;
+       ppc_md.calibrate_decr = pSeries_calibrate_decr;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/eeh.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/eeh.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/eeh.c  2003-09-27 11:38:19.795519008 +0800
+@@ -115,8 +115,17 @@
+               ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
+                               dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
+               if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
+-                      panic("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
+-                            rets[0], pci_name(dev), dev->dev.name);
++                      /*
++                       * XXX We should create a separate sysctl for this.
++                       *
++                       * Since the panic_on_oops sysctl is used to halt
++                       * the system in light of potential corruption, we
++                       * can use it here.
++                       */
++                      if (panic_on_oops)
++                              panic("EEH: MMIO failure (%ld) on device:\n%s\n", rets[0], pci_name(dev));
++                      else
++                              printk("EEH: MMIO failure (%ld) on device:\n%s\n", rets[0], pci_name(dev));
+               }
+       }
+       eeh_false_positives++;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/head.S    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/head.S 2003-09-27 11:38:19.811516576 +0800
+@@ -40,6 +40,15 @@
+ #define DO_SOFT_DISABLE
+ #endif
++/* copy saved SOFTE bit or EE bit from saved MSR depending
++ * if we are doing soft-disable or not
++ */
++#ifdef DO_SOFT_DISABLE
++#define DO_COPY_EE()  ld      r20,SOFTE(r1)
++#else
++#define DO_COPY_EE()  rldicl  r20,r23,49,63
++#endif
++
+ /*
+  * hcall interface to pSeries LPAR
+  */
+@@ -618,11 +627,7 @@
+       ld      r4,_DAR(r1)
+       ld      r5,_DSISR(r1)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)           /* Copy saved SOFTE bit */
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0x300
+       bl      .save_remaining_regs
+       bl      .do_page_fault
+@@ -644,12 +649,9 @@
+       or.     r3,r3,r3                /* Check return code */
+       beq     fast_exception_return   /* Return if we succeeded */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0x380
++      li      r5,0
+       bl      .save_remaining_regs
+       bl      .do_page_fault
+       b       .ret_from_except
+@@ -670,13 +672,9 @@
+       bl      .do_hash_page_ISI       /* Try to handle as hpte fault */
+ 1:
+       mr      r4,r22
+-      mr      r5,r23
++      rlwinm  r5,r23,0,4,4            /* We only care about PR in error_code */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0x400
+       bl      .save_remaining_regs
+       bl      .do_page_fault
+@@ -692,12 +690,9 @@
+       beq+    fast_exception_return   /* Return if we succeeded */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0x480
++      li      r5,0
+       bl      .save_remaining_regs
+       bl      .do_page_fault
+       b       .ret_from_except
+@@ -710,70 +705,14 @@
+       li      r20,0
+       li      r6,0x500
+       bl      .save_remaining_regs
+-      /* Determine if need to run do_irq on a hardware interrupt stack  */
+-      /*   The first invocation of do_irq will occur on the kernel      */
+-      /*   stack in the current stack                                   */
+-      /*   All other invocations of do_irq will run on the hardware     */
+-      /*   interrupt stack associated with the PACA of the current      */
+-      /*   processor.                                                   */
+-      /*                                                                */
+-      /*  The call to do_irq will preserve the value of r14 - r31       */
+-      /*                                                                */
+-/*
+- * XXX turn off interrupt stacks until the thread_info stuff is fixed.
+- * Otherwise we end up setting need_resched etc bits in the interrupt
+- *  stack and they never get seen when we return to the process stack - Anton
+- */
+-#if 0
+-      lbz     r21,PACAHRDWINTCOUNT(r13)    /* get hardware interrupt cnt */
+-      cmpi    0,r21,1                     /*                            */
+-      addi    r21,r21,1                   /* incr hardware interrupt cnt*/
+-      stb     r21,PACAHRDWINTCOUNT(r13)   /*                            */
+-      bne     2f                          /*                            */
+-
+-      mr      r14,r1                      /* preserve current r1        */
+-      ld      r1,PACAHRDWINTSTACK(r13)    /*                            */
+-      std     r14,0(r1)                   /* set the back chain         */
+       bl      .do_IRQ
+-      lbz     r22,PACAHRDWINTCOUNT(r13)   /* get hardware interrupt cnt */
+-      cmp     0,r22,r21                   /* debug test                 */
+-      bne     3f
+-      subi    r21,r21,1
+-      stb     r21,PACAHRDWINTCOUNT(r13)   /*                            */
+-      mr      r1,r14                      /*                            */
+       b       .ret_from_except
+-#endif
+-
+-2:
+-      bl      .do_IRQ
+-
+-#if 0
+-      lbz     r22,PACAHRDWINTCOUNT(r13)   /* get hardware interrupt cnt */
+-      cmp     0,r22,r21                   /* debug test                 */
+-      bne     3f                          /*                            */
+-      subi    r21,r21,1                   /* decr hardware interrupt cnt*/
+-      stb     r21,PACAHRDWINTCOUNT(r13)   /*                            */
+-#endif
+-
+-      b       .ret_from_except
+-
+-3:
+-      /* error - counts out of sync                                      */
+-#ifdef CONFIG_XMON
+-      bl      .xmon
+-#endif
+-4:    b       4b
+-
+       .globl Alignment_common
+ Alignment_common:
+       EXCEPTION_PROLOG_COMMON
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0x600
+       bl      .save_remaining_regs
+       bl      .AlignmentException
+@@ -783,11 +722,7 @@
+ ProgramCheck_common:
+       EXCEPTION_PROLOG_COMMON
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0x700
+       bl      .save_remaining_regs
+       bl      .ProgramCheckException
+@@ -798,11 +733,7 @@
+       EXCEPTION_PROLOG_COMMON
+       bne     .load_up_fpu            /* if from user, just load it up */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0x800
+       bl      .save_remaining_regs
+       bl      .KernelFPUnavailableException
+@@ -818,11 +749,7 @@
+       beq+    HardwareInterrupt_entry
+ 1:
+ #endif
+-#ifdef DO_SOFT_DISABLE
+-      ld      r20,SOFTE(r1)
+-#else
+-      rldicl  r20,r23,49,63           /* copy EE bit from saved MSR */
+-#endif
++      DO_COPY_EE()
+       li      r6,0xC00
+       bl      .save_remaining_regs
+       bl      .DoSyscall
+@@ -1866,18 +1793,6 @@
+       li      r5,0
+       std     r0,PACAKSAVE(r13)
+-      /* ptr to hardware interrupt stack for boot processor */
+-      LOADADDR(r3, hardware_int_paca0)
+-      li      r5,PAGE_SIZE
+-      sldi    r5,r5,3
+-      subi    r5,r5,STACK_FRAME_OVERHEAD
+-
+-      add     r3,r3,r5
+-      std     r3,PACAHRDWINTSTACK(r13)
+-
+-      li      r3,0
+-      stb     r3,PACAHRDWINTCOUNT(r13)
+-
+       /* Restore the parms passed in from the bootloader. */
+       mr      r3,r31
+       mr      r4,r30
+@@ -1999,10 +1914,6 @@
+ ioremap_dir:
+       .space  4096
+-      .globl  hardware_int_paca0
+-hardware_int_paca0:
+-      .space  8*PAGE_SIZE
+-
+ /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */
+       .globl  stab_array
+ stab_array:
+Index: linux-2.6.0-test5/arch/ppc64/kernel/htab.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/htab.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/htab.c 2003-09-27 11:38:19.814516120 +0800
+@@ -197,7 +197,7 @@
+       if (!pgd_none(*pg)) {
+               pm = pmd_offset(pg, ea);
+-              if (!pmd_none(*pm)) { 
++              if (pmd_present(*pm)) { 
+                       pt = pte_offset_kernel(pm, ea);
+                       pte = *pt;
+                       if (!pte_present(pte))
+@@ -436,8 +436,12 @@
+       if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
+               local = 1;
+-      ptep = find_linux_pte(pgdir, ea);
+-      ret = __hash_page(ea, access, vsid, ptep, trap, local);
++      ret = hash_huge_page(mm, access, ea, vsid, local);
++      if (ret < 0) {
++              ptep = find_linux_pte(pgdir, ea);
++              ret = __hash_page(ea, access, vsid, ptep, trap, local);
++      }
++
+       spin_unlock(&mm->page_table_lock);
+       return ret;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/irq.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/irq.c  2003-09-27 11:38:19.820515208 +0800
+@@ -39,6 +39,7 @@
+ #include <linux/irq.h>
+ #include <linux/proc_fs.h>
+ #include <linux/random.h>
++#include <linux/kallsyms.h>
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+@@ -350,14 +351,11 @@
+       return 0;
+ }
+-extern char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
+-
+-static inline void handle_irq_event(int irq, struct pt_regs *regs,
+-                                  struct irqaction *action)
++static inline int handle_irq_event(int irq, struct pt_regs *regs,
++                                 struct irqaction *action)
+ {
+       int status = 0;
+       int retval = 0;
+-      struct irqaction *first_action = action;
+       if (!(action->flags & SA_INTERRUPT))
+               local_irq_enable();
+@@ -370,28 +368,88 @@
+       if (status & SA_SAMPLE_RANDOM)
+               add_interrupt_randomness(irq);
+       local_irq_disable();
+-      if (retval != 1) {
+-              static int count = 100;
+-              char name_buf[256];
+-              if (count) {
+-                      count--;
+-                      if (retval) {
+-                              printk("irq event %d: bogus retval mask %x\n",
+-                                      irq, retval);
+-                      } else {
+-                              printk("irq %d: nobody cared!\n", irq);
+-                      }
+-                      dump_stack();
+-                      printk("handlers:\n");
+-                      action = first_action;
+-                      do {
+-                              printk("[<%p>]", action->handler);
+-                              printk(" (%s)\n",
+-                                     ppc_find_proc_name((unsigned *)action->handler, name_buf, 256));
+-                              action = action->next;
+-                      } while (action);
+-              }
++      return retval;
++}
++
++static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
++{
++      struct irqaction *action;
++
++      if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
++              printk(KERN_ERR "irq event %d: bogus return value %x\n",
++                              irq, action_ret);
++      } else {
++              printk(KERN_ERR "irq %d: nobody cared!\n", irq);
++      }
++      dump_stack();
++      printk(KERN_ERR "handlers:\n");
++      action = desc->action;
++      do {
++              printk(KERN_ERR "[<%p>]", action->handler);
++              print_symbol(" (%s)",
++                      (unsigned long)action->handler);
++              printk("\n");
++              action = action->next;
++      } while (action);
++}
++
++static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
++{
++      static int count = 100;
++
++      if (count) {
++              count--;
++              __report_bad_irq(irq, desc, action_ret);
++      }
++}
++
++static int noirqdebug;
++
++static int __init noirqdebug_setup(char *str)
++{
++      noirqdebug = 1;
++      printk("IRQ lockup detection disabled\n");
++      return 1;
++}
++
++__setup("noirqdebug", noirqdebug_setup);
++
++/*
++ * If 99,900 of the previous 100,000 interrupts have not been handled then
++ * assume that the IRQ is stuck in some manner.  Drop a diagnostic and try to
++ * turn the IRQ off.
++ *
++ * (The other 100-of-100,000 interrupts may have been a correctly-functioning
++ *  device sharing an IRQ with the failing one)
++ *
++ * Called under desc->lock
++ */
++static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
++{
++      if (action_ret != IRQ_HANDLED) {
++              desc->irqs_unhandled++;
++              if (action_ret != IRQ_NONE)
++                      report_bad_irq(irq, desc, action_ret);
+       }
++
++      desc->irq_count++;
++      if (desc->irq_count < 100000)
++              return;
++
++      desc->irq_count = 0;
++      if (desc->irqs_unhandled > 99900) {
++              /*
++               * The interrupt is stuck
++               */
++              __report_bad_irq(irq, desc, action_ret);
++              /*
++               * Now kill the IRQ
++               */
++              printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
++              desc->status |= IRQ_DISABLED;
++              desc->handler->disable(irq);
++      }
++      desc->irqs_unhandled = 0;
+ }
+ /*
+@@ -462,10 +520,13 @@
+        * SMP environment.
+        */
+       for (;;) {
++              irqreturn_t action_ret;
++
+               spin_unlock(&desc->lock);
+-              handle_irq_event(irq, regs, action);
++              action_ret = handle_irq_event(irq, regs, action);
+               spin_lock(&desc->lock);
+-              
++              if (!noirqdebug)
++                      note_interrupt(irq, desc, action_ret);
+               if (likely(!(desc->status & IRQ_PENDING)))
+                       break;
+               desc->status &= ~IRQ_PENDING;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/ppc_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/ppc_ksyms.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/ppc_ksyms.c    2003-09-27 11:38:19.822514904 +0800
+@@ -49,8 +49,6 @@
+ extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+ extern int do_signal(sigset_t *, struct pt_regs *);
+-extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
+-extern int unregister_ioctl32_conversion(unsigned int cmd);
+ int abs(int);
+@@ -66,9 +64,6 @@
+ EXPORT_SYMBOL(synchronize_irq);
+ #endif /* CONFIG_SMP */
+-EXPORT_SYMBOL(register_ioctl32_conversion);
+-EXPORT_SYMBOL(unregister_ioctl32_conversion);
+-
+ EXPORT_SYMBOL(isa_io_base);
+ EXPORT_SYMBOL(pci_io_base);
+Index: linux-2.6.0-test5/arch/ppc64/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/process.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/process.c      2003-09-27 11:38:19.827514144 +0800
+@@ -32,6 +32,7 @@
+ #include <linux/init_task.h>
+ #include <linux/prctl.h>
+ #include <linux/ptrace.h>
++#include <linux/kallsyms.h>
+ #include <asm/pgtable.h>
+ #include <asm/uaccess.h>
+@@ -130,12 +131,9 @@
+       return last;
+ }
+-char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
+-
+ void show_regs(struct pt_regs * regs)
+ {
+       int i;
+-      char name_buf[256];
+       printk("NIP: %016lX XER: %016lX LR: %016lX\n",
+              regs->nip, regs->xer, regs->link);
+@@ -170,8 +168,7 @@
+        * above info out without failing
+        */
+       printk("NIP [%016lx] ", regs->nip);
+-      printk("%s\n", ppc_find_proc_name((unsigned *)regs->nip,
+-             name_buf, 256));
++      print_symbol("%s\n", regs->nip);
+       show_stack(current, (unsigned long *)regs->gpr[1]);
+ }
+@@ -385,102 +382,6 @@
+       return error;
+ }
+-void initialize_paca_hardware_interrupt_stack(void)
+-{
+-      int i;
+-      unsigned long stack;
+-      unsigned long end_of_stack =0;
+-
+-      for (i=1; i < NR_CPUS; i++) {
+-              if (!cpu_possible(i))
+-                      continue;
+-              /* Carve out storage for the hardware interrupt stack */
+-              stack = __get_free_pages(GFP_ATOMIC, get_order(8*PAGE_SIZE));
+-
+-              if ( !stack ) {     
+-                      printk("ERROR, cannot find space for hardware stack.\n");
+-                      panic(" no hardware stack ");
+-              }
+-
+-
+-              /* Store the stack value in the PACA for the processor */
+-              paca[i].xHrdIntStack = stack + (8*PAGE_SIZE) - STACK_FRAME_OVERHEAD;
+-              paca[i].xHrdIntCount = 0;
+-
+-      }
+-
+-      /*
+-       * __get_free_pages() might give us a page > KERNBASE+256M which
+-       * is mapped with large ptes so we can't set up the guard page.
+-       */
+-      if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
+-              return;
+-
+-      for (i=0; i < NR_CPUS; i++) {
+-              if (!cpu_possible(i))
+-                      continue;
+-              /* set page at the top of stack to be protected - prevent overflow */
+-              end_of_stack = paca[i].xHrdIntStack - (8*PAGE_SIZE - STACK_FRAME_OVERHEAD);
+-              ppc_md.hpte_updateboltedpp(PP_RXRX,end_of_stack);
+-      }
+-}
+-
+-char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen)
+-{
+-      unsigned long tb_flags;
+-      unsigned short name_len;
+-      unsigned long tb_start, code_start, code_ptr, code_offset;
+-      unsigned int code_len;
+-      unsigned long end;
+-
+-      strcpy(buf, "Unknown");
+-      code_ptr = (unsigned long)p;
+-      code_offset = 0;
+-
+-      /* handle functions in text and init sections */
+-      if (((unsigned long)p >= (unsigned long)_stext) && 
+-          ((unsigned long)p < (unsigned long)_etext))
+-              end = (unsigned long)_etext;
+-      else if (((unsigned long)p >= (unsigned long)__init_begin) && 
+-               ((unsigned long)p < (unsigned long)__init_end))
+-              end = (unsigned long)__init_end;
+-      else
+-              return buf;
+-
+-      while ((unsigned long)p < end) {
+-              if (*p == 0) {
+-                      tb_start = (unsigned long)p;
+-                      ++p;    /* Point to traceback flags */
+-                      tb_flags = *((unsigned long *)p);
+-                      p += 2; /* Skip over traceback flags */
+-                      if (tb_flags & TB_NAME_PRESENT) {
+-                              if (tb_flags & TB_PARMINFO)
+-                                      ++p;    /* skip over parminfo data */
+-                              if (tb_flags & TB_HAS_TBOFF) {
+-                                      code_len = *p;  /* get code length */
+-                                      code_start = tb_start - code_len;
+-                                      code_offset = code_ptr - code_start + 1;
+-                                      if (code_offset > 0x100000)
+-                                              break;
+-                                      ++p;    /* skip over code size */
+-                              }
+-                              name_len = *((unsigned short *)p);
+-                              if (name_len > (buflen-20))
+-                                      name_len = buflen-20;
+-                              memcpy(buf, ((char *)p)+2, name_len);
+-                              buf[name_len] = 0;
+-                              if (code_offset)
+-                                      sprintf(buf+name_len, "+0x%lx",
+-                                              code_offset-1); 
+-                      }
+-                      break;
+-              }
+-              ++p;
+-      }
+-
+-      return buf;
+-}
+-
+ /*
+  * These bracket the sleeping functions..
+  */
+@@ -520,7 +421,6 @@
+       unsigned long ip;
+       unsigned long stack_page = (unsigned long)p->thread_info;
+       int count = 0;
+-      char name_buf[256];
+       unsigned long sp = (unsigned long)_sp;
+       if (!p)
+@@ -539,8 +439,7 @@
+               if (__get_user(ip, (unsigned long *)(sp + 16)))
+                       break;
+               printk("[%016lx] ", ip);
+-              printk("%s\n", ppc_find_proc_name((unsigned *)ip,
+-                     name_buf, 256));
++              print_symbol("%s\n", ip);
+       } while (count++ < 32);
+ }
+Index: linux-2.6.0-test5/arch/ppc64/kernel/pSeries_lpar.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/pSeries_lpar.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/pSeries_lpar.c 2003-09-27 11:38:19.831513536 +0800
+@@ -36,18 +36,6 @@
+ #include <asm/tlb.h>
+ #include <asm/hvcall.h>
+-
+-long plpar_pte_enter(unsigned long flags,
+-                   unsigned long ptex,
+-                   unsigned long new_pteh, unsigned long new_ptel,
+-                   unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+-{
+-      unsigned long dummy, ret;
+-      ret = plpar_hcall(H_ENTER, flags, ptex, new_pteh, new_ptel,
+-                         old_pteh_ret, old_ptel_ret, &dummy);
+-      return(ret);
+-}
+-
+ long plpar_pte_remove(unsigned long flags,
+                     unsigned long ptex,
+                     unsigned long avpn,
+@@ -83,7 +71,6 @@
+                          tce_ret, &dummy, &dummy);
+ }
+-
+ long plpar_tce_put(unsigned long liobn,
+                  unsigned long ioba,
+                  unsigned long tceval)
+@@ -104,10 +91,9 @@
+                        unsigned long len,
+                        const char *buffer)
+ {
+-      unsigned long dummy;
+       unsigned long *lbuf = (unsigned long *)buffer;  /* ToDo: alignment? */
+-      return plpar_hcall(H_PUT_TERM_CHAR, termno, len,
+-                         lbuf[0], lbuf[1], &dummy, &dummy, &dummy);
++      return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
++                                lbuf[1]);
+ }
+ static void tce_build_pSeriesLP(struct TceTable *tbl, long tcenum, 
+@@ -287,12 +273,11 @@
+ int hvc_put_chars(int index, const char *buf, int count)
+ {
+-      unsigned long dummy;
+       unsigned long *lbuf = (unsigned long *) buf;
+       long ret;
+-      ret = plpar_hcall(H_PUT_TERM_CHAR, index, count, lbuf[0], lbuf[1],
+-                        &dummy, &dummy, &dummy);
++      ret = plpar_hcall_norets(H_PUT_TERM_CHAR, index, count, lbuf[0],
++                               lbuf[1]);
+       if (ret == H_Success)
+               return count;
+       if (ret == H_Busy)
+@@ -318,7 +303,6 @@
+-
+ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
+                             unsigned long va, unsigned long prpn,
+                             int secondary, unsigned long hpteflags,
+@@ -329,6 +313,7 @@
+       unsigned long flags;
+       unsigned long slot;
+       HPTE lhpte;
++      unsigned long dummy0, dummy1;
+       /* Fill in the local HPTE with absolute rpn, avpn and flags */
+       lhpte.dw1.dword1      = 0;
+@@ -348,7 +333,6 @@
+       /* Now fill in the actual HPTE */
+       /* Set CEC cookie to 0         */
+-      /* Large page = 0              */
+       /* Zero page = 0               */
+       /* I-cache Invalidate = 0      */
+       /* I-cache synchronize = 0     */
+@@ -359,19 +343,8 @@
+       if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+               lhpte.dw1.flags.flags &= ~_PAGE_COHERENT;
+-      __asm__ __volatile__ (
+-              H_ENTER_r3
+-              "mr    4, %2\n"
+-                "mr    5, %3\n"
+-                "mr    6, %4\n"
+-                "mr    7, %5\n"
+-                HSC    
+-                "mr    %0, 3\n"
+-                "mr    %1, 4\n"
+-              : "=r" (lpar_rc), "=r" (slot)
+-              : "r" (flags), "r" (hpte_group), "r" (lhpte.dw0.dword0),
+-              "r" (lhpte.dw1.dword1)
+-              : "r3", "r4", "r5", "r6", "r7", "cc");
++      lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, lhpte.dw0.dword0,
++                            lhpte.dw1.dword1, &slot, &dummy0, &dummy1);
+       if (lpar_rc == H_PTEG_Full)
+               return -1;
+Index: linux-2.6.0-test5/arch/ppc64/kernel/pSeries_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/pSeries_pci.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/pSeries_pci.c  2003-09-27 11:38:19.836512776 +0800
+@@ -427,6 +427,7 @@
+ void pcibios_name_device(struct pci_dev *dev)
+ {
++#if 0
+       struct device_node *dn;
+       /*
+@@ -446,6 +447,7 @@
+                       }
+               }
+       }
++#endif
+ }   
+ void __init pcibios_fixup_device_resources(struct pci_dev *dev,
+Index: linux-2.6.0-test5/arch/ppc64/kernel/rtas.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/rtas.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/rtas.c 2003-09-27 11:38:19.839512320 +0800
+@@ -24,6 +24,7 @@
+ #include <asm/machdep.h>
+ #include <asm/paca.h>
+ #include <asm/page.h>
++#include <asm/param.h>
+ #include <asm/system.h>
+ #include <asm/abs_addr.h>
+ #include <asm/udbg.h>
+@@ -178,6 +179,26 @@
+       return (ulong)((nret > 0) ? rtas_args->rets[0] : 0);
+ }
++/* Given an RTAS status code of 990n compute the hinted delay of 10^n
++ * (last digit) milliseconds.  For now we bound at n=3 (1 sec).
++ */
++unsigned int
++rtas_extended_busy_delay_time(int status)
++{
++      int order = status - 9900;
++      unsigned int ms;
++
++      if (order < 0)
++              order = 0;      /* RTC depends on this for -2 clock busy */
++      else if (order > 3)
++              order = 3;      /* bound */
++
++      /* Use microseconds for reasonable accuracy */
++      for (ms = 1000; order > 0; order--)
++              ms = ms * 10;
++      return ms / (1000000/HZ); /* round down is fine */
++}
++
+ #define FLASH_BLOCK_LIST_VERSION (1UL)
+ static void
+ rtas_flash_firmware(void)
+Index: linux-2.6.0-test5/arch/ppc64/kernel/rtc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/rtc.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/rtc.c  2003-09-27 11:38:19.843511712 +0800
+@@ -35,6 +35,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/bcd.h>
++#include <asm/hardirq.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+@@ -340,20 +341,63 @@
+ #endif
+ #ifdef CONFIG_PPC_PSERIES
++#define MAX_RTC_WAIT 5000     /* 5 sec */
++#define RTAS_CLOCK_BUSY (-2)
++void pSeries_get_boot_time(struct rtc_time *rtc_tm)
++{
++      unsigned long ret[8];
++      int error, wait_time;
++      unsigned long max_wait_tb;
++
++      max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
++      do {
++              error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret);
++              if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
++                      wait_time = rtas_extended_busy_delay_time(error);
++                      /* This is boot time so we spin. */
++                      udelay(wait_time*1000);
++                      error = RTAS_CLOCK_BUSY;
++              }
++      } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
++
++      if (error != 0) {
++              printk(KERN_WARNING "error: reading the clock failed (%d)\n",
++                      error);
++              return;
++      }
++
++      rtc_tm->tm_sec = ret[5];
++      rtc_tm->tm_min = ret[4];
++      rtc_tm->tm_hour = ret[3];
++      rtc_tm->tm_mday = ret[2];
++      rtc_tm->tm_mon = ret[1] - 1;
++      rtc_tm->tm_year = ret[0] - 1900;
++}
++
++/* NOTE: get_rtc_time will get an error if executed in interrupt context
++ * and if a delay is needed to read the clock.  In this case we just
++ * silently return without updating rtc_tm.
++ */
+ void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
+ {
+         unsigned long ret[8];
+-        int error;
+-      int count;
++      int error, wait_time;
++      unsigned long max_wait_tb;
+-      /*
+-       * error -2 is clock busy, we keep retrying a few times to see
+-       * if it will come good  -- paulus
+-       */
+-      count = 0;
++      max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+       do {
+               error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret);
+-      } while (error == -2 && ++count < 1000);
++              if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
++                      if (in_interrupt()) {
++                              printk(KERN_WARNING "error: reading clock would delay interrupt\n");
++                              return; /* delay not allowed */
++                      }
++                      wait_time = rtas_extended_busy_delay_time(error);
++                      set_current_state(TASK_INTERRUPTIBLE);
++                      schedule_timeout(wait_time);
++                      error = RTAS_CLOCK_BUSY;
++              }
++      } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
+         if (error != 0) {
+                 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+@@ -371,20 +415,24 @@
+ int pSeries_set_rtc_time(struct rtc_time *tm)
+ {
+-        int error;
+-      int count;
++      int error, wait_time;
++      unsigned long max_wait_tb;
+-      /*
+-       * error -2 is clock busy, we keep retrying a few times to see
+-       * if it will come good  -- paulus
+-       */
+-      count = 0;
++      max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+       do {
+               error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
+                                 tm->tm_year + 1900, tm->tm_mon + 1, 
+                                 tm->tm_mday, tm->tm_hour, tm->tm_min, 
+                                 tm->tm_sec, 0);
+-      } while (error == -2 && ++count < 1000);
++              if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
++                      if (in_interrupt())
++                              return 1;       /* probably decrementer */
++                      wait_time = rtas_extended_busy_delay_time(error);
++                      set_current_state(TASK_INTERRUPTIBLE);
++                      schedule_timeout(wait_time);
++                      error = RTAS_CLOCK_BUSY;
++              }
++      } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
+         if (error != 0)
+                 printk(KERN_WARNING "error: setting the clock failed (%d)\n",
+Index: linux-2.6.0-test5/arch/ppc64/kernel/semaphore.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/semaphore.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/semaphore.c    2003-09-27 11:38:19.845511408 +0800
+@@ -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:
+@@ -75,9 +76,8 @@
+       struct task_struct *tsk = current;
+       DECLARE_WAITQUEUE(wait, tsk);
+-      tsk->state = TASK_UNINTERRUPTIBLE;
++      __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+       add_wait_queue_exclusive(&sem->wait, &wait);
+-      smp_wmb();
+       /*
+        * Try to get the semaphore.  If the count is > 0, then we've
+@@ -87,10 +87,10 @@
+        */
+       while (__sem_update_count(sem, -1) <= 0) {
+               schedule();
+-              tsk->state = TASK_UNINTERRUPTIBLE;
++              set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+       }
+       remove_wait_queue(&sem->wait, &wait);
+-      tsk->state = TASK_RUNNING;
++      __set_task_state(tsk, TASK_RUNNING);
+       /*
+        * If there are any more sleepers, wake one of them up so
+@@ -106,9 +106,8 @@
+       struct task_struct *tsk = current;
+       DECLARE_WAITQUEUE(wait, tsk);
+-      tsk->state = TASK_INTERRUPTIBLE;
++      __set_task_state(tsk, TASK_INTERRUPTIBLE);
+       add_wait_queue_exclusive(&sem->wait, &wait);
+-      smp_wmb();
+       while (__sem_update_count(sem, -1) <= 0) {
+               if (signal_pending(current)) {
+@@ -122,10 +121,148 @@
+                       break;
+               }
+               schedule();
+-              tsk->state = TASK_INTERRUPTIBLE;
++              set_task_state(tsk, TASK_INTERRUPTIBLE);
+       }
+-      tsk->state = TASK_RUNNING;
+       remove_wait_queue(&sem->wait, &wait);
++      __set_task_state(tsk, TASK_RUNNING);
++
+       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
+Index: linux-2.6.0-test5/arch/ppc64/kernel/stab.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/stab.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/stab.c 2003-09-27 11:38:19.848510952 +0800
+@@ -221,15 +221,18 @@
+ }
+ static inline void __ste_allocate(unsigned long esid, unsigned long vsid,
+-                                int kernel_segment)
++                                int kernel_segment, mm_context_t context)
+ {
+       if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
++              int large = 0;
++
+ #ifndef CONFIG_PPC_ISERIES
+               if (REGION_ID(esid << SID_SHIFT) == KERNEL_REGION_ID)
+-                      make_slbe(esid, vsid, 1, kernel_segment); 
+-              else
++                      large = 1;
++              else if (REGION_ID(esid << SID_SHIFT) == USER_REGION_ID)
++                      large = in_hugepage_area(context, esid << SID_SHIFT);
+ #endif
+-                      make_slbe(esid, vsid, 0, kernel_segment);
++              make_slbe(esid, vsid, large, kernel_segment);
+       } else {
+               unsigned char top_entry, stab_entry, *segments; 
+@@ -255,6 +258,7 @@
+ {
+       unsigned long vsid, esid;
+       int kernel_segment = 0;
++      mm_context_t context;
+       PMC_SW_PROCESSOR(stab_faults); 
+@@ -266,16 +270,18 @@
+       if (REGION_ID(ea) >= KERNEL_REGION_ID) {
+               kernel_segment = 1;
+               vsid = get_kernel_vsid(ea);
++              context = REGION_ID(ea);
+       } else {
+-              struct mm_struct *mm = current->mm;
+-              if (mm)
+-                      vsid = get_vsid(mm->context, ea);
+-              else
++              if (! current->mm)
+                       return 1;
++
++              context = current->mm->context;
++              
++              vsid = get_vsid(context, ea);
+       }
+       esid = GET_ESID(ea);
+-      __ste_allocate(esid, vsid, kernel_segment);
++      __ste_allocate(esid, vsid, kernel_segment, context);
+       if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
+               /* Order update */
+               asm volatile("sync":::"memory"); 
+@@ -302,7 +308,7 @@
+               for (esid = 0; esid < 16; esid++) {
+                       unsigned long ea = esid << SID_SHIFT;
+                       vsid = get_vsid(mm->context, ea);
+-                      __ste_allocate(esid, vsid, 0);
++                      __ste_allocate(esid, vsid, 0, mm->context);
+               }
+       } else {
+               unsigned long pc = KSTK_EIP(tsk);
+@@ -316,7 +322,7 @@
+                           (REGION_ID(pc) >= KERNEL_REGION_ID))
+                               return;
+                       vsid = get_vsid(mm->context, pc);
+-                      __ste_allocate(GET_ESID(pc), vsid, 0);
++                      __ste_allocate(GET_ESID(pc), vsid, 0, mm->context);
+               }
+               if (stack && (pc_segment != stack_segment)) {
+@@ -324,7 +330,7 @@
+                           (REGION_ID(stack) >= KERNEL_REGION_ID))
+                               return;
+                       vsid = get_vsid(mm->context, stack);
+-                      __ste_allocate(GET_ESID(stack), vsid, 0);
++                      __ste_allocate(GET_ESID(stack), vsid, 0, mm->context);
+               }
+       }
+Index: linux-2.6.0-test5/arch/ppc64/kernel/syscalls.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/syscalls.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/syscalls.c     2003-09-27 11:38:19.851510496 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/arch/ppc/kernel/sys_ppc.c
++ * linux/arch/ppc64/kernel/sys_ppc.c
+  *
+  *  PowerPC version 
+  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+@@ -40,7 +40,6 @@
+ #include <asm/uaccess.h>
+ #include <asm/ipc.h>
+ #include <asm/semaphore.h>
+-#include <asm/ppcdebug.h>
+ #include <asm/time.h>
+ extern unsigned long wall_jiffies;
+@@ -79,6 +78,7 @@
+       case SEMCTL: {
+               union semun fourth;
++              ret = -EINVAL;
+               if (!ptr)
+                       break;
+               if ((ret = get_user(fourth.__pad, (void **)ptr)))
+@@ -94,6 +94,7 @@
+               case 0: {
+                       struct ipc_kludge tmp;
++                      ret = -EINVAL;
+                       if (!ptr)
+                               break;
+                       if ((ret = copy_from_user(&tmp,
+@@ -127,6 +128,7 @@
+                       break;
+               }
+               case 1: /* iBCS2 emulator entry point */
++                      ret = -EINVAL;
+                       if (!segment_eq(get_fs(), get_ds()))
+                               break;
+                       ret = sys_shmat (first, (char *) ptr, second,
+Index: linux-2.6.0-test5/arch/ppc64/kernel/sys_ppc32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/sys_ppc32.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/sys_ppc32.c    2003-09-27 11:38:19.871507456 +0800
+@@ -748,16 +748,16 @@
+ {
+       int err;
+-      if (stat->size > MAX_NON_LFS)
+-              return -EOVERFLOW;
++      if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
++          !new_valid_dev(stat->rdev))
+-      err  = put_user(stat->dev, &statbuf->st_dev);
++      err  = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
+       err |= put_user(stat->ino, &statbuf->st_ino);
+       err |= put_user(stat->mode, &statbuf->st_mode);
+       err |= put_user(stat->nlink, &statbuf->st_nlink);
+       err |= put_user(stat->uid, &statbuf->st_uid);
+       err |= put_user(stat->gid, &statbuf->st_gid);
+-      err |= put_user(stat->rdev, &statbuf->st_rdev);
++      err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
+       err |= put_user(stat->size, &statbuf->st_size);
+       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+       err |= put_user(0, &statbuf->__unused1);
+@@ -1243,16 +1243,19 @@
+ }
+-struct msgbuf32 { s32 mtype; char mtext[1]; };
++struct msgbuf32 {
++      compat_long_t mtype; 
++      char mtext[1];
++};
+ struct semid_ds32 {
+       struct ipc_perm sem_perm;
+       compat_time_t sem_otime;
+       compat_time_t sem_ctime;
+-      u32 sem_base;
+-      u32 sem_pending;
+-      u32 sem_pending_last;
+-      u32 undo;
++      compat_uptr_t sem_base;
++      compat_uptr_t sem_pending;
++      compat_uptr_t sem_pending_last;
++      compat_uptr_t undo;
+       unsigned short sem_nsems;
+ };
+@@ -1262,21 +1265,20 @@
+       compat_time_t sem_otime;
+       unsigned int __unused2;
+       compat_time_t sem_ctime;
+-      u32 sem_nsems;
+-      u32 __unused3;
+-      u32 __unused4;
++      compat_ulong_t sem_nsems;
++      compat_ulong_t __unused3;
++      compat_ulong_t __unused4;
+ };
+-struct msqid_ds32
+-{
++struct msqid_ds32 {
+       struct ipc_perm msg_perm;
+-      u32 msg_first;
+-      u32 msg_last;
++      compat_uptr_t msg_first;
++      compat_uptr_t msg_last;
+       compat_time_t msg_stime;
+       compat_time_t msg_rtime;
+       compat_time_t msg_ctime;
+-      u32 msg_lcbytes;
+-      u32 msg_lqbytes;
++      compat_ulong_t msg_lcbytes;
++      compat_ulong_t msg_lqbytes;
+       unsigned short msg_cbytes;
+       unsigned short msg_qnum;
+       unsigned short msg_qbytes;
+@@ -1292,13 +1294,13 @@
+       compat_time_t msg_rtime;
+       unsigned int __unused3;
+       compat_time_t msg_ctime;
+-      unsigned int msg_cbytes;
+-      unsigned int msg_qnum;
+-      unsigned int msg_qbytes;
++      compat_ulong_t msg_cbytes;
++      compat_ulong_t msg_qnum;
++      compat_ulong_t msg_qbytes;
+       compat_pid_t msg_lspid;
+       compat_pid_t msg_lrpid;
+-      unsigned int __unused4;
+-      unsigned int __unused5;
++      compat_ulong_t __unused4;
++      compat_ulong_t __unused5;
+ };
+ struct shmid_ds32 {
+@@ -1311,8 +1313,8 @@
+       compat_ipc_pid_t shm_lpid;
+       unsigned short shm_nattch;
+       unsigned short __unused;
+-      unsigned int __unused2;
+-      unsigned int __unused3;
++      compat_uptr_t __unused2;
++      compat_uptr_t __unused3;
+ };
+ struct shmid64_ds32 {
+@@ -1327,9 +1329,9 @@
+       compat_size_t shm_segsz;
+       compat_pid_t shm_cpid;
+       compat_pid_t shm_lpid;
+-      unsigned int shm_nattch;
+-      unsigned int __unused5;
+-      unsigned int __unused6;
++      compat_ulong_t shm_nattch;
++      compat_ulong_t __unused5;
++      compat_ulong_t __unused6;
+ };
+ /*
+@@ -1350,7 +1352,7 @@
+       err = -EFAULT;
+       if (get_user(pad, (u32 *)uptr))
+               return err;
+-      if (third == SETVAL)
++      if ((third & ~IPC_64) == SETVAL)
+               fourth.val = (int)pad;
+       else
+               fourth.__pad = (void *)A(pad);
+Index: linux-2.6.0-test5/arch/ppc64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/time.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/time.c 2003-09-27 11:38:19.877506544 +0800
+@@ -307,6 +307,15 @@
+       return 1;
+ }
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ *
++ * This is wrong, but my CPUs run at 1GHz, so nyer nyer.
++ */
++unsigned long long sched_clock(void)
++{
++      return get_tb();
++}
+ /*
+  * This version of gettimeofday has microsecond resolution.
+Index: linux-2.6.0-test5/arch/ppc64/kernel/vmlinux.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/vmlinux.lds.S     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/vmlinux.lds.S  2003-09-27 11:38:19.878506392 +0800
+@@ -137,4 +137,9 @@
+   . = ALIGN(4096);
+   _end = . ;
+   PROVIDE (end = .);
++
++  /* Sections to be discarded. */
++  /DISCARD/ : {
++    *(.exitcall.exit)
++  }
+ }
+Index: linux-2.6.0-test5/arch/ppc64/kernel/xics.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/kernel/xics.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/kernel/xics.c 2003-09-27 11:38:19.883505632 +0800
+@@ -267,6 +267,15 @@
+                      irq, call_status);
+               return;
+       }
++
++      /* Have to set XIVE to 0xff to be able to remove a slot */
++      call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, default_server,
++                              0xff);
++      if (call_status != 0) {
++      printk("xics_disable_irq: irq=%x: ibm_set_xive(0xff) returned %lx\n",
++             irq, call_status);
++              return;
++      }
+ }
+ void xics_end_irq(u_int       irq)
+@@ -375,12 +384,12 @@
+       int i;
+       unsigned long intr_size = 0;
+       struct device_node *np;
+-      uint *ireg, ilen, indx=0;
++      uint *ireg, ilen, indx = 0;
+       unsigned long intr_base = 0;
+       struct xics_interrupt_node {
+-              unsigned long long addr;
+-              unsigned long long size;
+-      } inodes[NR_CPUS*2]; 
++              unsigned long addr;
++              unsigned long size;
++      } inodes[NR_CPUS]; 
+       ppc64_boot_msg(0x20, "XICS Init");
+Index: linux-2.6.0-test5/arch/ppc64/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/Makefile 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/Makefile      2003-09-27 11:38:19.884505480 +0800
+@@ -18,7 +18,13 @@
+ LDFLAGS               := -m elf64ppc
+ LDFLAGS_vmlinux       := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD)
+ CFLAGS                += -msoft-float -pipe -Wno-uninitialized -mminimal-toc \
+-              -mtraceback=full -mcpu=power4
++              -mcpu=power4
++
++have_zero_bss := $(shell if $(CC) -fno-zero-initialized-in-bss -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
++
++ifeq ($(have_zero_bss),y)
++CFLAGS                += -fno-zero-initialized-in-bss
++endif
+ head-y := arch/ppc64/kernel/head.o
+@@ -39,6 +45,12 @@
+       rm -f .config arch/ppc64/defconfig
+       cp -f arch/ppc64/configs/$(@:config=defconfig) arch/ppc64/defconfig
++bootimage-$(CONFIG_PPC_PSERIES) := zImage
++bootimage-$(CONFIG_PPC_ISERIES) := vmlinux.sm
++BOOTIMAGE := $(bootimage-y)
++install: vmlinux
++      $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
++
+ archclean:
+       $(Q)$(MAKE) $(clean)=$(boot)
+Index: linux-2.6.0-test5/arch/ppc64/mm/fault.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/fault.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/fault.c    2003-09-27 11:38:19.887505024 +0800
+@@ -46,8 +46,10 @@
+ void bad_page_fault(struct pt_regs *, unsigned long, int);
+ /*
+- * For 600- and 800-family processors, the error_code parameter is DSISR
+- * for a data fault, SRR1 for an instruction fault.
++ * The error_code parameter is
++ *  - DSISR for a non-SLB data access fault,
++ *  - SRR1 & 0x08000000 for a non-SLB instruction access fault
++ *  - 0 any SLB fault.
+  */
+ void do_page_fault(struct pt_regs *regs, unsigned long address,
+                  unsigned long error_code)
+@@ -58,17 +60,6 @@
+       unsigned long code = SEGV_MAPERR;
+       unsigned long is_write = error_code & 0x02000000;
+-      /*
+-       * Fortunately the bit assignments in SRR1 for an instruction
+-       * fault and DSISR for a data fault are mostly the same for the
+-       * bits we are interested in.  But there are some bits which
+-       * indicate errors in DSISR but can validly be set in SRR1.
+-       */
+-      if (regs->trap == 0x400)
+-              error_code &= 0x48200000;
+-      else if (regs->trap != 0x300) /* ensure error_code is 0 on SLB miss */
+-              error_code = 0;
+-
+ #ifdef CONFIG_DEBUG_KERNEL
+       if (debugger_fault_handler && (regs->trap == 0x300 ||
+                                      regs->trap == 0x380)) {
+Index: linux-2.6.0-test5/arch/ppc64/mm/hugetlbpage.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/hugetlbpage.c 2003-09-27 11:38:18.439725120 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/hugetlbpage.c      2003-09-27 11:38:19.889504720 +0800
+@@ -0,0 +1,925 @@
++/*
++ * PPC64 (POWER4) Huge TLB Page Support for Kernel.
++ *
++ * Copyright (C) 2003 David Gibson, IBM Corporation.
++ *
++ * Based on the IA-32 version:
++ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
++ */
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/mm.h>
++#include <linux/hugetlb.h>
++#include <linux/pagemap.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/sysctl.h>
++#include <asm/mman.h>
++#include <asm/pgalloc.h>
++#include <asm/tlb.h>
++#include <asm/tlbflush.h>
++#include <asm/mmu_context.h>
++#include <asm/machdep.h>
++#include <asm/cputable.h>
++#include <asm/tlb.h>
++#include <asm/rmap.h>
++
++#include <linux/sysctl.h>
++
++int htlbpage_max;
++
++/* This lock protects the two counters and list below */
++static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
++
++static int htlbpage_free; /* = 0 */
++static int htlbpage_total; /* = 0 */
++static struct list_head hugepage_freelists[MAX_NUMNODES];
++
++static void enqueue_huge_page(struct page *page)
++{
++      list_add(&page->list,
++              &hugepage_freelists[page_zone(page)->zone_pgdat->node_id]);
++}
++
++/* XXX make this a sysctl */
++unsigned long largepage_roundrobin = 1;
++
++static struct page *dequeue_huge_page(void)
++{
++      static int nid = 0;
++      struct page *page = NULL;
++      int i;
++
++      if (!largepage_roundrobin)
++              nid = numa_node_id();
++
++      for (i = 0; i < numnodes; i++) {
++              if (!list_empty(&hugepage_freelists[nid]))
++                      break;
++              nid = (nid + 1) % numnodes;
++      }
++
++      if (!list_empty(&hugepage_freelists[nid])) {
++              page = list_entry(hugepage_freelists[nid].next, struct page, list);
++              list_del(&page->list);
++      }
++
++      if (largepage_roundrobin)
++              nid = (nid + 1) % numnodes;
++
++      return page;
++}
++
++static struct page *alloc_fresh_huge_page(void)
++{
++      static int nid = 0;
++      struct page *page;
++
++      page = alloc_pages_node(nid, GFP_HIGHUSER, HUGETLB_PAGE_ORDER);
++      if (!page)
++              return NULL;
++
++      nid = page_zone(page)->zone_pgdat->node_id;
++      nid = (nid + 1) % numnodes;
++      return page;
++}
++
++/* HugePTE layout:
++ *
++ * 31 30 ... 15 14 13 12 10 9  8  7   6    5    4    3    2    1    0
++ * PFN>>12..... -  -  -  -  -  -  HASH_IX....   2ND  HASH RW   -    HG=1
++ */
++
++#define HUGEPTE_SHIFT 15
++#define _HUGEPAGE_PFN         0xffff8000
++#define _HUGEPAGE_BAD         0x00007f00
++#define _HUGEPAGE_HASHPTE     0x00000008
++#define _HUGEPAGE_SECONDARY   0x00000010
++#define _HUGEPAGE_GROUP_IX    0x000000e0
++#define _HUGEPAGE_HPTEFLAGS   (_HUGEPAGE_HASHPTE | _HUGEPAGE_SECONDARY | \
++                               _HUGEPAGE_GROUP_IX)
++#define _HUGEPAGE_RW          0x00000004
++
++typedef struct {unsigned int val;} hugepte_t;
++#define hugepte_val(hugepte)  ((hugepte).val)
++#define __hugepte(x)          ((hugepte_t) { (x) } )
++#define hugepte_pfn(x)                \
++      ((unsigned long)(hugepte_val(x)>>HUGEPTE_SHIFT) << HUGETLB_PAGE_ORDER)
++#define mk_hugepte(page,wr)   __hugepte( \
++      ((page_to_pfn(page)>>HUGETLB_PAGE_ORDER) << HUGEPTE_SHIFT ) \
++      | (!!(wr) * _HUGEPAGE_RW) | _PMD_HUGEPAGE )
++
++#define hugepte_bad(x)        ( !(hugepte_val(x) & _PMD_HUGEPAGE) || \
++                        (hugepte_val(x) & _HUGEPAGE_BAD) )
++#define hugepte_page(x)       pfn_to_page(hugepte_pfn(x))
++#define hugepte_none(x)       (!(hugepte_val(x) & _HUGEPAGE_PFN))
++
++
++static void free_huge_page(struct page *page);
++static void flush_hash_hugepage(mm_context_t context, unsigned long ea,
++                              hugepte_t pte, int local);
++
++static inline unsigned int hugepte_update(hugepte_t *p, unsigned int clr,
++                                        unsigned int set)
++{
++      unsigned int old, tmp;
++
++      __asm__ __volatile__(
++      "1:     lwarx   %0,0,%3         # pte_update\n\
++      andc    %1,%0,%4 \n\
++      or      %1,%1,%5 \n\
++      stwcx.  %1,0,%3 \n\
++      bne-    1b"
++      : "=&r" (old), "=&r" (tmp), "=m" (*p)
++      : "r" (p), "r" (clr), "r" (set), "m" (*p)
++      : "cc" );
++      return old;
++}
++
++static inline void set_hugepte(hugepte_t *ptep, hugepte_t pte)
++{
++      hugepte_update(ptep, ~_HUGEPAGE_HPTEFLAGS,
++                     hugepte_val(pte) & ~_HUGEPAGE_HPTEFLAGS);
++}
++
++static struct page *alloc_hugetlb_page(void)
++{
++      int i;
++      struct page *page;
++
++      spin_lock(&htlbpage_lock);
++      page = dequeue_huge_page();
++      if (!page) {
++              spin_unlock(&htlbpage_lock);
++              return NULL;
++      }
++
++      htlbpage_free--;
++      spin_unlock(&htlbpage_lock);
++      set_page_count(page, 1);
++      page->lru.prev = (void *)free_huge_page;
++      for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
++              clear_highpage(&page[i]);
++      return page;
++}
++
++static hugepte_t *hugepte_alloc(struct mm_struct *mm, unsigned long addr)
++{
++      pgd_t *pgd;
++      pmd_t *pmd = NULL;
++
++      BUG_ON(!in_hugepage_area(mm->context, addr));
++
++      pgd = pgd_offset(mm, addr);
++      pmd = pmd_alloc(mm, pgd, addr);
++
++      /* We shouldn't find a (normal) PTE page pointer here */
++      BUG_ON(!pmd_none(*pmd) && !pmd_hugepage(*pmd));
++      
++      return (hugepte_t *)pmd;
++}
++
++static hugepte_t *hugepte_offset(struct mm_struct *mm, unsigned long addr)
++{
++      pgd_t *pgd;
++      pmd_t *pmd = NULL;
++
++      BUG_ON(!in_hugepage_area(mm->context, addr));
++
++      pgd = pgd_offset(mm, addr);
++      pmd = pmd_offset(pgd, addr);
++
++      /* We shouldn't find a (normal) PTE page pointer here */
++      BUG_ON(!pmd_none(*pmd) && !pmd_hugepage(*pmd));
++
++      return (hugepte_t *)pmd;
++}
++
++static void setup_huge_pte(struct mm_struct *mm, struct page *page,
++                         hugepte_t *ptep, int write_access)
++{
++      hugepte_t entry;
++      int i;
++
++      mm->rss += (HPAGE_SIZE / PAGE_SIZE);
++      entry = mk_hugepte(page, write_access);
++      for (i = 0; i < HUGEPTE_BATCH_SIZE; i++)
++              set_hugepte(ptep+i, entry);
++}
++
++static void teardown_huge_pte(hugepte_t *ptep)
++{
++      int i;
++
++      for (i = 0; i < HUGEPTE_BATCH_SIZE; i++)
++              pmd_clear((pmd_t *)(ptep+i));
++}
++
++/*
++ * This function checks for proper alignment of input addr and len parameters.
++ */
++int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
++{
++      if (len & ~HPAGE_MASK)
++              return -EINVAL;
++      if (addr & ~HPAGE_MASK)
++              return -EINVAL;
++      if (! is_hugepage_only_range(addr, len))
++              return -EINVAL;
++      return 0;
++}
++
++static void do_slbia(void *unused)
++{
++      asm volatile ("isync; slbia; isync":::"memory");
++}
++
++/* Activate the low hpage region for 32bit processes.  mmap_sem must
++ * be held*/
++static int open_32bit_htlbpage_range(struct mm_struct *mm)
++{
++      struct vm_area_struct *vma;
++      unsigned long addr;
++
++      if (mm->context & CONTEXT_LOW_HPAGES)
++              return 0; /* The window is already open */
++      
++      /* Check no VMAs are in the region */
++      vma = find_vma(mm, TASK_HPAGE_BASE_32);
++
++      if (vma && (vma->vm_start < TASK_HPAGE_END_32))
++              return -EBUSY;
++
++      /* Clean up any leftover PTE pages in the region */
++      spin_lock(&mm->page_table_lock);
++      for (addr = TASK_HPAGE_BASE_32; addr < TASK_HPAGE_END_32;
++           addr += PMD_SIZE) {
++              pgd_t *pgd = pgd_offset(mm, addr);
++              pmd_t *pmd = pmd_offset(pgd, addr);
++
++              if (! pmd_none(*pmd)) {
++                      struct page *page = pmd_page(*pmd);
++                      pte_t *pte = (pte_t *)pmd_page_kernel(*pmd);
++                      int i;
++
++                      /* No VMAs, so there should be no PTEs, check
++                       * just in case. */
++                      for (i = 0; i < PTRS_PER_PTE; i++) {
++                              BUG_ON(! pte_none(*pte));
++                              pte++;
++                      }
++
++                      pmd_clear(pmd);
++                      pgtable_remove_rmap(page);
++                      pte_free(page);
++              }
++      }
++      spin_unlock(&mm->page_table_lock);
++
++      /* FIXME: do we need to scan for PTEs too? */
++
++      mm->context |= CONTEXT_LOW_HPAGES;
++
++      /* the context change must make it to memory before the slbia,
++       * so that further SLB misses do the right thing. */
++      mb();
++
++      on_each_cpu(do_slbia, NULL, 0, 1);
++
++      return 0;
++}
++
++int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
++                      struct vm_area_struct *vma)
++{
++      hugepte_t *src_pte, *dst_pte, entry;
++      struct page *ptepage;
++      unsigned long addr = vma->vm_start;
++      unsigned long end = vma->vm_end;
++
++      while (addr < end) {
++              BUG_ON(! in_hugepage_area(src->context, addr));
++              BUG_ON(! in_hugepage_area(dst->context, addr));
++
++              dst_pte = hugepte_alloc(dst, addr);
++              if (!dst_pte)
++                      return -ENOMEM;
++
++              src_pte = hugepte_offset(src, addr);
++              entry = *src_pte;
++              
++              if ((addr % HPAGE_SIZE) == 0) {
++                      /* This is the first hugepte in a batch */
++                      ptepage = hugepte_page(entry);
++                      get_page(ptepage);
++                      dst->rss += (HPAGE_SIZE / PAGE_SIZE);
++              }
++              set_hugepte(dst_pte, entry);
++
++
++              addr += PMD_SIZE;
++      }
++      return 0;
++}
++
++int
++follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
++                  struct page **pages, struct vm_area_struct **vmas,
++                  unsigned long *position, int *length, int i)
++{
++      unsigned long vpfn, vaddr = *position;
++      int remainder = *length;
++
++      WARN_ON(!is_vm_hugetlb_page(vma));
++
++      vpfn = vaddr/PAGE_SIZE;
++      while (vaddr < vma->vm_end && remainder) {
++              BUG_ON(!in_hugepage_area(mm->context, vaddr));
++
++              if (pages) {
++                      hugepte_t *pte;
++                      struct page *page;
++
++                      pte = hugepte_offset(mm, vaddr);
++
++                      /* hugetlb should be locked, and hence, prefaulted */
++                      WARN_ON(!pte || hugepte_none(*pte));
++
++                      page = &hugepte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
++
++                      WARN_ON(!PageCompound(page));
++
++                      get_page(page);
++                      pages[i] = page;
++              }
++
++              if (vmas)
++                      vmas[i] = vma;
++
++              vaddr += PAGE_SIZE;
++              ++vpfn;
++              --remainder;
++              ++i;
++      }
++
++      *length = remainder;
++      *position = vaddr;
++
++      return i;
++}
++
++struct page *
++follow_huge_addr(struct mm_struct *mm,
++      struct vm_area_struct *vma, unsigned long address, int write)
++{
++      return NULL;
++}
++
++struct vm_area_struct *hugepage_vma(struct mm_struct *mm, unsigned long addr)
++{
++      return NULL;
++}
++
++int pmd_huge(pmd_t pmd)
++{
++      return pmd_hugepage(pmd);
++}
++
++struct page *
++follow_huge_pmd(struct mm_struct *mm, unsigned long address,
++              pmd_t *pmd, int write)
++{
++      struct page *page;
++
++      BUG_ON(! pmd_hugepage(*pmd));
++
++      page = hugepte_page(*(hugepte_t *)pmd);
++      if (page) {
++              page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
++              get_page(page);
++      }
++      return page;
++}
++
++static void free_huge_page(struct page *page)
++{
++      BUG_ON(page_count(page));
++      BUG_ON(page->mapping);
++
++      INIT_LIST_HEAD(&page->list);
++
++      spin_lock(&htlbpage_lock);
++      enqueue_huge_page(page);
++      htlbpage_free++;
++      spin_unlock(&htlbpage_lock);
++}
++
++void huge_page_release(struct page *page)
++{
++      if (!put_page_testzero(page))
++              return;
++
++      free_huge_page(page);
++}
++
++void unmap_hugepage_range(struct vm_area_struct *vma,
++                        unsigned long start, unsigned long end)
++{
++      struct mm_struct *mm = vma->vm_mm;
++      unsigned long addr;
++      hugepte_t *ptep;
++      struct page *page;
++      int local = 0;
++      cpumask_t tmp;
++
++      WARN_ON(!is_vm_hugetlb_page(vma));
++      BUG_ON((start % HPAGE_SIZE) != 0);
++      BUG_ON((end % HPAGE_SIZE) != 0);
++
++      /* XXX are there races with checking cpu_vm_mask? - Anton */
++      tmp = cpumask_of_cpu(smp_processor_id());
++      if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
++              local = 1;
++
++      for (addr = start; addr < end; addr += HPAGE_SIZE) {
++              hugepte_t pte;
++
++              BUG_ON(!in_hugepage_area(mm->context, addr));
++
++              ptep = hugepte_offset(mm, addr);
++              if (!ptep || hugepte_none(*ptep))
++                      continue;
++
++              pte = *ptep;
++              page = hugepte_page(pte);
++              teardown_huge_pte(ptep);
++              
++              if (hugepte_val(pte) & _HUGEPAGE_HASHPTE)
++                      flush_hash_hugepage(mm->context, addr,
++                                          pte, local);
++
++              huge_page_release(page);
++      }
++
++      mm->rss -= (end - start) >> PAGE_SHIFT;
++}
++
++void zap_hugepage_range(struct vm_area_struct *vma,
++                      unsigned long start, unsigned long length)
++{
++      struct mm_struct *mm = vma->vm_mm;
++
++      spin_lock(&mm->page_table_lock);
++      unmap_hugepage_range(vma, start, start + length);
++      spin_unlock(&mm->page_table_lock);
++}
++
++int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
++{
++      struct mm_struct *mm = current->mm;
++      unsigned long addr;
++      int ret = 0;
++
++      WARN_ON(!is_vm_hugetlb_page(vma));
++      BUG_ON((vma->vm_start % HPAGE_SIZE) != 0);
++      BUG_ON((vma->vm_end % HPAGE_SIZE) != 0);
++
++      spin_lock(&mm->page_table_lock);
++      for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
++              unsigned long idx;
++              hugepte_t *pte = hugepte_alloc(mm, addr);
++              struct page *page;
++
++              BUG_ON(!in_hugepage_area(mm->context, addr));
++
++              if (!pte) {
++                      ret = -ENOMEM;
++                      goto out;
++              }
++              if (!hugepte_none(*pte))
++                      continue;
++
++              idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
++                      + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
++              page = find_get_page(mapping, idx);
++              if (!page) {
++                      page = alloc_hugetlb_page();
++                      if (!page) {
++                              ret = -ENOMEM;
++                              goto out;
++                      }
++                      ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
++                      unlock_page(page);
++                      if (ret) {
++                              free_huge_page(page);
++                              goto out;
++                      }
++              }
++              setup_huge_pte(mm, page, pte, vma->vm_flags & VM_WRITE);
++      }
++out:
++      spin_unlock(&mm->page_table_lock);
++      return ret;
++}
++
++/* Because we have an exclusive hugepage region which lies within the
++ * normal user address space, we have to take special measures to make
++ * non-huge mmap()s evade the hugepage reserved region. */
++unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
++                                   unsigned long len, unsigned long pgoff,
++                                   unsigned long flags)
++{
++      struct mm_struct *mm = current->mm;
++      struct vm_area_struct *vma;
++      unsigned long start_addr;
++
++      if (len > TASK_SIZE)
++              return -ENOMEM;
++
++      if (addr) {
++              addr = PAGE_ALIGN(addr);
++              vma = find_vma(mm, addr);
++              if (TASK_SIZE - len >= addr &&
++                  (!vma || addr + len <= vma->vm_start) &&
++                  !is_hugepage_only_range(addr,len))
++                      return addr;
++      }
++      start_addr = addr = mm->free_area_cache;
++
++full_search:
++      for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
++              /* At this point:  (!vma || addr < vma->vm_end). */
++              if (TASK_SIZE - len < addr) {
++                      /*
++                       * Start a new search - just in case we missed
++                       * some holes.
++                       */
++                      if (start_addr != TASK_UNMAPPED_BASE) {
++                              start_addr = addr = TASK_UNMAPPED_BASE;
++                              goto full_search;
++                      }
++                      return -ENOMEM;
++              }
++              if (!vma || addr + len <= vma->vm_start) {
++                      if (is_hugepage_only_range(addr, len)) {
++                              if (addr < TASK_HPAGE_END_32)
++                                      addr = TASK_HPAGE_END_32;
++                              else
++                                      addr = TASK_HPAGE_END;
++
++                              continue;
++                      }
++                      /*
++                       * Remember the place where we stopped the search:
++                       */
++                      mm->free_area_cache = addr + len;
++                      return addr;
++              }
++              addr = vma->vm_end;
++      }
++}
++
++
++unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
++                                      unsigned long len, unsigned long pgoff,
++                                      unsigned long flags)
++{
++      struct vm_area_struct *vma;
++      unsigned long base, end;
++
++      if (len & ~HPAGE_MASK)
++              return -EINVAL;
++
++      if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE))
++              return -EINVAL;
++
++      if (test_thread_flag(TIF_32BIT)) {
++              int err;
++
++              err = open_32bit_htlbpage_range(current->mm);
++              if (err)
++                      return err; /* Should this just be EINVAL? */
++
++              base = TASK_HPAGE_BASE_32;
++              end = TASK_HPAGE_END_32;
++      } else {
++              base = TASK_HPAGE_BASE;
++              end = TASK_HPAGE_END;
++      }
++      
++      if (!in_hugepage_area(current->mm->context, addr) 
++          || (addr & (HPAGE_SIZE - 1)))
++              addr = base;
++
++      for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
++              /* At this point:  (!vma || addr < vma->vm_end). */
++              if (addr + len > end)
++                      return -ENOMEM;
++              if (!vma || (addr + len) <= vma->vm_start)
++                      return addr;
++              addr = ALIGN(vma->vm_end, HPAGE_SIZE);
++
++              /* Because we're in an exclusively hugepage region,
++               * this alignment shouldn't have skipped over any
++               * other vmas */
++      }
++}
++
++static inline unsigned long computeHugeHptePP(unsigned int hugepte)
++{
++      unsigned long flags = 0x2;
++
++      if (! (hugepte & _HUGEPAGE_RW))
++              flags |= 0x1;
++      return flags;
++}
++
++int hash_huge_page(struct mm_struct *mm, unsigned long access,
++                 unsigned long ea, unsigned long vsid, int local)
++{
++      hugepte_t *ptep;
++      unsigned long va, vpn;
++      int is_write;
++      hugepte_t old_pte, new_pte;
++      unsigned long hpteflags, prpn;
++      long slot;
++
++      /* Is this for us? */
++      if (!in_hugepage_area(mm->context, ea))
++              return -1;
++
++      ea &= ~(HPAGE_SIZE-1);
++
++      /* We have to find the first hugepte in the batch, since
++       * that's the one that will store the HPTE flags */
++      ptep = hugepte_offset(mm, ea);
++
++      /* Search the Linux page table for a match with va */
++      va = (vsid << 28) | (ea & 0x0fffffff);
++      vpn = va >> HPAGE_SHIFT;
++
++      /*
++       * If no pte found or not present, send the problem up to
++       * do_page_fault
++       */
++      if (unlikely(!ptep || hugepte_none(*ptep)))
++              return 1;
++
++      BUG_ON(hugepte_bad(*ptep));
++
++      /* 
++       * Check the user's access rights to the page.  If access should be
++       * prevented then send the problem up to do_page_fault.
++       */
++      is_write = access & _PAGE_RW;
++      if (unlikely(is_write && !(hugepte_val(*ptep) & _HUGEPAGE_RW)))
++              return 1;
++
++      /*
++       * At this point, we have a pte (old_pte) which can be used to build
++       * or update an HPTE. There are 2 cases:
++       *
++       * 1. There is a valid (present) pte with no associated HPTE (this is 
++       *      the most common case)
++       * 2. There is a valid (present) pte with an associated HPTE. The
++       *      current values of the pp bits in the HPTE prevent access
++       *      because we are doing software DIRTY bit management and the
++       *      page is currently not DIRTY. 
++       */
++
++      old_pte = *ptep;
++      new_pte = old_pte;
++
++      hpteflags = computeHugeHptePP(hugepte_val(new_pte));
++
++      /* Check if pte already has an hpte (case 2) */
++      if (unlikely(hugepte_val(old_pte) & _HUGEPAGE_HASHPTE)) {
++              /* There MIGHT be an HPTE for this pte */
++              unsigned long hash, slot;
++
++              hash = hpt_hash(vpn, 1);
++              if (hugepte_val(old_pte) & _HUGEPAGE_SECONDARY)
++                      hash = ~hash;
++              slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
++              slot += (hugepte_val(old_pte) & _HUGEPAGE_GROUP_IX) >> 5;
++
++              if (ppc_md.hpte_updatepp(slot, hpteflags, va, 1, local) == -1)
++                      hugepte_val(old_pte) &= ~_HUGEPAGE_HPTEFLAGS;
++      }
++
++      if (likely(!(hugepte_val(old_pte) & _HUGEPAGE_HASHPTE))) {
++              unsigned long hash = hpt_hash(vpn, 1);
++              unsigned long hpte_group;
++
++              prpn = hugepte_pfn(old_pte);
++
++repeat:
++              hpte_group = ((hash & htab_data.htab_hash_mask) *
++                            HPTES_PER_GROUP) & ~0x7UL;
++
++              /* Update the linux pte with the HPTE slot */
++              hugepte_val(new_pte) &= ~_HUGEPAGE_HPTEFLAGS;
++              hugepte_val(new_pte) |= _HUGEPAGE_HASHPTE;
++
++              /* Add in WIMG bits */
++              /* XXX We should store these in the pte */
++              hpteflags |= _PAGE_COHERENT;
++
++              slot = ppc_md.hpte_insert(hpte_group, va, prpn, 0,
++                                        hpteflags, 0, 1);
++
++              /* Primary is full, try the secondary */
++              if (unlikely(slot == -1)) {
++                      hugepte_val(new_pte) |= _HUGEPAGE_SECONDARY;
++                      hpte_group = ((~hash & htab_data.htab_hash_mask) *
++                                    HPTES_PER_GROUP) & ~0x7UL; 
++                      slot = ppc_md.hpte_insert(hpte_group, va, prpn,
++                                                1, hpteflags, 0, 1);
++                      if (slot == -1) {
++                              if (mftb() & 0x1)
++                                      hpte_group = ((hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
++
++                              ppc_md.hpte_remove(hpte_group);
++                              goto repeat;
++                        }
++              }
++
++              if (unlikely(slot == -2))
++                      panic("hash_huge_page: pte_insert failed\n");
++
++              hugepte_val(new_pte) |= (slot<<5) & _HUGEPAGE_GROUP_IX;
++
++              /* 
++               * No need to use ldarx/stdcx here because all who
++               * might be updating the pte will hold the
++               * page_table_lock or the hash_table_lock
++               * (we hold both)
++               */
++              *ptep = new_pte;
++      }
++
++      return 0;
++}
++
++static void flush_hash_hugepage(mm_context_t context, unsigned long ea,
++                              hugepte_t pte, int local)
++{
++      unsigned long vsid, vpn, va, hash, secondary, slot;
++
++      BUG_ON(hugepte_bad(pte));
++      BUG_ON(!in_hugepage_area(context, ea));
++
++      vsid = get_vsid(context, ea);
++
++      va = (vsid << 28) | (ea & 0x0fffffff);
++      vpn = va >> LARGE_PAGE_SHIFT;
++      hash = hpt_hash(vpn, 1);
++      secondary = !!(hugepte_val(pte) & _HUGEPAGE_SECONDARY);
++      if (secondary)
++              hash = ~hash;
++      slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
++      slot += (hugepte_val(pte) & _HUGEPAGE_GROUP_IX) >> 5;
++
++      ppc_md.hpte_invalidate(slot, va, 1, local);
++}
++
++static void split_and_free_hugepage(struct page *page)
++{
++      int j;
++      struct page *map;
++
++      map = page;
++      htlbpage_total--;
++      for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
++              map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
++                              1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
++                              1 << PG_private | 1<< PG_writeback);
++              set_page_count(map, 0);
++              map++;
++      }
++      set_page_count(page, 1);
++      __free_pages(page, HUGETLB_PAGE_ORDER);
++}
++
++int set_hugetlb_mem_size(int count)
++{
++      int lcount;
++      struct page *page;
++
++      if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE))
++              return 0;
++      
++      if (count < 0)
++              lcount = count;
++      else
++              lcount = count - htlbpage_total;
++
++      if (lcount == 0)
++              return htlbpage_total;
++      if (lcount > 0) {       /* Increase the mem size. */
++              while (lcount--) {
++                      page = alloc_fresh_huge_page();
++                      if (page == NULL)
++                              break;
++                      spin_lock(&htlbpage_lock);
++                      enqueue_huge_page(page);
++                      htlbpage_free++;
++                      htlbpage_total++;
++                      spin_unlock(&htlbpage_lock);
++              }
++              return htlbpage_total;
++      }
++      /* Shrink the memory size. */
++      while (lcount++) {
++              page = alloc_hugetlb_page();
++              if (page == NULL)
++                      break;
++              spin_lock(&htlbpage_lock);
++              split_and_free_hugepage(page);
++              spin_unlock(&htlbpage_lock);
++      }
++      return htlbpage_total;
++}
++
++int hugetlb_sysctl_handler(ctl_table *table, int write,
++              struct file *file, void *buffer, size_t *length)
++{
++      proc_dointvec(table, write, file, buffer, length);
++      htlbpage_max = set_hugetlb_mem_size(htlbpage_max);
++      return 0;
++}
++
++static int __init hugetlb_setup(char *s)
++{
++      if (sscanf(s, "%d", &htlbpage_max) <= 0)
++              htlbpage_max = 0;
++      return 1;
++}
++__setup("hugepages=", hugetlb_setup);
++
++static int __init hugetlb_init(void)
++{
++      int i;
++      struct page *page;
++
++      if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) {
++              for (i = 0; i < MAX_NUMNODES; ++i)
++                      INIT_LIST_HEAD(&hugepage_freelists[i]);
++
++              for (i = 0; i < htlbpage_max; ++i) {
++                      page = alloc_fresh_huge_page();
++                      if (!page)
++                              break;
++                      spin_lock(&htlbpage_lock);
++                      enqueue_huge_page(page);
++                      spin_unlock(&htlbpage_lock);
++              }
++              htlbpage_max = htlbpage_free = htlbpage_total = i;
++              printk("Total HugeTLB memory allocated, %d\n", htlbpage_free);
++      } else {
++              htlbpage_max = 0;
++              printk("CPU does not support HugeTLB\n");
++      }
++
++      return 0;
++}
++module_init(hugetlb_init);
++
++int hugetlb_report_meminfo(char *buf)
++{
++      return sprintf(buf,
++                      "HugePages_Total: %5d\n"
++                      "HugePages_Free:  %5d\n"
++                      "Hugepagesize:    %5lu kB\n",
++                      htlbpage_total,
++                      htlbpage_free,
++                      HPAGE_SIZE/1024);
++}
++
++/* This is advisory only, so we can get away with accesing
++ * htlbpage_free without taking the lock. */
++int is_hugepage_mem_enough(size_t size)
++{
++      return (size + ~HPAGE_MASK)/HPAGE_SIZE <= htlbpage_free;
++}
++
++/*
++ * We cannot handle pagefaults against hugetlb pages at all.  They cause
++ * handle_mm_fault() to try to instantiate regular-sized pages in the
++ * hugegpage VMA.  do_page_fault() is supposed to trap this, so BUG is we get
++ * this far.
++ */
++static struct page *hugetlb_nopage(struct vm_area_struct *vma,
++                              unsigned long address, int unused)
++{
++      BUG();
++      return NULL;
++}
++
++struct vm_operations_struct hugetlb_vm_ops = {
++      .nopage = hugetlb_nopage,
++};
+Index: linux-2.6.0-test5/arch/ppc64/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/init.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/init.c     2003-09-27 11:38:19.894503960 +0800
+@@ -290,7 +290,7 @@
+       if (!pgd_none(*pgd)) {
+               pmd = pmd_offset(pgd, vmaddr);
+-              if (!pmd_none(*pmd)) {
++              if (pmd_present(*pmd)) {
+                       ptep = pte_offset_kernel(pmd, vmaddr);
+                       /* Check if HPTE might exist and flush it if so */
+                       pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
+@@ -298,6 +298,7 @@
+                               flush_hash_page(context, vmaddr, pte, local);
+                       }
+               }
++              WARN_ON(pmd_hugepage(*pmd));
+       }
+ }
+@@ -348,7 +349,7 @@
+                               pmd_end = (start + PMD_SIZE) & PMD_MASK;
+                               if (pmd_end > end)
+                                       pmd_end = end;
+-                              if (!pmd_none(*pmd)) {
++                              if (pmd_present(*pmd)) {
+                                       ptep = pte_offset_kernel(pmd, start);
+                                       do {
+                                               if (pte_val(*ptep) & _PAGE_HASHPTE) {
+@@ -367,6 +368,7 @@
+                                               ++ptep;
+                                       } while (start < pmd_end);
+                               } else {
++                                      WARN_ON(pmd_hugepage(*pmd));
+                                       start = pmd_end;
+                               }
+                               ++pmd;
+@@ -540,8 +542,6 @@
+ }
+ module_init(setup_kcore);
+-void initialize_paca_hardware_interrupt_stack(void);
+-
+ void __init mem_init(void)
+ {
+ #ifndef CONFIG_DISCONTIGMEM
+@@ -608,9 +608,6 @@
+ #endif
+       mem_init_done = 1;
+-      /* set the last page of each hardware interrupt stack to be protected */
+-      initialize_paca_hardware_interrupt_stack();
+-
+ #ifdef CONFIG_PPC_ISERIES
+       create_virtual_bus_tce_table();
+ #endif
+Index: linux-2.6.0-test5/arch/ppc64/mm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/Makefile      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/Makefile   2003-09-27 11:38:19.896503656 +0800
+@@ -6,3 +6,4 @@
+ obj-y := fault.o init.o extable.o imalloc.o
+ obj-$(CONFIG_DISCONTIGMEM) += numa.o
++obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+Index: linux-2.6.0-test5/arch/ppc64/mm/numa.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/mm/numa.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/mm/numa.c     2003-09-27 11:38:19.898503352 +0800
+@@ -24,18 +24,21 @@
+ int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] = -1};
+ int numa_memory_lookup_table[MAX_MEMORY >> MEMORY_INCREMENT_SHIFT] =
+       { [ 0 ... ((MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1)] = -1};
+-unsigned long numa_cpumask_lookup_table[MAX_NUMNODES];
++cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
+ int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0};
+ struct pglist_data node_data[MAX_NUMNODES];
+ bootmem_data_t plat_node_bdata[MAX_NUMNODES];
++EXPORT_SYMBOL(node_data);
++EXPORT_SYMBOL(numa_memory_lookup_table);
++
+ static inline void map_cpu_to_node(int cpu, int node)
+ {
+       dbg("cpu %d maps to domain %d\n", cpu, node);
+       numa_cpu_lookup_table[cpu] = node;
+-      if (!(numa_cpumask_lookup_table[node] & 1UL << cpu)) {
+-              numa_cpumask_lookup_table[node] |= 1UL << cpu;
++      if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) {
++              cpu_set(cpu, numa_cpumask_lookup_table[node]);
+               nr_cpus_in_node[node]++;
+       }
+ }
+Index: linux-2.6.0-test5/arch/ppc64/xmon/xmon.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc64/xmon/xmon.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc64/xmon/xmon.c   2003-09-27 11:38:19.922499704 +0800
+@@ -15,6 +15,8 @@
+ #include <linux/mm.h>
+ #include <linux/reboot.h>
+ #include <linux/delay.h>
++#include <linux/kallsyms.h>
++
+ #include <asm/ptrace.h>
+ #include <asm/string.h>
+ #include <asm/prom.h>
+@@ -27,6 +29,7 @@
+ #include <asm/paca.h>
+ #include <asm/ppcdebug.h>
+ #include <asm/cputable.h>
++
+ #include "nonstdio.h"
+ #include "privinst.h"
+@@ -59,7 +62,6 @@
+       unsigned instr;
+       unsigned long count;
+       unsigned char enabled;
+-      char funcname[64];      /* function name for humans */
+ };
+ #define NBPTS 16
+@@ -79,14 +81,9 @@
+ static int bsesc(void);
+ static void dump(void);
+ static void prdump(unsigned long, long);
+-#ifdef __MWERKS__
+-static void prndump(unsigned, int);
+-static int nvreadb(unsigned);
+-#endif
+ static int ppc_inst_dump(unsigned long, long);
+ void print_address(unsigned long);
+ static int getsp(void);
+-static void dump_hash_table(void);
+ static void backtrace(struct pt_regs *);
+ static void excprint(struct pt_regs *);
+ static void prregs(struct pt_regs *);
+@@ -106,7 +103,6 @@
+ static unsigned long read_spr(int);
+ static void write_spr(int, unsigned long);
+ static void super_regs(void);
+-static void print_sysmap(void);
+ static void remove_bpts(void);
+ static void insert_bpts(void);
+ static struct bpt *at_breakpoint(unsigned long pc);
+@@ -158,7 +154,6 @@
+   dd  dump double values\n\
+   e   print exception information\n\
+   f   flush cache\n\
+-  h   dump hash table\n\
+   m   examine/change memory\n\
+   mm  move a block of memory\n\
+   ms  set a block of memory\n\
+@@ -183,6 +178,13 @@
+ static struct pt_regs *xmon_regs[NR_CPUS];
++void __xmon_print_symbol(const char *fmt, unsigned long address);
++#define xmon_print_symbol(fmt, addr)          \
++do {                                          \
++      __check_printsym_format(fmt, "");       \
++      __xmon_print_symbol(fmt, addr);         \
++} while(0)
++
+ /*
+  * Stuff for reading and writing memory safely
+  */
+@@ -211,42 +213,6 @@
+  no functions have been called from the current function.
+  */
+-/*
+- A traceback table typically follows each function.
+- The find_tb_table() func will fill in this struct.  Note that the struct
+- is not an exact match with the encoded table defined by the ABI.  It is
+- defined here more for programming convenience.
+- */
+-struct tbtable {
+-      unsigned long   flags;          /* flags: */
+-#define TBTAB_FLAGSGLOBALLINK (1L<<47)
+-#define TBTAB_FLAGSISEPROL    (1L<<46)
+-#define TBTAB_FLAGSHASTBOFF   (1L<<45)
+-#define TBTAB_FLAGSINTPROC    (1L<<44)
+-#define TBTAB_FLAGSHASCTL     (1L<<43)
+-#define TBTAB_FLAGSTOCLESS    (1L<<42)
+-#define TBTAB_FLAGSFPPRESENT  (1L<<41)
+-#define TBTAB_FLAGSNAMEPRESENT        (1L<<38)
+-#define TBTAB_FLAGSUSESALLOCA (1L<<37)
+-#define TBTAB_FLAGSSAVESCR    (1L<<33)
+-#define TBTAB_FLAGSSAVESLR    (1L<<32)
+-#define TBTAB_FLAGSSTORESBC   (1L<<31)
+-#define TBTAB_FLAGSFIXUP      (1L<<30)
+-#define TBTAB_FLAGSPARMSONSTK (1L<<0)
+-      unsigned char   fp_saved;       /* num fp regs saved f(32-n)..f31 */
+-      unsigned char   gpr_saved;      /* num gpr's saved */
+-      unsigned char   fixedparms;     /* num fixed point parms */
+-      unsigned char   floatparms;     /* num float parms */
+-      unsigned char   parminfo[32];   /* types of args.  null terminated */
+-#define TBTAB_PARMFIXED 1
+-#define TBTAB_PARMSFLOAT 2
+-#define TBTAB_PARMDFLOAT 3
+-      unsigned int    tb_offset;      /* offset from start of func */
+-      unsigned long   funcstart;      /* addr of start of function */
+-      char            name[64];       /* name of function (null terminated)*/
+-};
+-static int find_tb_table(unsigned long codeaddr, struct tbtable *tab);
+-
+ #define SURVEILLANCE_TOKEN    9000
+ static inline void disable_surveillance(void)
+@@ -304,8 +270,7 @@
+                       std     29,232(%0)\n\
+                       std     30,240(%0)\n\
+                       std     31,248(%0)" : : "b" (&regs));
+-              /* Fetch the link reg for this stack frame.
+-               NOTE: the prev printf fills in the lr. */
++
+               regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
+               regs.msr = get_msr();
+               regs.ctr = get_ctr();
+@@ -380,7 +345,9 @@
+               xmon_trace[smp_processor_id()] = BRSTEP;
+               regs->msr |= MSR_SE;
+       } else {
+-              printf("Stopped at breakpoint %x (%lx %s)\n", (bp - bpts)+1, bp->address, bp->funcname);
++              printf("Stopped at breakpoint %x (%lx ", (bp - bpts) + 1,
++                      bp->address);
++              xmon_print_symbol("%s)\n", bp->address);
+               xmon(regs);
+       }
+       return 1;
+@@ -578,9 +545,6 @@
+                       else
+                               excprint(excp);
+                       break;
+-              case 'M':
+-                      print_sysmap();
+-                      break;
+               case 'S':
+                       super_regs();
+                       break;
+@@ -590,9 +554,6 @@
+               case 'f':
+                       cacheflush();
+                       break;
+-              case 'h':
+-                      dump_hash_table();
+-                      break;
+               case 's':
+               case 'x':
+               case EOF:
+@@ -773,7 +734,6 @@
+       unsigned long a;
+       int mode, i;
+       struct bpt *bp;
+-      struct tbtable tab;
+       cmd = inchar();
+       switch (cmd) {
+@@ -829,7 +789,9 @@
+                       if (bp == 0) {
+                               printf("No breakpoint at %x\n", a);
+                       } else {
+-                              printf("Cleared breakpoint %x (%lx %s)\n", (bp - bpts)+1, bp->address, bp->funcname);
++                              printf("Cleared breakpoint %x (%lx ", 
++                                      (bp - bpts) + 1, bp->address);
++                              xmon_print_symbol("%s)\n", bp->address);
+                               bp->enabled = 0;
+                       }
+               }
+@@ -863,8 +825,11 @@
+                               printf("   inst   %.16lx %8x\n", iabr.address & ~3,
+                                      iabr.count);
+                       for (bp = bpts, bpnum = 1; bp < &bpts[NBPTS]; ++bp, ++bpnum)
+-                              if (bp->enabled)
+-                                      printf("%2x trap   %.16lx %8x  %s\n", bpnum, bp->address, bp->count, bp->funcname);
++                              if (bp->enabled) {
++                                      printf("%2x trap   %.16lx %8x  ",
++                                              bpnum, bp->address, bp->count);
++                                      xmon_print_symbol("%s\n", bp->address);
++                              }
+                       break;
+               }
+               bp = at_breakpoint(a);
+@@ -881,14 +846,9 @@
+               bp->address = a;
+               bp->count = 0;
+               scanhex(&bp->count);
+-              /* Find the function name just once. */
+-              bp->funcname[0] = '\0';
+-              if (find_tb_table(bp->address, &tab) && tab.name[0]) {
+-                      /* Got a nice name for it. */
+-                      int delta = bp->address - tab.funcstart;
+-                      sprintf(bp->funcname, "%s+0x%x", tab.name, delta);
+-              }
+-              printf("Set breakpoint %2x trap   %.16lx %8x  %s\n", (bp-bpts)+1, bp->address, bp->count, bp->funcname);
++              printf("Set breakpoint %2x trap   %.16lx %8x  ", (bp-bpts) + 1, 
++                      bp->address, bp->count);
++              xmon_print_symbol("%s\n", bp->address);
+               break;
+       }
+ }
+@@ -925,7 +885,6 @@
+       unsigned long lr;
+       unsigned long stack[3];
+       struct pt_regs regs;
+-      struct tbtable tab;
+       int framecount;
+       char *funcname;
+       /* declare these as raw ptrs so we don't get func descriptors */
+@@ -971,17 +930,11 @@
+                               break;
+                       printf("exception: %lx %s regs %lx\n", regs.trap, getvecname(regs.trap), sp+112);
+                       printf("                  %.16lx", regs.nip);
+-                      if ((regs.nip & 0xffffffff00000000UL) &&
+-                          find_tb_table(regs.nip, &tab)) {
+-                              int delta = regs.nip-tab.funcstart;
+-                              if (delta < 0)
+-                                      printf("  <unknown code>");
+-                              else
+-                                      printf("  %s+0x%x", tab.name, delta);
+-                      }
++                      if (regs.nip & 0xffffffff00000000UL)
++                              xmon_print_symbol("  %s", regs.nip);
+                       printf("\n");
+                         if (regs.gpr[1] < sp) {
+-                            printf("<Stack drops into 32-bit userspace %.16lx>\n", regs.gpr[1]);
++                            printf("<Stack drops into userspace %.16lx>\n", regs.gpr[1]);
+                             break;
+                       }
+@@ -989,13 +942,8 @@
+                       if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
+                               break;
+               } else {
+-                      if (stack[2] && find_tb_table(stack[2], &tab)) {
+-                              int delta = stack[2]-tab.funcstart;
+-                              if (delta < 0)
+-                                      printf("  <unknown code>");
+-                              else
+-                                      printf("  %s+0x%x", tab.name, delta);
+-                      }
++                      if (stack[2])
++                              xmon_print_symbol("  %s", stack[2]);
+                       printf("\n");
+               }
+               if (stack[0] && stack[0] <= sp) {
+@@ -1024,8 +972,6 @@
+ void
+ excprint(struct pt_regs *fp)
+ {
+-      struct task_struct *c;
+-      struct tbtable tab;
+       unsigned long flags;
+       spin_lock_irqsave(&exception_print_lock, flags);
+@@ -1034,21 +980,13 @@
+       printf("cpu %d: ", smp_processor_id());
+ #endif /* CONFIG_SMP */
+-      printf("Vector: %lx %s at  [%lx]\n", fp->trap, getvecname(fp->trap), fp);
++      printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(fp->trap), fp);
+       printf("    pc: %lx", fp->nip);
+-      if (find_tb_table(fp->nip, &tab) && tab.name[0]) {
+-              /* Got a nice name for it */
+-              int delta = fp->nip - tab.funcstart;
+-              printf(" (%s+0x%x)", tab.name, delta);
+-      }
+-      printf("\n");
++      xmon_print_symbol(" (%s)\n", fp->nip);
++
+       printf("    lr: %lx", fp->link);
+-      if (find_tb_table(fp->link, &tab) && tab.name[0]) {
+-              /* Got a nice name for it */
+-              int delta = fp->link - tab.funcstart;
+-              printf(" (%s+0x%x)", tab.name, delta);
+-      }
+-      printf("\n");
++      xmon_print_symbol(" (%s)\n", fp->link);
++
+       printf("    sp: %lx\n", fp->gpr[1]);
+       printf("   msr: %lx\n", fp->msr);
+@@ -1057,13 +995,11 @@
+               printf(" dsisr: %lx\n", fp->dsisr);
+       }
+-      /* XXX: need to copy current or we die.  Why? */
+-      c = current;
+-      printf("  current = 0x%lx\n", c);
++      printf("  current = 0x%lx\n", current);
+       printf("  paca    = 0x%lx\n", get_paca());
+-      if (c) {
+-              printf("  current = %lx, pid = %ld, comm = %s\n",
+-                     c, c->pid, c->comm);
++      if (current) {
++              printf("    pid   = %ld, comm = %s\n",
++                     current->pid, current->comm);
+       }
+       spin_unlock_irqrestore(&exception_print_lock, flags);
+@@ -1153,14 +1089,6 @@
+ extern char dec_exc;
+ void
+-print_sysmap(void)
+-{
+-      extern char *sysmap;
+-      if ( sysmap )
+-              printf("System.map: \n%s", sysmap);
+-}
+-
+-void
+ super_regs()
+ {
+       int i, cmd;
+@@ -1228,152 +1156,6 @@
+       scannl();
+ }
+-#ifndef CONFIG_PPC64BRIDGE
+-static void
+-dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+-{
+-      extern void *Hash;
+-      extern unsigned long Hash_size;
+-      unsigned *htab = Hash;
+-      unsigned hsize = Hash_size;
+-      unsigned v, hmask, va, last_va;
+-      int found, last_found, i;
+-      unsigned *hg, w1, last_w2, last_va0;
+-
+-      last_found = 0;
+-      hmask = hsize / 64 - 1;
+-      va = start;
+-      start = (start >> 12) & 0xffff;
+-      end = (end >> 12) & 0xffff;
+-      for (v = start; v < end; ++v) {
+-              found = 0;
+-              hg = htab + (((v ^ seg) & hmask) * 16);
+-              w1 = 0x80000000 | (seg << 7) | (v >> 10);
+-              for (i = 0; i < 8; ++i, hg += 2) {
+-                      if (*hg == w1) {
+-                              found = 1;
+-                              break;
+-                      }
+-              }
+-              if (!found) {
+-                      w1 ^= 0x40;
+-                      hg = htab + ((~(v ^ seg) & hmask) * 16);
+-                      for (i = 0; i < 8; ++i, hg += 2) {
+-                              if (*hg == w1) {
+-                                      found = 1;
+-                                      break;
+-                              }
+-                      }
+-              }
+-              if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) {
+-                      if (last_found) {
+-                              if (last_va != last_va0)
+-                                      printf(" ... %x", last_va);
+-                              printf("\n");
+-                      }
+-                      if (found) {
+-                              printf("%x to %x", va, hg[1]);
+-                              last_va0 = va;
+-                      }
+-                      last_found = found;
+-              }
+-              if (found) {
+-                      last_w2 = hg[1] & ~0x180;
+-                      last_va = va;
+-              }
+-              va += 4096;
+-      }
+-      if (last_found)
+-              printf(" ... %x\n", last_va);
+-}
+-
+-#else /* CONFIG_PPC64BRIDGE */
+-static void
+-dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
+-{
+-      extern void *Hash;
+-      extern unsigned long Hash_size;
+-      unsigned *htab = Hash;
+-      unsigned hsize = Hash_size;
+-      unsigned v, hmask, va, last_va;
+-      int found, last_found, i;
+-      unsigned *hg, w1, last_w2, last_va0;
+-
+-      last_found = 0;
+-      hmask = hsize / 128 - 1;
+-      va = start;
+-      start = (start >> 12) & 0xffff;
+-      end = (end >> 12) & 0xffff;
+-      for (v = start; v < end; ++v) {
+-              found = 0;
+-              hg = htab + (((v ^ seg) & hmask) * 32);
+-              w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
+-              for (i = 0; i < 8; ++i, hg += 4) {
+-                      if (hg[1] == w1) {
+-                              found = 1;
+-                              break;
+-                      }
+-              }
+-              if (!found) {
+-                      w1 ^= 2;
+-                      hg = htab + ((~(v ^ seg) & hmask) * 32);
+-                      for (i = 0; i < 8; ++i, hg += 4) {
+-                              if (hg[1] == w1) {
+-                                      found = 1;
+-                                      break;
+-                              }
+-                      }
+-              }
+-              if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
+-                      if (last_found) {
+-                              if (last_va != last_va0)
+-                                      printf(" ... %x", last_va);
+-                              printf("\n");
+-                      }
+-                      if (found) {
+-                              printf("%x to %x", va, hg[3]);
+-                              last_va0 = va;
+-                      }
+-                      last_found = found;
+-              }
+-              if (found) {
+-                      last_w2 = hg[3] & ~0x180;
+-                      last_va = va;
+-              }
+-              va += 4096;
+-      }
+-      if (last_found)
+-              printf(" ... %x\n", last_va);
+-}
+-#endif /* CONFIG_PPC64BRIDGE */
+-
+-static unsigned long hash_ctx;
+-static unsigned long hash_start;
+-static unsigned long hash_end;
+-
+-static void
+-dump_hash_table()
+-{
+-      int seg;
+-      unsigned seg_start, seg_end;
+-
+-      hash_ctx = 0;
+-      hash_start = 0;
+-      hash_end = 0xfffff000;
+-      scanhex(&hash_ctx);
+-      scanhex(&hash_start);
+-      scanhex(&hash_end);
+-      printf("Mappings for context %x\n", hash_ctx);
+-      seg_start = hash_start;
+-      for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) {
+-              seg_end = (seg << 28) | 0x0ffff000;
+-              if (seg_end > hash_end)
+-                      seg_end = hash_end;
+-              dump_hash_table_seg((hash_ctx << 4) + seg, seg_start, seg_end);
+-              seg_start = seg_end + 0x1000;
+-      }
+-}
+-
+ int
+ mread(unsigned long adrs, void *buf, int size)
+ {
+@@ -2073,111 +1855,52 @@
+       lineptr = str;
+ }
+-
+-/* Starting at codeaddr scan forward for a tbtable and fill in the
+- given table.  Return non-zero if successful at doing something.
+- */
+-static int
+-find_tb_table(unsigned long codeaddr, struct tbtable *tab)
++/* xmon version of __print_symbol */
++void __xmon_print_symbol(const char *fmt, unsigned long address)
+ {
+-      unsigned long codeaddr_max;
+-      unsigned long tbtab_start;
+-      int nr;
+-      int instr;
+-      int num_parms;
++      char *modname;
++      const char *name;
++      unsigned long offset, size;
++      char namebuf[128];
+-      /* don't look for traceback table in userspace */
+-      if (codeaddr < PAGE_OFFSET)
+-              return 0;
++      if (setjmp(bus_error_jmp) == 0) {
++              debugger_fault_handler = handle_fault;
++              sync();
++              name = kallsyms_lookup(address, &size, &offset, &modname,
++                                     namebuf);
++              sync();
++              /* wait a little while to see if we get a machine check */
++              __delay(200);
++      } else {
++              name = "symbol lookup failed";
++      }
+-      if (tab == NULL)
+-              return 0;
+-      memset(tab, 0, sizeof(tab));
++      debugger_fault_handler = 0;
+-      /* Scan instructions starting at codeaddr for 128k max */
+-      for (codeaddr_max = codeaddr + 128*1024*4;
+-           codeaddr < codeaddr_max;
+-           codeaddr += 4) {
+-              nr = mread(codeaddr, &instr, 4);
+-              if (nr != 4)
+-                      return 0;       /* Bad read.  Give up promptly. */
+-              if (instr == 0) {
+-                      /* table should follow. */
+-                      int version;
+-                      unsigned long flags;
+-                      tbtab_start = codeaddr; /* save it to compute func start addr */
+-                      codeaddr += 4;
+-                      nr = mread(codeaddr, &flags, 8);
+-                      if (nr != 8)
+-                              return 0;       /* Bad read or no tb table. */
+-                      tab->flags = flags;
+-                      version = (flags >> 56) & 0xff;
+-                      if (version != 0)
+-                              continue;       /* No tb table here. */
+-                      /* Now, like the version, some of the flags are values
+-                       that are more conveniently extracted... */
+-                      tab->fp_saved = (flags >> 24) & 0x3f;
+-                      tab->gpr_saved = (flags >> 16) & 0x3f;
+-                      tab->fixedparms = (flags >> 8) & 0xff;
+-                      tab->floatparms = (flags >> 1) & 0x7f;
+-                      codeaddr += 8;
+-                      num_parms = tab->fixedparms + tab->floatparms;
+-                      if (num_parms) {
+-                              unsigned int parminfo;
+-                              int parm;
+-                              if (num_parms > 32)
+-                                      return 1;       /* incomplete */
+-                              nr = mread(codeaddr, &parminfo, 4);
+-                              if (nr != 4)
+-                                      return 1;       /* incomplete */
+-                              /* decode parminfo...32 bits.
+-                               A zero means fixed.  A one means float and the
+-                               following bit determines single (0) or double (1).
+-                               */
+-                              for (parm = 0; parm < num_parms; parm++) {
+-                                      if (parminfo & 0x80000000) {
+-                                              parminfo <<= 1;
+-                                              if (parminfo & 0x80000000)
+-                                                      tab->parminfo[parm] = TBTAB_PARMDFLOAT;
+-                                              else
+-                                                      tab->parminfo[parm] = TBTAB_PARMSFLOAT;
+-                                      } else {
+-                                              tab->parminfo[parm] = TBTAB_PARMFIXED;
+-                                      }
+-                                      parminfo <<= 1;
+-                              }
+-                              codeaddr += 4;
+-                      }
+-                      if (flags & TBTAB_FLAGSHASTBOFF) {
+-                              nr = mread(codeaddr, &tab->tb_offset, 4);
+-                              if (nr != 4)
+-                                      return 1;       /* incomplete */
+-                              if (tab->tb_offset > 0) {
+-                                      tab->funcstart = tbtab_start - tab->tb_offset;
+-                              }
+-                              codeaddr += 4;
+-                      }
+-                      /* hand_mask appears to be always be omitted. */
+-                      if (flags & TBTAB_FLAGSHASCTL) {
+-                              /* Assume this will never happen for C or asm */
+-                              return 1;       /* incomplete */
+-                      }
+-                      if (flags & TBTAB_FLAGSNAMEPRESENT) {
+-                              short namlen;
+-                              nr = mread(codeaddr, &namlen, 2);
+-                              if (nr != 2)
+-                                      return 1;       /* incomplete */
+-                              if (namlen >= sizeof(tab->name))
+-                                      namlen = sizeof(tab->name)-1;
+-                              codeaddr += 2;
+-                              nr = mread(codeaddr, tab->name, namlen);
+-                              tab->name[namlen] = '\0';
+-                              codeaddr += namlen;
+-                      }
+-                      return 1;
+-              }
++      if (!name) {
++              char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)];
++
++              sprintf(addrstr, "0x%lx", address);
++              printf(fmt, addrstr);
++              return;
++      }
++
++      if (modname) {
++              /* This is pretty small. */
++              char buffer[sizeof("%s+%#lx/%#lx [%s]")
++                         + strlen(name) + 2*(BITS_PER_LONG*3/10)
++                         + strlen(modname)];
++
++              sprintf(buffer, "%s+%#lx/%#lx [%s]",
++                      name, offset, size, modname);
++              printf(fmt, buffer);
++      } else {
++              char buffer[sizeof("%s+%#lx/%#lx")
++                         + strlen(name) + 2*(BITS_PER_LONG*3/10)];
++
++              sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
++              printf(fmt, buffer);
+       }
+-      return 0;       /* hit max...sorry. */
+ }
+ void
+Index: linux-2.6.0-test5/arch/ppc/boot/ld.script
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/boot/ld.script     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/boot/ld.script  2003-09-27 11:38:19.924499400 +0800
+@@ -82,6 +82,7 @@
+     *(__ksymtab)
+     *(__ksymtab_strings)
+     *(__bug_table)
++    *(__kcrctab)
+   }
+ }
+Index: linux-2.6.0-test5/arch/ppc/kernel/align.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/align.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/align.c  2003-09-27 11:38:19.927498944 +0800
+@@ -21,11 +21,11 @@
+       unsigned char flags;
+ };
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+ #define       OPCD(inst)      (((inst) & 0xFC000000) >> 26)
+ #define       RS(inst)        (((inst) & 0x03E00000) >> 21)
+ #define       RA(inst)        (((inst) & 0x001F0000) >> 16)
+-#define       IS_DFORM(code)  ((code) >= 32 && (code) <= 55)
++#define       IS_XFORM(code)  ((code) == 31)
+ #endif
+ #define INVALID       { 0, 0 }
+@@ -61,9 +61,9 @@
+       { 4, ST+F+S },          /* 00 0 1010: stfs */
+       { 8, ST+F },            /* 00 0 1011: stfd */
+       INVALID,                /* 00 0 1100 */
+-      INVALID,                /* 00 0 1101 */
++      INVALID,                /* 00 0 1101: ld/ldu/lwa */
+       INVALID,                /* 00 0 1110 */
+-      INVALID,                /* 00 0 1111 */
++      INVALID,                /* 00 0 1111: std/stdu */
+       { 4, LD+U },            /* 00 1 0000: lwzu */
+       INVALID,                /* 00 1 0001 */
+       { 4, ST+U },            /* 00 1 0010: stwu */
+@@ -80,12 +80,12 @@
+       INVALID,                /* 00 1 1101 */
+       INVALID,                /* 00 1 1110 */
+       INVALID,                /* 00 1 1111 */
+-      INVALID,                /* 01 0 0000 */
++      INVALID,                /* 01 0 0000: ldx */
+       INVALID,                /* 01 0 0001 */
+-      INVALID,                /* 01 0 0010 */
++      INVALID,                /* 01 0 0010: stdx */
+       INVALID,                /* 01 0 0011 */
+       INVALID,                /* 01 0 0100 */
+-      INVALID,                /* 01 0 0101: lwax?? */
++      INVALID,                /* 01 0 0101: lwax */
+       INVALID,                /* 01 0 0110 */
+       INVALID,                /* 01 0 0111 */
+       { 0, LD+HARD },         /* 01 0 1000: lswx */
+@@ -96,12 +96,12 @@
+       INVALID,                /* 01 0 1101 */
+       INVALID,                /* 01 0 1110 */
+       INVALID,                /* 01 0 1111 */
+-      INVALID,                /* 01 1 0000 */
++      INVALID,                /* 01 1 0000: ldux */
+       INVALID,                /* 01 1 0001 */
+-      INVALID,                /* 01 1 0010 */
++      INVALID,                /* 01 1 0010: stdux */
+       INVALID,                /* 01 1 0011 */
+       INVALID,                /* 01 1 0100 */
+-      INVALID,                /* 01 1 0101: lwaux?? */
++      INVALID,                /* 01 1 0101: lwaux */
+       INVALID,                /* 01 1 0110 */
+       INVALID,                /* 01 1 0111 */
+       INVALID,                /* 01 1 1000 */
+@@ -157,9 +157,9 @@
+       { 4, ST+F+S },          /* 11 0 1010: stfsx */
+       { 8, ST+F },            /* 11 0 1011: stfdx */
+       INVALID,                /* 11 0 1100 */
+-      INVALID,                /* 11 0 1101 */
++      INVALID,                /* 11 0 1101: lmd */
+       INVALID,                /* 11 0 1110 */
+-      INVALID,                /* 11 0 1111 */
++      INVALID,                /* 11 0 1111: stmd */
+       { 4, LD+U },            /* 11 1 0000: lwzux */
+       INVALID,                /* 11 1 0001 */
+       { 4, ST+U },            /* 11 1 0010: stwux */
+@@ -184,7 +184,7 @@
+ fix_alignment(struct pt_regs *regs)
+ {
+       int instr, nb, flags;
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+       int opcode, f1, f2, f3;
+ #endif
+       int i, t;
+@@ -199,9 +199,11 @@
+       CHECK_FULL_REGS(regs);
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+       /* The 4xx-family processors have no DSISR register,
+        * so we emulate it.
++       * The POWER4 has a DSISR register but doesn't set it on
++       * an alignment fault.  -- paulus
+        */
+       instr = *((unsigned int *)regs->nip);
+@@ -209,7 +211,7 @@
+       reg = RS(instr);
+       areg = RA(instr);
+-      if (IS_DFORM(opcode)) {
++      if (!IS_XFORM(opcode)) {
+               f1 = 0;
+               f2 = (instr & 0x04000000) >> 26;
+               f3 = (instr & 0x78000000) >> 27;
+Index: linux-2.6.0-test5/arch/ppc/kernel/asm-offsets.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/asm-offsets.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/asm-offsets.c    2003-09-27 11:38:19.930498488 +0800
+@@ -52,6 +52,7 @@
+       DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
+       DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
+       DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
++      DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
+ #endif /* CONFIG_ALTIVEC */
+       /* Interrupt register frame */
+       DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
+@@ -101,7 +102,7 @@
+       DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
+       DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+       DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+-      /* The PowerPC 400-class processors have neither the DAR nor the DSISR
++      /* The PowerPC 400-class & Book-E processors have neither the DAR nor the DSISR
+        * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
+        * for such processors.  For critical interrupts we use them to
+        * hold SRR0 and SRR1.
+Index: linux-2.6.0-test5/arch/ppc/kernel/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/head.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/head.S   2003-09-27 11:38:19.941496816 +0800
+@@ -915,7 +915,9 @@
+       /* enable use of AltiVec after return */
+       oris    r9,r9,MSR_VEC@h
+       mfspr   r5,SPRG3                /* current task's THREAD (phys) */
++      li      r4,1
+       li      r10,THREAD_VSCR
++      stw     r4,THREAD_USED_VR(r5)
+       lvx     vr0,r10,r5
+       mtvscr  vr0
+       REST_32VR(0,r10,r5)
+Index: linux-2.6.0-test5/arch/ppc/kernel/misc.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/misc.S      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/misc.S   2003-09-27 11:38:19.948495752 +0800
+@@ -1379,7 +1379,7 @@
+       .long sys_clock_gettime
+       .long sys_clock_getres
+       .long sys_clock_nanosleep
+-      .long sys_ni_syscall    /* reserved for swapcontext */
++      .long sys_swapcontext
+       .long sys_tgkill        /* 250 */
+       .long sys_utimes
+       .long sys_statfs64
+Index: linux-2.6.0-test5/arch/ppc/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/process.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/process.c        2003-09-27 11:38:19.953494992 +0800
+@@ -415,6 +415,7 @@
+       memset(current->thread.vr, 0, sizeof(current->thread.vr));
+       memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
+       current->thread.vrsave = 0;
++      current->thread.used_vr = 0;
+ #endif /* CONFIG_ALTIVEC */
+ }
+Index: linux-2.6.0-test5/arch/ppc/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/signal.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/signal.c 2003-09-27 11:38:19.959494080 +0800
+@@ -41,18 +41,6 @@
+ #define GP_REGS_SIZE  min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+-/* 
+- * These are the flags in the MSR that the user is allowed to change
+- * by modifying the saved value of the MSR on the stack.  SE and BE
+- * should not be in this list since gdb may want to change these.  I.e,
+- * you should be able to step out of a signal handler to see what
+- * instruction executes next after the signal handler completes.
+- * Alternately, if you stepped into a signal handler, you should be
+- * able to continue 'til the next breakpoint from within the signal
+- * handler, even if the handler returns.
+- */
+-#define MSR_USERCHANGE        (MSR_FE0 | MSR_FE1)
+-
+ int do_signal(sigset_t *oldset, struct pt_regs *regs);
+ /*
+@@ -72,8 +60,8 @@
+       spin_unlock_irq(&current->sighand->siglock);
+       regs->result = -EINTR;
+-      regs->ccr |= 0x10000000;
+       regs->gpr[3] = EINTR;
++      regs->ccr |= 0x10000000;
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule();
+@@ -103,8 +91,8 @@
+       spin_unlock_irq(&current->sighand->siglock);
+       regs->result = -EINTR;
+-      regs->ccr |= 0x10000000;
+       regs->gpr[3] = EINTR;
++      regs->ccr |= 0x10000000;
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule();
+@@ -164,305 +152,389 @@
+  *
+  */
+ struct sigregs {
+-      elf_gregset_t   gp_regs;
+-      double          fp_regs[ELF_NFPREG];
+-      unsigned long   tramp[2];
++      struct mcontext mctx;           /* all the register values */
+       /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
+          and 18 fp regs below sp before decrementing it. */
+       int             abigap[56];
+ };
+-struct rt_sigframe
+-{
+-      unsigned long   _unused[2];
+-      struct siginfo *pinfo;
+-      void *puc;
+-      struct siginfo info;
+-      struct ucontext uc;
+-};
+-
++/* We use the mc_pad field for the signal return trampoline. */
++#define tramp mc_pad
+ /*
+  *  When we have rt signals to deliver, we set up on the
+  *  user stack, going down from the original stack pointer:
+- *       a sigregs struct
+- *       one rt_sigframe struct (siginfo + ucontext)
+- *       a gap of __SIGNAL_FRAMESIZE bytes
++ *    one rt_sigframe struct (siginfo + ucontext + ABI gap)
++ *    a gap of __SIGNAL_FRAMESIZE+16 bytes
++ *  (the +16 is to get the siginfo and ucontext in the same
++ *  positions as in older kernels).
+  *
+  *  Each of these things must be a multiple of 16 bytes in size.
+  *
+  */
+-int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+-                   struct pt_regs *regs)
++struct rt_sigframe
+ {
+-      struct rt_sigframe __user *rt_sf;
+-      struct sigcontext sigctx;
+-      struct sigregs __user *sr;
+-      elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
+-      sigset_t set;
+-      stack_t st;
++      struct siginfo info;
++      struct ucontext uc;
++      /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
++         and 18 fp regs below sp before decrementing it. */
++      int             abigap[56];
++};
+-      rt_sf = (struct rt_sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+-      if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
+-          || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
+-          || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
+-              goto badframe;
+-      sigdelsetmask(&set, ~_BLOCKABLE);
+-      spin_lock_irq(&current->sighand->siglock);
+-      current->blocked = set;
+-      recalc_sigpending();
+-      spin_unlock_irq(&current->sighand->siglock);
++/*
++ * Save the current user registers on the user stack.
++ * We only save the altivec registers if the process has used
++ * altivec instructions at some point.
++ */
++static int
++save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
++{
++      /* save general and floating-point registers */
++      CHECK_FULL_REGS(regs);
+       if (regs->msr & MSR_FP)
+               giveup_fpu(current);
++      if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
++          || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
++                            ELF_NFPREG * sizeof(double)))
++              return 1;
+-      /* restore registers -
+-       * sigctx is initialized to point to the 
+-       * preamble frame (where registers are stored) 
+-       * see handle_signal()
++      current->thread.fpscr = 0;      /* turn off all fp exceptions */
++
++#ifdef CONFIG_ALTIVEC
++      /* save altivec registers */
++      if (current->thread.used_vr) {
++              if (regs->msr & MSR_VEC)
++                      giveup_altivec(current);
++              if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
++                                 ELF_NVRREG * sizeof(vector128)))
++                      return 1;
++              /* set MSR_VEC in the saved MSR value to indicate that
++                 frame->mc_vregs contains valid data */
++              if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
++                      return 1;
++      }
++      /* else assert((regs->msr & MSR_VEC) == 0) */
++
++      /* We always copy to/from vrsave, it's 0 if we don't have or don't
++       * use altivec. Since VSCR only contains 32 bits saved in the least
++       * significant bits of a vector, we "cheat" and stuff VRSAVE in the
++       * most significant bits of that same vector. --BenH
+        */
+-      sr = (struct sigregs __user *) sigctx.regs;
+-      if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
+-              goto badframe;
+-      saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+-              | (saved_regs[PT_MSR] & MSR_USERCHANGE);
+-      memcpy(regs, saved_regs, GP_REGS_SIZE);
+-      if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+-                         sizeof(sr->fp_regs)))
+-              goto badframe;
++      if (__put_user(current->thread.vrsave, (u32 *)&frame->mc_vregs[32]))
++              return 1;
++#endif /* CONFIG_ALTIVEC */
++
++      if (sigret) {
++              /* Set up the sigreturn trampoline: li r0,sigret; sc */
++              if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
++                  || __put_user(0x44000002UL, &frame->tramp[1]))
++                      return 1;
++              flush_icache_range((unsigned long) &frame->tramp[0],
++                                 (unsigned long) &frame->tramp[2]);
++      }
+-      sigreturn_exit(regs);           /* doesn't return here */
+       return 0;
++}
+-badframe:
+-      do_exit(SIGSEGV);
++/*
++ * Restore the current user register values from the user stack,
++ * (except for MSR).
++ */
++static int
++restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr)
++{
++#ifdef CONFIG_ALTIVEC
++      unsigned long msr;
++#endif
++
++      /* copy up to but not including MSR */
++      if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
++              return 1;
++      /* copy from orig_r3 (the word after the MSR) up to the end */
++      if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
++                           GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
++              return 1;
++
++      /* force the process to reload the FP registers from
++         current->thread when it next does FP instructions */
++      regs->msr &= ~MSR_FP;
++      if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
++                           sizeof(sr->mc_fregs)))
++              return 1;
++
++#ifdef CONFIG_ALTIVEC
++      /* force the process to reload the altivec registers from
++         current->thread when it next does altivec instructions */
++      regs->msr &= ~MSR_VEC;
++      if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
++              /* restore altivec registers from the stack */
++              if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
++                                   sizeof(sr->mc_vregs)))
++                      return 1;
++      } else if (current->thread.used_vr)
++              memset(&current->thread.vr, 0, sizeof(current->thread.vr));
++
++      /* Always get VRSAVE back */
++      if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32]))
++              return 1;
++#endif /* CONFIG_ALTIVEC */
++
++      return 0;
+ }
++/*
++ * Restore the user process's signal mask
++ */
+ static void
+-setup_rt_frame(struct pt_regs *regs, struct sigregs __user *frame,
+-             signed long newsp)
++restore_sigmask(sigset_t *set)
+ {
+-      struct rt_sigframe __user *rt_sf = (struct rt_sigframe __user *) newsp;
++      sigdelsetmask(set, ~_BLOCKABLE);
++      spin_lock_irq(&current->sighand->siglock);
++      current->blocked = *set;
++      recalc_sigpending();
++      spin_unlock_irq(&current->sighand->siglock);
++}
+-      /* Set up preamble frame */
+-      if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
++/*
++ * Set up a signal frame for a "real-time" signal handler
++ * (one which gets siginfo).
++ */
++static void
++handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
++               siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
++               unsigned long newsp)
++{
++      struct rt_sigframe __user *rt_sf;
++      struct mcontext __user *frame;
++      unsigned long origsp = newsp;
++
++      /* Set up Signal Frame */
++      /* Put a Real Time Context onto stack */
++      newsp -= sizeof(*rt_sf);
++      rt_sf = (struct rt_sigframe __user *) newsp;
++
++      /* create a stack frame for the caller of the handler */
++      newsp -= __SIGNAL_FRAMESIZE + 16;
++
++      if (verify_area(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
+               goto badframe;
+-      CHECK_FULL_REGS(regs);
+-      if (regs->msr & MSR_FP)
+-              giveup_fpu(current);
+-      if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+-          || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+-                            ELF_NFPREG * sizeof(double))
+-      /* Set up to return from user space.
+-         It calls the sc exception at offset 0x9999 
+-         for sys_rt_sigreturn().
+-      */
+-          || __put_user(0x38000000UL + __NR_rt_sigreturn, &frame->tramp[0])
+-          || __put_user(0x44000002UL, &frame->tramp[1]))      /* sc */
++
++      /* Put the siginfo & fill in most of the ucontext */
++      if (copy_siginfo_to_user(&rt_sf->info, info)
++          || __put_user(0, &rt_sf->uc.uc_flags)
++          || __put_user(0, &rt_sf->uc.uc_link)
++          || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
++          || __put_user(sas_ss_flags(regs->gpr[1]), 
++                        &rt_sf->uc.uc_stack.ss_flags)
++          || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
++          || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
++          || __copy_to_user(&rt_sf->uc.uc_oldsigmask, oldset, sizeof(*oldset))
++          || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
+               goto badframe;
+-      flush_icache_range((unsigned long) &frame->tramp[0],
+-                         (unsigned long) &frame->tramp[2]);
+-      current->thread.fpscr = 0;      /* turn off all fp exceptions */
+-      /* Retrieve rt_sigframe from stack and
+-         set up registers for signal handler
+-      */
+-      newsp -= __SIGNAL_FRAMESIZE;
+-      if (put_user(regs->gpr[1], (unsigned long __user *)newsp)
+-          || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler)
+-          || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
+-          || get_user(regs->gpr[4], (unsigned long __user *)&rt_sf->pinfo)
+-          || get_user(regs->gpr[5], (unsigned long __user *)&rt_sf->puc))
++      /* Save user registers on the stack */
++      frame = &rt_sf->uc.uc_mcontext;
++      if (save_user_regs(regs, frame, __NR_rt_sigreturn))
+               goto badframe;
++      if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
++              goto badframe;
+       regs->gpr[1] = newsp;
++      regs->gpr[3] = sig;
++      regs->gpr[4] = (unsigned long) &rt_sf->info;
++      regs->gpr[5] = (unsigned long) &rt_sf->uc;
+       regs->gpr[6] = (unsigned long) rt_sf;
++      regs->nip = (unsigned long) ka->sa.sa_handler;
+       regs->link = (unsigned long) frame->tramp;
++      regs->trap = 0;
+       return;
+ badframe:
+ #if DEBUG_SIG
+-      printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
++      printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
+              regs, frame, newsp);
+ #endif
+-      do_exit(SIGSEGV);
++      if (sig == SIGSEGV)
++              ka->sa.sa_handler = SIG_DFL;
++      force_sig(SIGSEGV, current);
+ }
+-/*
+- * Do a signal return; undo the signal stack.
+- */
+-int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+-                struct pt_regs *regs)
++static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs)
+ {
+-      struct sigcontext __user *sc;
+-      struct sigcontext sigctx;
+-      struct sigregs __user *sr;
+-      elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
+       sigset_t set;
+-      sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+-      if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+-              goto badframe;
++      if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set)))
++              return -EFAULT;
++      restore_sigmask(&set);
+-      set.sig[0] = sigctx.oldmask;
+-#if _NSIG_WORDS > 1
+-      set.sig[1] = sigctx._unused[3];
+-#endif
+-      sigdelsetmask(&set, ~_BLOCKABLE);
+-      spin_lock_irq(&current->sighand->siglock);
+-      current->blocked = set;
+-      recalc_sigpending();
+-      spin_unlock_irq(&current->sighand->siglock);
+-      if (regs->msr & MSR_FP )
+-              giveup_fpu(current);
++      if (restore_user_regs(regs, &ucp->uc_mcontext))
++              return -EFAULT;
+-      /* restore registers */
+-      sr = (struct sigregs __user *) sigctx.regs;
+-      if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
+-              goto badframe;
+-      saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+-              | (saved_regs[PT_MSR] & MSR_USERCHANGE);
+-      memcpy(regs, saved_regs, GP_REGS_SIZE);
++      return 0;
++}
+-      if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+-                         sizeof(sr->fp_regs)))
+-              goto badframe;
++int sys_swapcontext(struct ucontext __user *old_ctx,
++                  struct ucontext __user *new_ctx,
++                  int r5, int r6, int r7, int r8, struct pt_regs *regs)
++{
++      unsigned char tmp;
++
++      if (old_ctx != NULL) {
++              if (verify_area(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
++                  || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
++                  || __copy_to_user(&old_ctx->uc_sigmask,
++                                    &current->blocked, sizeof(sigset_t))
++                  /* the next 2 things aren't strictly necessary */
++                  || __copy_to_user(&old_ctx->uc_oldsigmask,
++                                    &current->blocked, sizeof(sigset_t))
++                  || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
++                      return -EFAULT;
++      }
++      if (new_ctx == NULL)
++              return 0;
++      if (verify_area(VERIFY_READ, new_ctx, sizeof(*new_ctx))
++          || __get_user(tmp, (u8 *) new_ctx)
++          || __get_user(tmp, (u8 *) (new_ctx + 1) - 1))
++              return -EFAULT;
++
++      /*
++       * If we get a fault copying the context into the kernel's
++       * image of the user's registers, we can't just return -EFAULT
++       * because the user's registers will be corrupted.  For instance
++       * the NIP value may have been updated but not some of the
++       * other registers.  Given that we have done the verify_area
++       * and successfully read the first and last bytes of the region
++       * above, this should only happen in an out-of-memory situation
++       * or if another thread unmaps the region containing the context.
++       * We kill the task with a SIGSEGV in this situation.
++       */
++      if (do_setcontext(new_ctx, regs))
++              do_exit(SIGSEGV);
++      sigreturn_exit(regs);
++      /* doesn't actually return back to here */
++      return 0;
++}
++
++int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
++                   struct pt_regs *regs)
++{
++      struct rt_sigframe __user *rt_sf;
++
++      rt_sf = (struct rt_sigframe __user *)
++              (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
++      if (verify_area(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
++              goto bad;
++      if (do_setcontext(&rt_sf->uc, regs))
++              goto bad;
++
++      /*
++       * It's not clear whether or why it is desirable to save the
++       * sigaltstack setting on signal delivery and restore it on
++       * signal return.  But other architectures do this and we have
++       * always done it up until now so it is probably better not to
++       * change it.  -- paulus
++       */
++      do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
+       sigreturn_exit(regs);           /* doesn't return here */
+       return 0;
+-badframe:
+-      do_exit(SIGSEGV);
+-}     
++ bad:
++      force_sig(SIGSEGV, current);
++      return 0;
++}
+ /*
+- * Set up a signal frame.
++ * OK, we're invoking a handler
+  */
+ static void
+-setup_frame(struct pt_regs *regs, struct sigregs __user *frame,
+-          unsigned long newsp)
++handle_signal(unsigned long sig, struct k_sigaction *ka,
++            siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
++            unsigned long newsp)
+ {
+-      struct sigcontext __user *sc = (struct sigcontext __user *) newsp;
++      struct sigcontext __user *sc;
++      struct sigregs __user *frame;
++      unsigned long origsp = newsp;
+-      if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
++      /* Set up Signal Frame */
++      newsp -= sizeof(struct sigregs);
++      frame = (struct sigregs __user *) newsp;
++
++      /* Put a sigcontext on the stack */
++      newsp -= sizeof(*sc);
++      sc = (struct sigcontext __user *) newsp;
++
++      /* create a stack frame for the caller of the handler */
++      newsp -= __SIGNAL_FRAMESIZE;
++
++      if (verify_area(VERIFY_WRITE, (void *) newsp, origsp - newsp))
+               goto badframe;
+-      CHECK_FULL_REGS(regs);
+-      if (regs->msr & MSR_FP)
+-              giveup_fpu(current);
+-      if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+-          || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+-                            ELF_NFPREG * sizeof(double))
+-          || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
+-          || __put_user(0x44000002UL, &frame->tramp[1]))   /* sc */
++
++#if _NSIG != 64
++#error "Please adjust handle_signal()"
++#endif
++      if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
++          || __put_user(oldset->sig[0], &sc->oldmask)
++          || __put_user(oldset->sig[1], &sc->_unused[3])
++          || __put_user((struct pt_regs *)frame, &sc->regs)
++          || __put_user(sig, &sc->signal))
+               goto badframe;
+-      flush_icache_range((unsigned long) &frame->tramp[0],
+-                         (unsigned long) &frame->tramp[2]);
+-      current->thread.fpscr = 0;      /* turn off all fp exceptions */
+-      newsp -= __SIGNAL_FRAMESIZE;
+-      if (put_user(regs->gpr[1], (unsigned long __user *)newsp)
+-          || get_user(regs->nip, &sc->handler)
+-          || get_user(regs->gpr[3], &sc->signal))
++      if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
++              goto badframe;
++
++      if (put_user(regs->gpr[1], (unsigned long *)newsp))
+               goto badframe;
+       regs->gpr[1] = newsp;
++      regs->gpr[3] = sig;
+       regs->gpr[4] = (unsigned long) sc;
+-      regs->link = (unsigned long) frame->tramp;
++      regs->nip = (unsigned long) ka->sa.sa_handler;
++      regs->link = (unsigned long) frame->mctx.tramp;
++      regs->trap = 0;
+       return;
+ badframe:
+ #if DEBUG_SIG
+-      printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
+-             regs, frame, newsp);
++      printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
++             regs, frame, *newspp);
+ #endif
+-      do_exit(SIGSEGV);
++      if (sig == SIGSEGV)
++              ka->sa.sa_handler = SIG_DFL;
++      force_sig(SIGSEGV, current);
+ }
+ /*
+- * OK, we're invoking a handler
++ * Do a signal return; undo the signal stack.
+  */
+-static void
+-handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
+-      struct pt_regs * regs, unsigned long *newspp, unsigned long frame)
++int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
++                struct pt_regs *regs)
+ {
+       struct sigcontext __user *sc;
+-      struct rt_sigframe __user *rt_sf;
+-      struct k_sigaction *ka = &current->sighand->action[sig-1];
++      struct sigcontext sigctx;
++      struct mcontext __user *sr;
++      sigset_t set;
+-      if (TRAP(regs) == 0x0C00 /* System Call! */
+-          && ((int)regs->result == -ERESTARTNOHAND ||
+-              (int)regs->result == -ERESTART_RESTARTBLOCK ||
+-              ((int)regs->result == -ERESTARTSYS &&
+-               !(ka->sa.sa_flags & SA_RESTART)))) {
+-              if ((int)regs->result == -ERESTART_RESTARTBLOCK)
+-                      current_thread_info()->restart_block.fn
+-                              = do_no_restart_syscall;
+-              regs->result = -EINTR;
+-              regs->gpr[3] = EINTR;
+-              regs->ccr |= 0x10000000;
+-      }
++      sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
++      if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
++              goto badframe;
+-      /* Set up Signal Frame */
+-      if (ka->sa.sa_flags & SA_SIGINFO) {
+-              /* Put a Real Time Context onto stack */
+-              *newspp -= sizeof(*rt_sf);
+-              rt_sf = (struct rt_sigframe __user *) *newspp;
+-              if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
+-                      goto badframe;
+-
+-              if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler)
+-                  || __put_user(&rt_sf->info, &rt_sf->pinfo)
+-                  || __put_user(&rt_sf->uc, &rt_sf->puc)
+-                  /* Put the siginfo */
+-                  || copy_siginfo_to_user(&rt_sf->info, info)
+-                  /* Create the ucontext */
+-                  || __put_user(0, &rt_sf->uc.uc_flags)
+-                  || __put_user(0, &rt_sf->uc.uc_link)
+-                  || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
+-                  || __put_user(sas_ss_flags(regs->gpr[1]), 
+-                                &rt_sf->uc.uc_stack.ss_flags)
+-                  || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
+-                  || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))
+-                  /* mcontext.regs points to preamble register frame */
+-                  || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
+-                  || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
+-                      goto badframe;
+-      } else {
+-              /* Put a sigcontext on the stack */
+-              *newspp -= sizeof(*sc);
+-              sc = (struct sigcontext __user *) *newspp;
+-              if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
+-                      goto badframe;
+-              
+-              if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
+-                  || __put_user(oldset->sig[0], &sc->oldmask)
+-#if _NSIG_WORDS > 1
+-                  || __put_user(oldset->sig[1], &sc->_unused[3])
+-#endif
+-                  || __put_user((struct pt_regs *)frame, &sc->regs)
+-                  || __put_user(sig, &sc->signal))
+-                      goto badframe;
+-      }
++      set.sig[0] = sigctx.oldmask;
++      set.sig[1] = sigctx._unused[3];
++      restore_sigmask(&set);
+-      if (ka->sa.sa_flags & SA_ONESHOT)
+-              ka->sa.sa_handler = SIG_DFL;
++      sr = (struct mcontext *) sigctx.regs;
++      if (verify_area(VERIFY_READ, sr, sizeof(*sr))
++          || restore_user_regs(regs, sr))
++              goto badframe;
+-      if (!(ka->sa.sa_flags & SA_NODEFER)) {
+-              spin_lock_irq(&current->sighand->siglock);
+-              sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+-              sigaddset(&current->blocked,sig);
+-              recalc_sigpending();
+-              spin_unlock_irq(&current->sighand->siglock);
+-      }
+-      return;
++      sigreturn_exit(regs);           /* doesn't return */
++      return 0;
+ badframe:
+-#if DEBUG_SIG
+-      printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
+-             regs, frame, *newspp);
+-      printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
+-#endif
+-      do_exit(SIGSEGV);
++      force_sig(SIGSEGV, current);
++      return 0;
+ }
+ /*
+@@ -475,7 +547,7 @@
+       siginfo_t info;
+       struct k_sigaction *ka;
+       unsigned long frame, newsp;
+-      int signr;
++      int signr, ret;
+       if (!oldset)
+               oldset = &current->blocked;
+@@ -483,40 +555,65 @@
+       newsp = frame = 0;
+       signr = get_signal_to_deliver(&info, regs, NULL);
+-      if (signr > 0) {
+-              ka = &current->sighand->action[signr-1];
+-              if ( (ka->sa.sa_flags & SA_ONSTACK)
+-                   && (! on_sig_stack(regs->gpr[1])))
+-                      newsp = (current->sas_ss_sp + current->sas_ss_size);
+-              else
+-                      newsp = regs->gpr[1];
+-              newsp = frame = newsp - sizeof(struct sigregs);
+-              /* Whee!  Actually deliver the signal.  */
+-              handle_signal(signr, &info, oldset, regs, &newsp, frame);
+-      }
++      ka = (signr == 0)? NULL: &current->sighand->action[signr-1];
+-      if (TRAP(regs) == 0x0C00) {     /* System Call! */
+-              if ((int)regs->result == -ERESTARTNOHAND ||
+-                  (int)regs->result == -ERESTARTSYS ||
+-                  (int)regs->result == -ERESTARTNOINTR) {
+-                      regs->gpr[3] = regs->orig_gpr3;
++      if (TRAP(regs) == 0x0C00                /* System Call! */
++          && regs->ccr & 0x10000000           /* error signalled */
++          && ((ret = regs->gpr[3]) == ERESTARTSYS
++              || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
++              || ret == ERESTART_RESTARTBLOCK)) {
++
++              if (signr > 0
++                  && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
++                      || (ret == ERESTARTSYS
++                          && !(ka->sa.sa_flags & SA_RESTART)))) {
++                      /* make the system call return an EINTR error */
++                      regs->result = -EINTR;
++                      regs->gpr[3] = EINTR;
++                      /* note that the cr0.SO bit is already set */
++                      /* clear any restart function that was set */
++                      if (ret == ERESTART_RESTARTBLOCK)
++                              current_thread_info()->restart_block.fn
++                                      = do_no_restart_syscall;
++              } else {
+                       regs->nip -= 4; /* Back up & retry system call */
+                       regs->result = 0;
+-              } else if ((int)regs->result == -ERESTART_RESTARTBLOCK) {
+-                      regs->gpr[0] = __NR_restart_syscall;
+-                      regs->nip -= 4;
+-                      regs->result = 0;
++                      regs->trap = 0;
++                      if (ret == ERESTART_RESTARTBLOCK)
++                              regs->gpr[0] = __NR_restart_syscall;
++                      else
++                              regs->gpr[3] = regs->orig_gpr3;
+               }
+       }
+-      if (newsp == frame)
++      if (signr == 0)
+               return 0;               /* no signals delivered */
++      if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
++          && !on_sig_stack(regs->gpr[1]))
++              newsp = current->sas_ss_sp + current->sas_ss_size;
++      else
++              newsp = regs->gpr[1];
++      newsp &= ~0xfUL;
++
++      /* Whee!  Actually deliver the signal.  */
+       if (ka->sa.sa_flags & SA_SIGINFO)
+-              setup_rt_frame(regs, (struct sigregs __user *) frame, newsp);
++              handle_rt_signal(signr, ka, &info, oldset, regs, newsp);
+       else
+-              setup_frame(regs, (struct sigregs __user *) frame, newsp);
++              handle_signal(signr, ka, &info, oldset, regs, newsp);
++
++      if (ka->sa.sa_flags & SA_ONESHOT)
++              ka->sa.sa_handler = SIG_DFL;
++
++      if (!(ka->sa.sa_flags & SA_NODEFER)) {
++              spin_lock_irq(&current->sighand->siglock);
++              sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
++              sigaddset(&current->blocked, signr);
++              recalc_sigpending();
++              spin_unlock_irq(&current->sighand->siglock);
++      }
++
+       return 1;
+ }
+Index: linux-2.6.0-test5/arch/ppc/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/time.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/time.c   2003-09-27 11:38:19.964493320 +0800
+@@ -83,6 +83,7 @@
+ unsigned tb_ticks_per_jiffy;
+ unsigned tb_to_us;
+ unsigned tb_last_stamp;
++unsigned long tb_to_ns_scale;
+ extern unsigned long wall_jiffies;
+@@ -309,6 +310,7 @@
+               tb_to_us = 0x418937;
+         } else {
+                 ppc_md.calibrate_decr();
++              tb_to_ns_scale = mulhwu(tb_to_us, 1000 << 10);
+       }
+       /* Now that the decrementer is calibrated, it can be used in case the 
+@@ -432,3 +434,26 @@
+       return mlt;
+ }
++unsigned long long sched_clock(void)
++{
++      unsigned long lo, hi, hi2;
++      unsigned long long tb;
++
++      if (!__USE_RTC()) {
++              do {
++                      hi = get_tbu();
++                      lo = get_tbl();
++                      hi2 = get_tbu();
++              } while (hi2 != hi);
++              tb = ((unsigned long long) hi << 32) | lo;
++              tb = (tb * tb_to_ns_scale) >> 10;
++      } else {
++              do {
++                      hi = get_rtcu();
++                      lo = get_rtcl();
++                      hi2 = get_rtcu();
++              } while (hi2 != hi);
++              tb = ((unsigned long long) hi) * 1000000000 + lo;
++      }
++      return tb;
++}
+Index: linux-2.6.0-test5/arch/ppc/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/kernel/traps.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/kernel/traps.c  2003-09-27 11:38:19.968492712 +0800
+@@ -95,14 +95,19 @@
+ }
+ void
+-_exception(int signr, struct pt_regs *regs)
++_exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+ {
+-      if (!user_mode(regs))
+-      {
++      siginfo_t info;
++
++      if (!user_mode(regs)) {
+               debugger(regs);
+               die("Exception in kernel mode", regs, signr);
+       }
+-      force_sig(signr, current);
++      info.si_signo = signr;
++      info.si_errno = 0;
++      info.si_code = code;
++      info.si_addr = (void *) addr;
++      force_sig_info(signr, &info, current);
+ }
+ /*
+@@ -154,12 +159,40 @@
+       return 0;
+ }
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
++/* On 4xx, the reason for the machine check or program exception
++   is in the ESR. */
++#define get_reason(regs)      ((regs)->dsisr)
++#define REASON_FP             0
++#define REASON_ILLEGAL                ESR_PIL
++#define REASON_PRIVILEGED     ESR_PPR
++#define REASON_TRAP           ESR_PTR
++
++/* single-step stuff */
++#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC)
++#define clear_single_step(regs)       (current->thread.dbcr0 &= ~DBCR0_IC)
++
++#else
++/* On non-4xx, the reason for the machine check or program
++   exception is in the MSR. */
++#define get_reason(regs)      ((regs)->msr)
++#define REASON_FP             0x100000
++#define REASON_ILLEGAL                0x80000
++#define REASON_PRIVILEGED     0x40000
++#define REASON_TRAP           0x20000
++
++#define single_stepping(regs) ((regs)->msr & MSR_SE)
++#define clear_single_step(regs)       ((regs)->msr &= ~MSR_SE)
++#endif
++
+ void
+ MachineCheckException(struct pt_regs *regs)
+ {
++      unsigned long reason = get_reason(regs);
++
+       if (user_mode(regs)) {
+               regs->msr |= MSR_RI;
+-              _exception(SIGSEGV, regs);
++              _exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+               return;
+       }
+@@ -178,10 +211,18 @@
+       if (check_io_access(regs))
+               return;
+-#ifndef CONFIG_4xx
+-      printk(KERN_CRIT "Machine check in kernel mode.\n");
+-      printk(KERN_CRIT "Caused by (from SRR1=%lx): ", regs->msr);
+-      switch (regs->msr & 0x601F0000) {
++#ifdef CONFIG_4xx
++      if (reason & ESR_IMCP) {
++              printk("Instruction");
++              mtspr(SPRN_ESR, reason & ~ESR_IMCP);
++      } else
++              printk("Data");
++      printk(" machine check in kernel mode.\n");
++
++#else /* !CONFIG_4xx */
++      printk("Machine check in kernel mode.\n");
++      printk("Caused by (from SRR1=%lx): ", reason);
++      switch (reason & 0x601F0000) {
+       case 0x80000:
+               printk("Machine check signal\n");
+               break;
+@@ -208,15 +249,6 @@
+       default:
+               printk("Unknown values in msr\n");
+       }
+-
+-#else /* CONFIG_4xx */
+-      /* Note that the ESR gets stored in regs->dsisr on 4xx. */
+-      if (regs->dsisr & ESR_MCI) {
+-              printk(KERN_CRIT "Instruction");
+-              mtspr(SPRN_ESR, regs->dsisr & ~ESR_MCI);
+-      } else
+-              printk(KERN_CRIT "Data");
+-      printk(" machine check in kernel mode.\n");
+ #endif /* CONFIG_4xx */
+       debugger(regs);
+@@ -238,7 +270,7 @@
+ {
+       printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx    %s\n",
+              regs->nip, regs->msr, regs->trap, print_tainted());
+-      _exception(SIGTRAP, regs);
++      _exception(SIGTRAP, regs, 0, 0);
+ }
+ void
+@@ -246,13 +278,13 @@
+ {
+       if (debugger_iabr_match(regs))
+               return;
+-      _exception(SIGTRAP, regs);
++      _exception(SIGTRAP, regs, TRAP_BRKPT, 0);
+ }
+ void
+ RunModeException(struct pt_regs *regs)
+ {
+-      _exception(SIGTRAP, regs);
++      _exception(SIGTRAP, regs, 0, 0);
+ }
+ /* Illegal instruction emulation support.  Originally written to
+@@ -271,17 +303,17 @@
+ static int
+ emulate_instruction(struct pt_regs *regs)
+ {
+-      uint    instword;
+-      uint    rd;
+-      uint    retval;
++      u32 instword;
++      u32 rd;
++      int retval;
+-      retval = EINVAL;
++      retval = -EINVAL;
+       if (!user_mode(regs))
+               return retval;
+       CHECK_FULL_REGS(regs);
+-      if (get_user(instword, (uint __user *)(regs->nip)))
++      if (get_user(instword, (u32 __user *)(regs->nip)))
+               return -EFAULT;
+       /* Emulate the mfspr rD, PVR.
+@@ -290,10 +322,23 @@
+               rd = (instword >> 21) & 0x1f;
+               regs->gpr[rd] = mfspr(PVR);
+               retval = 0;
+-      }
+-      if (retval == 0)
+               regs->nip += 4;
+-      return(retval);
++      }
++      return retval;
++}
++
++/*
++ * After we have successfully emulated an instruction, we have to
++ * check if the instruction was being single-stepped, and if so,
++ * pretend we got a single-step exception.  This was pointed out
++ * by Kumar Gala.  -- paulus
++ */
++static void emulate_single_step(struct pt_regs *regs)
++{
++      if (single_stepping(regs)) {
++              clear_single_step(regs);
++              _exception(SIGTRAP, regs, TRAP_TRACE, 0);
++      }
+ }
+ /*
+@@ -349,29 +394,47 @@
+ void
+ ProgramCheckException(struct pt_regs *regs)
+ {
+-      int errcode;
+-
+-#if defined(CONFIG_4xx)
+-      unsigned int esr = regs->dsisr;
+-      int isbpt = esr & ESR_PTR;
++      unsigned int reason = get_reason(regs);
+       extern int do_mathemu(struct pt_regs *regs);
+ #ifdef CONFIG_MATH_EMULATION
+-      if (!isbpt && do_mathemu(regs) == 0)
++      /* (reason & REASON_ILLEGAL) would be the obvious thing here,
++       * but there seems to be a hardware bug on the 405GP (RevD)
++       * that means ESR is sometimes set incorrectly - either to
++       * ESR_DST (!?) or 0.  In the process of chasing this with the
++       * hardware people - not sure if it can happen on any illegal
++       * instruction or only on FP instructions, whether there is a
++       * pattern to occurences etc. -dgibson 31/Mar/2003 */
++      if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
++              emulate_single_step(regs);
+               return;
++      }
+ #endif /* CONFIG_MATH_EMULATION */
+-#else /* ! CONFIG_4xx */
+-      int isbpt = regs->msr & 0x20000;
+-
+-      if (regs->msr & 0x100000) {
++      if (reason & REASON_FP) {
+               /* IEEE FP exception */
+-              _exception(SIGFPE, regs);
++              int code = 0;
++              u32 fpscr;
++
++              if (regs->msr & MSR_FP)
++                      giveup_fpu(current);
++              fpscr = current->thread.fpscr;
++              fpscr &= fpscr << 22;   /* mask summary bits with enables */
++              if (fpscr & FPSCR_VX)
++                      code = FPE_FLTINV;
++              else if (fpscr & FPSCR_OX)
++                      code = FPE_FLTOVF;
++              else if (fpscr & FPSCR_UX)
++                      code = FPE_FLTUND;
++              else if (fpscr & FPSCR_ZX)
++                      code = FPE_FLTDIV;
++              else if (fpscr & FPSCR_XX)
++                      code = FPE_FLTRES;
++              _exception(SIGFPE, regs, code, regs->nip);
+               return;
+       }
+-#endif /* ! CONFIG_4xx */
+-      if (isbpt) {
++      if (reason & REASON_TRAP) {
+               /* trap exception */
+               if (debugger_bpt(regs))
+                       return;
+@@ -379,17 +442,21 @@
+                       regs->nip += 4;
+                       return;
+               }
+-              _exception(SIGTRAP, regs);
++              _exception(SIGTRAP, regs, TRAP_BRKPT, 0);
+               return;
+       }
+-      /* Try to emulate it if we should. */
+-      if ((errcode = emulate_instruction(regs))) {
+-              if (errcode == -EFAULT)
+-                      _exception(SIGBUS, regs);
+-              else
+-                      _exception(SIGILL, regs);
++      if (reason & REASON_PRIVILEGED) {
++              /* Try to emulate it if we should. */
++              if (emulate_instruction(regs) == 0) {
++                      emulate_single_step(regs);
++                      return;
++              }
++              _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
++              return;
+       }
++
++      _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+ }
+ void
+@@ -398,7 +465,7 @@
+       regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
+       if (debugger_sstep(regs))
+               return;
+-      _exception(SIGTRAP, regs);
++      _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+ void
+@@ -414,12 +481,12 @@
+       if (fixed == -EFAULT) {
+               /* fixed == -EFAULT means the operand address was bad */
+               if (user_mode(regs))
+-                      force_sig(SIGSEGV, current);
++                      _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
+               else
+                       bad_page_fault(regs, regs->dar, SIGSEGV);
+               return;
+       }
+-      _exception(SIGBUS, regs);
++      _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+ }
+ void
+@@ -470,16 +537,17 @@
+ #endif
+       if (errcode) {
+               if (errcode > 0)
+-                      _exception(SIGFPE, regs);
++                      _exception(SIGFPE, regs, 0, 0);
+               else if (errcode == -EFAULT)
+-                      _exception(SIGSEGV, regs);
++                      _exception(SIGSEGV, regs, 0, 0);
+               else
+-                      _exception(SIGILL, regs);
+-      }
++                      _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
++      } else
++              emulate_single_step(regs);
+ }
+ #endif /* CONFIG_8xx */
+-#if defined(CONFIG_4xx)
++#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ void DebugException(struct pt_regs *regs, unsigned long debug_status)
+ {
+@@ -487,7 +555,7 @@
+       if (debug_status & DBSR_TIE) {          /* trap instruction*/
+               if (!user_mode(regs) && debugger_bpt(regs))
+                       return;
+-              _exception(SIGTRAP, regs);
++              _exception(SIGTRAP, regs, 0, 0);
+       }
+ #endif
+@@ -495,10 +563,10 @@
+               if (!user_mode(regs) && debugger_sstep(regs))
+                       return;
+               current->thread.dbcr0 &= ~DBCR0_IC;
+-              _exception(SIGTRAP, regs);
++              _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+       }
+ }
+-#endif /* CONFIG_4xx */
++#endif /* CONFIG_4xx || CONFIG_BOOKE */
+ #if !defined(CONFIG_TAU_INT)
+ void
+Index: linux-2.6.0-test5/arch/ppc/mm/cachemap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/mm/cachemap.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/mm/cachemap.c   2003-09-27 11:38:19.970492408 +0800
+@@ -101,7 +101,7 @@
+       if (! area)
+               goto out;
+-      va = VMALLOC_VMADDR(area->addr);
++      va = (unsigned long) area->addr;
+       flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
+       
+Index: linux-2.6.0-test5/arch/ppc/mm/pgtable.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/mm/pgtable.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/mm/pgtable.c    2003-09-27 11:38:19.974491800 +0800
+@@ -195,7 +195,7 @@
+               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);
+       }
+Index: linux-2.6.0-test5/arch/ppc/platforms/pmac_setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/ppc/platforms/pmac_setup.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/ppc/platforms/pmac_setup.c  2003-09-27 11:38:19.979491040 +0800
+@@ -107,7 +107,7 @@
+ extern int pmac_newworld;
+-#define DEFAULT_ROOT_DEVICE 0x0801    /* sda1 - slightly silly choice */
++#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
+ extern void zs_kgdb_hook(int tty_num);
+ static void ohare_init(void);
+Index: linux-2.6.0-test5/arch/s390/kernel/compat_linux.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/kernel/compat_linux.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/kernel/compat_linux.c  2003-09-27 11:38:19.998488152 +0800
+@@ -1316,13 +1316,16 @@
+ {
+       int err;
+-      err = put_user(stat->dev, &statbuf->st_dev);
++      if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++
++      err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
+       err |= put_user(stat->ino, &statbuf->st_ino);
+       err |= put_user(stat->mode, &statbuf->st_mode);
+       err |= put_user(stat->nlink, &statbuf->st_nlink);
+       err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+       err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+-      err |= put_user(stat->rdev, &statbuf->st_rdev);
++      err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
+       err |= put_user(stat->size, &statbuf->st_size);
+       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+       err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+@@ -2543,8 +2546,7 @@
+ }
+ struct stat64_emu31 {
+-      unsigned char   __pad0[6];
+-      unsigned short  st_dev;
++      unsigned long long  st_dev;
+       unsigned int    __pad1;
+ #define STAT64_HAS_BROKEN_ST_INO        1
+       u32             __st_ino;
+@@ -2552,8 +2554,7 @@
+       unsigned int    st_nlink;
+       u32             st_uid;
+       u32             st_gid;
+-      unsigned char   __pad2[6];
+-      unsigned short  st_rdev;
++      unsigned long long  st_rdev;
+       unsigned int    __pad3;
+       long            st_size;
+       u32             st_blksize;
+@@ -2569,93 +2570,55 @@
+       unsigned long   st_ino;
+ };    
+-static inline int
+-putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
++static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
+ {
+-    struct stat64_emu31 tmp;
+-   
+-    memset(&tmp, 0, sizeof(tmp));
+-
+-    tmp.st_dev = (unsigned short)kbuf->st_dev;
+-    tmp.st_ino = kbuf->st_ino;
+-    tmp.__st_ino = (u32)kbuf->st_ino;
+-    tmp.st_mode = kbuf->st_mode;
+-    tmp.st_nlink = (unsigned int)kbuf->st_nlink;
+-    tmp.st_uid = kbuf->st_uid;
+-    tmp.st_gid = kbuf->st_gid;
+-    tmp.st_rdev = (unsigned short)kbuf->st_rdev;
+-    tmp.st_size = kbuf->st_size;
+-    tmp.st_blksize = (u32)kbuf->st_blksize;
+-    tmp.st_blocks = (u32)kbuf->st_blocks;
+-    tmp.st_atime = (u32)kbuf->st_atime;
+-    tmp.st_mtime = (u32)kbuf->st_mtime;
+-    tmp.st_ctime = (u32)kbuf->st_ctime;
++      struct stat64_emu31 tmp;
+-    return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
+-}
++      memset(&tmp, 0, sizeof(tmp));
+-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
++      tmp.st_dev = huge_encode_dev(stat->dev);
++      tmp.st_ino = stat->ino;
++      tmp.__st_ino = (u32)stat->ino;
++      tmp.st_mode = stat->mode;
++      tmp.st_nlink = (unsigned int)stat->nlink;
++      tmp.uid = stat->uid;
++      tmp.gid = stat->gid;
++      tmp.st_rdev = huge_encode_dev(stat->rdev);
++      tmp.st_size = stat->st_size;
++      tmp.st_blksize = (u32)stat->blksize;
++      tmp.st_blocks = (u32)stat->blocks;
++      tmp.st_atime = (u32)stat->atime.tv_sec;
++      tmp.st_mtime = (u32)stat->mtime.tv_sec;
++      tmp.st_ctime = (u32)stat->ctime.tv_sec;
++
++      return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
++}
+ asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf, long flags)
+ {
+-    int ret;
+-    struct stat s;
+-    char * tmp;
+-    int err;
+-    mm_segment_t old_fs = get_fs();
+-    
+-    tmp = getname(filename);
+-    err = PTR_ERR(tmp);
+-    if (IS_ERR(tmp))   
+-          return err;
+-
+-    set_fs (KERNEL_DS);
+-    ret = sys_newstat(tmp, &s);
+-    set_fs (old_fs);
+-    putname(tmp);
+-    if (putstat64 (statbuf, &s)) 
+-          return -EFAULT;
+-    return ret;
++      struct kstat stat;
++      int ret = vfs_stat(filename, &stat);
++      if (!ret)
++              ret = cp_stat64(statbuf, &stat);
++      return ret;
+ }
+-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
+-
+ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf, long flags)
+ {
+-    int ret;
+-    struct stat s;
+-    char * tmp;
+-    int err;
+-    mm_segment_t old_fs = get_fs();
+-    
+-    tmp = getname(filename);
+-    err = PTR_ERR(tmp);
+-    if (IS_ERR(tmp))   
+-          return err;
+-
+-    set_fs (KERNEL_DS);
+-    ret = sys_newlstat(tmp, &s);
+-    set_fs (old_fs);
+-    putname(tmp);
+-    if (putstat64 (statbuf, &s)) 
+-          return -EFAULT;
+-    return ret;
++      struct kstat stat;
++      int ret = vfs_lstat(filename, &stat);
++      if (!ret)
++              ret = cp_stat64(statbuf, &stat);
++      return ret;
+ }
+-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
+-
+ asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf, long flags)
+ {
+-    int ret;
+-    struct stat s;
+-    mm_segment_t old_fs = get_fs();
+-    
+-    set_fs (KERNEL_DS);
+-    ret = sys_newfstat(fd, &s);
+-    set_fs (old_fs);
+-    if (putstat64 (statbuf, &s))
+-          return -EFAULT;
+-    return ret;
++      struct kstat stat;
++      int ret = vfs_fstat(fd, &stat);
++      if (!ret)
++              ret = cp_stat64(statbuf, &stat);
++      return ret;
+ }
+ /*
+Index: linux-2.6.0-test5/arch/s390/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/Makefile  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/Makefile       2003-09-27 11:38:19.999488000 +0800
+@@ -13,8 +13,6 @@
+ # Copyright (C) 1994 by Linus Torvalds
+ #
+-check_gcc = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+-
+ ifdef CONFIG_ARCH_S390_31
+ LDFLAGS               := -m elf_s390
+ CFLAGS                += -m31
+Index: linux-2.6.0-test5/arch/s390/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/mm/ioremap.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/mm/ioremap.c   2003-09-27 11:38:20.001487696 +0800
+@@ -124,7 +124,7 @@
+       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;
+       }
+Index: linux-2.6.0-test5/arch/sh/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/boot/compressed/misc.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/boot/compressed/misc.c   2003-09-27 11:38:20.003487392 +0800
+@@ -105,8 +105,8 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
+-      if (free_mem_ptr == 0) error("Memory error\n");
++      if (size <0) error("Malloc error");
++      if (free_mem_ptr == 0) error("Memory error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+@@ -114,7 +114,7 @@
+       free_mem_ptr += size;
+       if (free_mem_ptr >= free_mem_end_ptr)
+-              error("\nOut of memory\n");
++              error("Out of memory");
+       return p;
+ }
+@@ -180,7 +180,7 @@
+ static int fill_inbuf(void)
+ {
+       if (insize != 0) {
+-              error("ran out of input data\n");
++              error("ran out of input data");
+       }
+       inbuf = input_data;
+Index: linux-2.6.0-test5/arch/sh/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/kernel/setup.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/kernel/setup.c   2003-09-27 11:38:20.008486632 +0800
+@@ -353,7 +353,7 @@
+       sh_console_init();
+ #endif
+       
+-      ROOT_DEV = ORIG_ROOT_DEV;
++      ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+ #ifdef CONFIG_BLK_DEV_RAM
+       rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+Index: linux-2.6.0-test5/arch/sh/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/mm/init.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/mm/init.c        2003-09-27 11:38:20.011486176 +0800
+@@ -51,8 +51,8 @@
+ #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)
+Index: linux-2.6.0-test5/arch/sh/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sh/mm/ioremap.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sh/mm/ioremap.c     2003-09-27 11:38:20.012486024 +0800
+@@ -149,7 +149,7 @@
+       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;
+       }
+Index: linux-2.6.0-test5/arch/sparc64/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/defconfig      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/defconfig   2003-09-27 11:38:20.021484656 +0800
+@@ -1,13 +1,15 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++CONFIG_64BIT=y
+ CONFIG_MMU=y
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
+-CONFIG_BROKEN=y
++CONFIG_CLEAN_COMPILE=y
++CONFIG_STANDALONE=y
+ #
+ # General setup
+@@ -17,6 +19,7 @@
+ # 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
+@@ -51,6 +54,10 @@
+ CONFIG_US3_FREQ=m
+ CONFIG_US2E_FREQ=m
+ CONFIG_CPU_FREQ_PROC_INTF=y
++CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+ CONFIG_CPU_FREQ_GOV_USERSPACE=m
+ # CONFIG_CPU_FREQ_24_API is not set
+ CONFIG_SPARC64=y
+@@ -67,7 +74,6 @@
+ # CONFIG_PCI_LEGACY_PROC is not set
+ # CONFIG_PCI_NAMES is not set
+ CONFIG_SUN_OPENPROMFS=m
+-CONFIG_KCORE_ELF=y
+ CONFIG_SPARC32_COMPAT=y
+ CONFIG_COMPAT=y
+ CONFIG_BINFMT_ELF32=y
+@@ -102,8 +108,6 @@
+ # Graphics support
+ #
+ CONFIG_FB=y
+-# CONFIG_FB_CIRRUS is not set
+-# CONFIG_FB_PM2 is not set
+ # CONFIG_FB_CYBER2000 is not set
+ # CONFIG_FB_IMSTT is not set
+ # CONFIG_FB_BW2 is not set
+@@ -119,7 +123,6 @@
+ # CONFIG_FB_3DFX is not set
+ # CONFIG_FB_VOODOO1 is not set
+ # CONFIG_FB_TRIDENT is not set
+-# CONFIG_FB_PM3 is not set
+ CONFIG_FB_SBUS=y
+ CONFIG_FB_FFB=y
+ # CONFIG_FB_TCX is not set
+@@ -274,6 +277,7 @@
+ # SCSI device support
+ #
+ CONFIG_SCSI=y
++CONFIG_SCSI_PROC_FS=y
+ #
+ # SCSI support type (disk, tape, CD-ROM)
+@@ -309,7 +313,6 @@
+ # CONFIG_AIC79XX_DEBUG_ENABLE is not set
+ CONFIG_AIC79XX_DEBUG_MASK=0
+ # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+-# CONFIG_SCSI_DPT_I2O is not set
+ # CONFIG_SCSI_ADVANSYS is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+@@ -319,7 +322,7 @@
+ CONFIG_SCSI_EATA_PIO=m
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+ # CONFIG_SCSI_GDTH is not set
+-# CONFIG_SCSI_INITIO is not set
++CONFIG_SCSI_IPS=m
+ CONFIG_SCSI_INIA100=m
+ CONFIG_SCSI_PPA=m
+ CONFIG_SCSI_IMM=m
+@@ -330,15 +333,12 @@
+ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+-# CONFIG_SCSI_PCI2000 is not set
+-# CONFIG_SCSI_PCI2220I is not set
+ CONFIG_SCSI_QLOGIC_ISP=m
+ CONFIG_SCSI_QLOGIC_FC=y
+ CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+ CONFIG_SCSI_QLOGICPTI=m
+ CONFIG_SCSI_DC395x=m
+-# CONFIG_SCSI_DC390T is not set
+ # CONFIG_SCSI_NSP32 is not set
+ CONFIG_SCSI_DEBUG=m
+ CONFIG_SCSI_SUNESP=y
+@@ -474,6 +474,7 @@
+ CONFIG_BRIDGE=m
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
++CONFIG_BRIDGE_NETFILTER=y
+ #
+ # IP: Netfilter Configuration
+@@ -486,6 +487,7 @@
+ CONFIG_IP_NF_QUEUE=m
+ CONFIG_IP_NF_IPTABLES=m
+ CONFIG_IP_NF_MATCH_LIMIT=m
++CONFIG_IP_NF_MATCH_IPRANGE=m
+ CONFIG_IP_NF_MATCH_MAC=m
+ CONFIG_IP_NF_MATCH_PKTTYPE=m
+ CONFIG_IP_NF_MATCH_MARK=m
+@@ -501,16 +503,16 @@
+ 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_MATCH_PHYSDEV=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_TARGET_NETMAP=m
++CONFIG_IP_NF_TARGET_SAME=m
+ CONFIG_IP_NF_NAT_LOCAL=y
+ CONFIG_IP_NF_NAT_SNMP_BASIC=m
+ CONFIG_IP_NF_NAT_IRC=m
+@@ -522,6 +524,7 @@
+ CONFIG_IP_NF_TARGET_ECN=m
+ CONFIG_IP_NF_TARGET_DSCP=m
+ CONFIG_IP_NF_TARGET_MARK=m
++CONFIG_IP_NF_TARGET_CLASSIFY=m
+ CONFIG_IP_NF_TARGET_LOG=m
+ CONFIG_IP_NF_TARGET_ULOG=m
+ CONFIG_IP_NF_TARGET_TCPMSS=m
+@@ -558,21 +561,27 @@
+ # DECnet: Netfilter Configuration
+ #
+ CONFIG_DECNET_NF_GRABULATOR=m
++
++#
++# Bridge: Netfilter Configuration
++#
+ CONFIG_BRIDGE_NF_EBTABLES=m
++CONFIG_BRIDGE_EBT_BROUTE=m
+ CONFIG_BRIDGE_EBT_T_FILTER=m
+ CONFIG_BRIDGE_EBT_T_NAT=m
+-CONFIG_BRIDGE_EBT_BROUTE=m
+-CONFIG_BRIDGE_EBT_LOG=m
+-CONFIG_BRIDGE_EBT_IP=m
++CONFIG_BRIDGE_EBT_802_3=m
+ CONFIG_BRIDGE_EBT_ARP=m
+-CONFIG_BRIDGE_EBT_VLAN=m
++CONFIG_BRIDGE_EBT_IP=m
+ CONFIG_BRIDGE_EBT_MARK=m
+ CONFIG_BRIDGE_EBT_PKTTYPE=m
+ CONFIG_BRIDGE_EBT_STP=m
+-CONFIG_BRIDGE_EBT_SNAT=m
++CONFIG_BRIDGE_EBT_VLAN=m
++CONFIG_BRIDGE_EBT_ARPREPLY=m
+ CONFIG_BRIDGE_EBT_DNAT=m
+-CONFIG_BRIDGE_EBT_REDIRECT=m
+ CONFIG_BRIDGE_EBT_MARK_T=m
++CONFIG_BRIDGE_EBT_REDIRECT=m
++CONFIG_BRIDGE_EBT_SNAT=m
++CONFIG_BRIDGE_EBT_LOG=m
+ CONFIG_XFRM=y
+ CONFIG_XFRM_USER=m
+@@ -781,7 +790,6 @@
+ # Token Ring devices (depends on LLC=y)
+ #
+ CONFIG_NET_FC=y
+-# CONFIG_IPHASE5526 is not set
+ # CONFIG_RCPCI is not set
+ CONFIG_SHAPER=m
+@@ -830,8 +838,6 @@
+ #
+ # AX.25 network device drivers
+ #
+-# CONFIG_MKISS is not set
+-# CONFIG_6PACK is not set
+ # CONFIG_BPQETHER is not set
+ # CONFIG_BAYCOM_SER_FDX is not set
+ # CONFIG_BAYCOM_SER_HDX is not set
+@@ -875,7 +881,6 @@
+ #
+ # Old SIR device drivers
+ #
+-# CONFIG_IRTTY_OLD is not set
+ # CONFIG_IRPORT_SIR is not set
+ #
+@@ -886,7 +891,6 @@
+ # FIR device drivers
+ #
+ # CONFIG_USB_IRDA is not set
+-# CONFIG_TOSHIBA_OLD is not set
+ # CONFIG_TOSHIBA_FIR is not set
+ # CONFIG_VLSI_FIR is not set
+@@ -896,11 +900,6 @@
+ CONFIG_ISDN_BOOL=y
+ #
+-# Old ISDN4Linux
+-#
+-# CONFIG_ISDN is not set
+-
+-#
+ # CAPI subsystem
+ #
+ CONFIG_ISDN_CAPI=m
+@@ -1000,7 +999,6 @@
+ CONFIG_I2C_PHILIPSPAR=m
+ CONFIG_SCx200_ACB=m
+ CONFIG_I2C_ALGOPCF=m
+-# CONFIG_I2C_ELEKTOR is not set
+ CONFIG_I2C_CHARDEV=m
+ #
+@@ -1198,7 +1196,6 @@
+ #
+ # Video For Linux
+ #
+-CONFIG_VIDEO_PROC_FS=y
+ #
+ # Video Adapters
+@@ -1214,7 +1211,6 @@
+ CONFIG_TUNER_3036=m
+ # CONFIG_VIDEO_STRADIS is not set
+ # CONFIG_VIDEO_ZORAN is not set
+-# CONFIG_VIDEO_ZR36120 is not set
+ CONFIG_VIDEO_SAA7134=m
+ CONFIG_VIDEO_MXB=m
+ CONFIG_VIDEO_DPC=m
+@@ -1247,7 +1243,6 @@
+ CONFIG_DVB_GRUNDIG_29504_401=m
+ CONFIG_DVB_MT312=m
+ CONFIG_DVB_VES1820=m
+-# CONFIG_DVB_TDA1004X is not set
+ #
+ # Supported SAA7146 based PCI Adapters
+@@ -1262,7 +1257,6 @@
+ # Supported USB Adapters
+ #
+ # CONFIG_DVB_TTUSB_BUDGET is not set
+-# CONFIG_DVB_TTUSB_DEC is not set
+ #
+ # Supported FlexCopII (B2C2) Adapters
+@@ -1430,7 +1424,7 @@
+ #
+ # USB Network adaptors
+ #
+-CONFIG_USB_AX8817X=m
++CONFIG_USB_AX8817X_STANDALONE=m
+ CONFIG_USB_CATC=m
+ CONFIG_USB_KAWETH=m
+ CONFIG_USB_PEGASUS=m
+@@ -1455,6 +1449,11 @@
+ CONFIG_USB_CDCETHER=y
+ #
++# USB Network Adapters
++#
++CONFIG_USB_AX8817X=y
++
++#
+ # USB port drivers
+ #
+ CONFIG_USB_USS720=m
+Index: linux-2.6.0-test5/arch/sparc64/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/Kconfig        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/Kconfig     2003-09-27 11:38:20.029483440 +0800
+@@ -29,7 +29,8 @@
+         smartcard reader, if present.  Say Y to enable support for these.
+ config VT
+-      bool
++      bool "Virtual terminal" if EMBEDDED
++      select INPUT
+       default y
+       ---help---
+         If you say Y here, you will get support for terminal devices with
+@@ -59,7 +60,8 @@
+         shiny Linux system :-)
+ config VT_CONSOLE
+-      bool
++      bool "Support for console on virtual terminal" if EMBEDDED
++      depends on VT
+       default y
+       ---help---
+         The system console is the device which receives all kernel messages
+@@ -83,16 +85,6 @@
+       bool
+       default y
+-config HUGETLB_PAGE
+-      bool "SPARC64 Huge TLB Page Support"
+-      help
+-        This enables support for huge pages.  User space applications
+-        can make use of this support with the sys_alloc_hugepages and
+-        sys_free_hugepages system calls.  If your applications are
+-        huge page aware, then say Y here.
+-
+-        Otherwise, say N.
+-
+ config SMP
+       bool "Symmetric multi-processing support"
+       ---help---
+@@ -832,12 +824,19 @@
+         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
+Index: linux-2.6.0-test5/arch/sparc64/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/kernel/setup.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/kernel/setup.c      2003-09-27 11:38:20.034482680 +0800
+@@ -517,7 +517,7 @@
+       if (!root_flags)
+               root_mountflags &= ~MS_RDONLY;
+-      ROOT_DEV = root_dev;
++      ROOT_DEV = old_decode_dev(root_dev);
+ #ifdef CONFIG_BLK_DEV_INITRD
+       rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
+       rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
+Index: linux-2.6.0-test5/arch/sparc64/kernel/sys_sparc32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/kernel/sys_sparc32.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/kernel/sys_sparc32.c        2003-09-27 11:38:20.053479792 +0800
+@@ -1304,16 +1304,17 @@
+ {
+       int err;
+-      if (stat->size > MAX_NON_LFS)
++      if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
++          !old_valid_dev(stat->rdev))
+               return -EOVERFLOW;
+-      err  = put_user(stat->dev, &statbuf->st_dev);
++      err  = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
+       err |= put_user(stat->ino, &statbuf->st_ino);
+       err |= put_user(stat->mode, &statbuf->st_mode);
+       err |= put_user(stat->nlink, &statbuf->st_nlink);
+       err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+       err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+-      err |= put_user(stat->rdev, &statbuf->st_rdev);
++      err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
+       err |= put_user(stat->size, &statbuf->st_size);
+       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+       err |= put_user(0, &statbuf->__unused1);
+Index: linux-2.6.0-test5/arch/sparc64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/kernel/time.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/kernel/time.c       2003-09-27 11:38:20.062478424 +0800
+@@ -416,6 +416,7 @@
+ unsigned long timer_tick_compare;
+ static unsigned long timer_ticks_per_usec_quotient;
++static unsigned long timer_ticks_per_nsec_quotient;
+ #define TICK_SIZE (tick_nsec / 1000)
+@@ -1051,12 +1052,18 @@
+ #endif
+ /* The quotient formula is taken from the IA64 port. */
++#define SPARC64_USEC_PER_CYC_SHIFT    30UL
++#define SPARC64_NSEC_PER_CYC_SHIFT    30UL
+ void __init time_init(void)
+ {
+       unsigned long clock = sparc64_init_timers(timer_interrupt);
+       timer_ticks_per_usec_quotient =
+-              (((1000000UL << 30) +
++              (((1000000UL << SPARC64_USEC_PER_CYC_SHIFT) +
++                (clock / 2)) / clock);
++
++      timer_ticks_per_nsec_quotient =
++              (((NSEC_PER_SEC << SPARC64_NSEC_PER_CYC_SHIFT) +
+                 (clock / 2)) / clock);
+ #ifdef CONFIG_CPU_FREQ
+@@ -1072,7 +1079,16 @@
+       ticks += timer_tick_offset;
+       ticks -= timer_tick_compare;
+-      return (ticks * timer_ticks_per_usec_quotient) >> 30UL;
++      return (ticks * timer_ticks_per_usec_quotient)
++              >> SPARC64_USEC_PER_CYC_SHIFT;
++}
++
++unsigned long long sched_clock(void)
++{
++      unsigned long ticks = tick_ops->get_tick();
++
++      return (ticks * timer_ticks_per_nsec_quotient)
++              >> SPARC64_NSEC_PER_CYC_SHIFT;
+ }
+ int do_settimeofday(struct timespec *tv)
+Index: linux-2.6.0-test5/arch/sparc64/lib/rwlock.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/lib/rwlock.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/lib/rwlock.S        2003-09-27 11:38:20.063478272 +0800
+@@ -63,5 +63,33 @@
+       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:
+Index: linux-2.6.0-test5/arch/sparc64/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/mm/init.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/mm/init.c   2003-09-27 11:38:20.077476144 +0800
+@@ -1706,10 +1706,6 @@
+       unsigned long addr, last;
+       int i;
+-#ifndef CONFIG_SMP
+-      cpu_data(0).udelay_val = loops_per_jiffy;
+-#endif
+-
+       i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
+       i += 1;
+       sparc64_valid_addr_bitmap = (unsigned long *)
+Index: linux-2.6.0-test5/arch/sparc64/solaris/fs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/solaris/fs.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/solaris/fs.c        2003-09-27 11:38:20.083475232 +0800
+@@ -28,9 +28,6 @@
+ #include "conv.h"
+-#define R4_DEV(DEV) ((DEV & 0xff) | ((DEV & 0xff00) << 10))
+-#define R4_MAJOR(DEV) (((DEV) >> 18) & 0x3fff)
+-#define R4_MINOR(DEV) ((DEV) & 0x3ffff)
+ #define R3_VERSION    1
+ #define R4_VERSION    2
+@@ -84,15 +81,17 @@
+ static inline int putstat(struct sol_stat *ubuf, struct kstat *kbuf)
+ {
+-      if (kbuf->size > MAX_NON_LFS)
++      if (kbuf->size > MAX_NON_LFS ||
++          !sysv_valid_dev(kbuf->dev) ||
++          !sysv_valid_dev(kbuf->rdev))
+               return -EOVERFLOW;
+-      if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
++      if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev)        ||
+           __put_user (kbuf->ino, &ubuf->st_ino)               ||
+           __put_user (kbuf->mode, &ubuf->st_mode)             ||
+           __put_user (kbuf->nlink, &ubuf->st_nlink)   ||
+           __put_user (kbuf->uid, &ubuf->st_uid)               ||
+           __put_user (kbuf->gid, &ubuf->st_gid)               ||
+-          __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev)     ||
++          __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev)    ||
+           __put_user (kbuf->size, &ubuf->st_size)             ||
+           __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec)     ||
+           __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec)   ||
+@@ -109,13 +108,15 @@
+ static inline int putstat64(struct sol_stat64 *ubuf, struct kstat *kbuf)
+ {
+-      if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
++      if (!sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev))
++              return -EOVERFLOW;
++      if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev)        ||
+           __put_user (kbuf->ino, &ubuf->st_ino)               ||
+           __put_user (kbuf->mode, &ubuf->st_mode)             ||
+           __put_user (kbuf->nlink, &ubuf->st_nlink)   ||
+           __put_user (kbuf->uid, &ubuf->st_uid)               ||
+           __put_user (kbuf->gid, &ubuf->st_gid)               ||
+-          __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev)     ||
++          __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev)    ||
+           __put_user (kbuf->size, &ubuf->st_size)             ||
+           __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec)     ||
+           __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec)   ||
+@@ -245,13 +246,16 @@
+ asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev)
+ {
+-      int (*sys_mknod)(const char *,int,dev_t) = 
+-              (int (*)(const char *,int,dev_t))SYS(mknod);
+-      int major, minor;
+-
+-      if ((major = R4_MAJOR(dev)) > 255 || 
+-          (minor = R4_MINOR(dev)) > 255) return -EINVAL;
+-      return sys_mknod((const char *)A(path), mode, MKDEV(major,minor));
++      int (*sys_mknod)(const char *,int,unsigned) = 
++              (int (*)(const char *,int,unsigned))SYS(mknod);
++      int major = sysv_major(dev);
++      int minor = sysv_minor(dev);
++
++      /* minor is guaranteed to be OK for MKDEV, major might be not */
++      if (major > 0xfff)
++              return -EINVAL;
++      return sys_mknod((const char *)A(path), mode,
++                              new_encode_dev(MKDEV(major,minor)));
+ }
+ asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev)
+@@ -403,6 +407,8 @@
+               if (j > 15) j = 15;
+               if (IS_RDONLY(inode)) i = 1;
+               if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
++              if (!sysv_valid_dev(inode->i_sb->s_dev))
++                      return -EOVERFLOW;
+               if (put_user (s.f_bsize, &ss->f_bsize)          ||
+                   __put_user (0, &ss->f_frsize)               ||
+                   __put_user (s.f_blocks, &ss->f_blocks)      ||
+@@ -411,7 +417,7 @@
+                   __put_user (s.f_files, &ss->f_files)        ||
+                   __put_user (s.f_ffree, &ss->f_ffree)        ||
+                   __put_user (s.f_ffree, &ss->f_favail)       ||
+-                  __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
++                  __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
+                   __copy_to_user (ss->f_basetype,p,j)         ||
+                   __put_user (0, (char *)&ss->f_basetype[j])  ||
+                   __put_user (s.f_namelen, &ss->f_namemax)    ||
+@@ -437,6 +443,8 @@
+               if (j > 15) j = 15;
+               if (IS_RDONLY(inode)) i = 1;
+               if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
++              if (!sysv_valid_dev(inode->i_sb->s_dev))
++                      return -EOVERFLOW;
+               if (put_user (s.f_bsize, &ss->f_bsize)          ||
+                   __put_user (0, &ss->f_frsize)               ||
+                   __put_user (s.f_blocks, &ss->f_blocks)      ||
+@@ -445,7 +453,7 @@
+                   __put_user (s.f_files, &ss->f_files)        ||
+                   __put_user (s.f_ffree, &ss->f_ffree)        ||
+                   __put_user (s.f_ffree, &ss->f_favail)       ||
+-                  __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) ||
++                  __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
+                   __copy_to_user (ss->f_basetype,p,j)         ||
+                   __put_user (0, (char *)&ss->f_basetype[j])  ||
+                   __put_user (s.f_namelen, &ss->f_namemax)    ||
+Index: linux-2.6.0-test5/arch/sparc64/solaris/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc64/solaris/misc.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc64/solaris/misc.c      2003-09-27 11:38:20.089474320 +0800
+@@ -392,7 +392,7 @@
+       
+       switch (cmd) {
+       case 0: /* getpgrp */
+-              return current->pgrp;
++              return process_group(current);
+       case 1: /* setpgrp */
+               {
+                       int (*sys_setpgid)(pid_t,pid_t) =
+@@ -403,7 +403,7 @@
+                       ret = sys_setpgid(0, 0);
+                       if (ret) return ret;
+                       current->tty = NULL;
+-                      return current->pgrp;
++                      return process_group(current);
+               }
+       case 2: /* getsid */
+               {
+Index: linux-2.6.0-test5/arch/sparc/boot/btfixupprep.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/boot/btfixupprep.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/boot/btfixupprep.c    2003-09-27 11:38:20.093473712 +0800
+@@ -171,6 +171,8 @@
+                       }
+               } else if (buffer[nbase+4] != '_')
+                       continue;
++              if (!strcmp (sect, ".text.exit"))
++                      continue;
+               if (strcmp (sect, ".text") &&
+                   strcmp (sect, ".init.text") &&
+                   strcmp (sect, ".fixup") &&
+Index: linux-2.6.0-test5/arch/sparc/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/kernel/setup.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/kernel/setup.c        2003-09-27 11:38:20.096473256 +0800
+@@ -321,7 +321,7 @@
+       if (!root_flags)
+               root_mountflags &= ~MS_RDONLY;
+-      ROOT_DEV = root_dev;
++      ROOT_DEV = old_decode_dev(root_dev);
+ #ifdef CONFIG_BLK_DEV_INITRD
+       rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
+       rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
+Index: linux-2.6.0-test5/arch/sparc/kernel/sun4d_smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/kernel/sun4d_smp.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/kernel/sun4d_smp.c    2003-09-27 11:38:20.100472648 +0800
+@@ -343,11 +343,11 @@
+                       unsigned long a3 asm("i3") = arg3;
+                       unsigned long a4 asm("i4") = arg4;
+                       unsigned long a5 asm("i5") = arg5;
+-                                      
+-                      __asm__ __volatile__("
+-                              std %0, [%6]
+-                              std %2, [%6 + 8]
+-                              std %4, [%6 + 16]" : : 
++
++                      __asm__ __volatile__(
++                              "std %0, [%6]\n\t"
++                              "std %2, [%6 + 8]\n\t"
++                              "std %4, [%6 + 16]\n\t" : :
+                               "r"(f), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5),
+                               "r" (&ccall_info.func));
+               }
+Index: linux-2.6.0-test5/arch/sparc/lib/checksum.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/lib/checksum.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/lib/checksum.S        2003-09-27 11:38:20.106471736 +0800
+@@ -145,36 +145,39 @@
+       .globl C_LABEL(__csum_partial_copy_start), C_LABEL(__csum_partial_copy_end)
+ C_LABEL(__csum_partial_copy_start):
+-#define EX(x,y,a,b,z)                           \
++/* Work around cpp -rob */
++#define ALLOC #alloc
++#define EXECINSTR #execinstr
++#define EX(x,y,a,b)                           \
+ 98:     x,y;                                    \
+-        .section .fixup,z##alloc,z##execinstr;  \
++        .section .fixup,ALLOC,EXECINSTR;      \
+         .align  4;                              \
+ 99:     ba 30f;                                 \
+          a, b, %o3;                             \
+-        .section __ex_table,z##alloc;           \
++        .section __ex_table,ALLOC;            \
+         .align  4;                              \
+         .word   98b, 99b;                       \
+         .text;                                  \
+         .align  4
+-#define EX2(x,y,z)                            \
++#define EX2(x,y)                              \
+ 98:     x,y;                                    \
+-        .section __ex_table,z##alloc;           \
++        .section __ex_table,ALLOC;            \
+         .align  4;                              \
+         .word   98b, 30f;                       \
+         .text;                                  \
+         .align  4
+-#define EX3(x,y,z)                            \
++#define EX3(x,y)                              \
+ 98:     x,y;                                    \
+-        .section __ex_table,z##alloc;           \
++        .section __ex_table,ALLOC;            \
+         .align  4;                              \
+         .word   98b, 96f;                       \
+         .text;                                  \
+         .align  4
+-#define EXT(start,end,handler,z)                \
+-        .section __ex_table,z##alloc;           \
++#define EXT(start,end,handler)                        \
++        .section __ex_table,ALLOC;            \
+         .align  4;                              \
+         .word   start, 0, end, handler;         \
+         .text;                                  \
+@@ -247,21 +250,21 @@
+ cc_end_cruft:
+       be      1f
+        andcc  %o3, 4, %g0
+-      EX(ldd  [%o0 + 0x00], %g2, and %o3, 0xf,#)
++      EX(ldd  [%o0 + 0x00], %g2, and %o3, 0xf)
+       add     %o1, 8, %o1
+       addcc   %g2, %g7, %g7
+       add     %o0, 8, %o0
+       addxcc  %g3, %g7, %g7
+-      EX2(st  %g2, [%o1 - 0x08],#)
++      EX2(st  %g2, [%o1 - 0x08])
+       addx    %g0, %g7, %g7
+       andcc   %o3, 4, %g0
+-      EX2(st  %g3, [%o1 - 0x04],#)
++      EX2(st  %g3, [%o1 - 0x04])
+ 1:    be      1f
+        andcc  %o3, 3, %o3
+-      EX(ld   [%o0 + 0x00], %g2, add %o3, 4,#)
++      EX(ld   [%o0 + 0x00], %g2, add %o3, 4)
+       add     %o1, 4, %o1
+       addcc   %g2, %g7, %g7
+-      EX2(st  %g2, [%o1 - 0x04],#)
++      EX2(st  %g2, [%o1 - 0x04])
+       addx    %g0, %g7, %g7
+       andcc   %o3, 3, %g0
+       add     %o0, 4, %o0
+@@ -271,14 +274,14 @@
+        subcc  %o3, 2, %o3
+       b       4f
+        or     %g0, %g0, %o4
+-2:    EX(lduh [%o0 + 0x00], %o4, add %o3, 2,#)
++2:    EX(lduh [%o0 + 0x00], %o4, add %o3, 2)
+       add     %o0, 2, %o0
+-      EX2(sth %o4, [%o1 + 0x00],#)
++      EX2(sth %o4, [%o1 + 0x00])
+       be      6f
+        add    %o1, 2, %o1
+       sll     %o4, 16, %o4
+-4:    EX(ldub [%o0 + 0x00], %o5, add %g0, 1,#)
+-      EX2(stb %o5, [%o1 + 0x00],#)
++4:    EX(ldub [%o0 + 0x00], %o5, add %g0, 1)
++      EX2(stb %o5, [%o1 + 0x00])
+       sll     %o5, 8, %o5
+       or      %o5, %o4, %o4
+ 6:    addcc   %o4, %g7, %g7
+@@ -295,9 +298,9 @@
+        andcc  %o0, 0x2, %g0
+       be      1f
+        andcc  %o0, 0x4, %g0
+-      EX(lduh [%o0 + 0x00], %g4, add %g1, 0,#)
++      EX(lduh [%o0 + 0x00], %g4, add %g1, 0)
+       sub     %g1, 2, %g1
+-      EX2(sth %g4, [%o1 + 0x00],#)
++      EX2(sth %g4, [%o1 + 0x00])
+       add     %o0, 2, %o0
+       sll     %g4, 16, %g4
+       addcc   %g4, %g7, %g7
+@@ -311,9 +314,9 @@
+       or      %g3, %g7, %g7
+ 1:    be      3f
+        andcc  %g1, 0xffffff80, %g0
+-      EX(ld   [%o0 + 0x00], %g4, add %g1, 0,#)
++      EX(ld   [%o0 + 0x00], %g4, add %g1, 0)
+       sub     %g1, 4, %g1
+-      EX2(st  %g4, [%o1 + 0x00],#)
++      EX2(st  %g4, [%o1 + 0x00])
+       add     %o0, 4, %o0
+       addcc   %g4, %g7, %g7
+       add     %o1, 4, %o1
+@@ -342,7 +345,7 @@
+       CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+       CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+       CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+-10:   EXT(5b, 10b, 20f,#)             ! note for exception handling
++10:   EXT(5b, 10b, 20f)               ! note for exception handling
+       sub     %g1, 128, %g1           ! detract from length
+       addx    %g0, %g7, %g7           ! add in last carry bit
+       andcc   %g1, 0xffffff80, %g0    ! more to csum?
+@@ -367,7 +370,7 @@
+       CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x28,%g2,%g3,%g4,%g5)
+       CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x18,%g2,%g3,%g4,%g5)
+       CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x08,%g2,%g3,%g4,%g5)
+-12:   EXT(cctbl, 12b, 22f,#)          ! note for exception table handling
++12:   EXT(cctbl, 12b, 22f)            ! note for exception table handling
+       addx    %g0, %g7, %g7
+       andcc   %o3, 0xf, %g0           ! check for low bits set
+ ccte: bne     cc_end_cruft            ! something left, handle it out of band
+@@ -378,7 +381,7 @@
+       CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+       CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+       CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
+-11:   EXT(ccdbl, 11b, 21f,#)          ! note for exception table handling
++11:   EXT(ccdbl, 11b, 21f)            ! note for exception table handling
+       sub     %g1, 128, %g1           ! detract from length
+       addx    %g0, %g7, %g7           ! add in last carry bit
+       andcc   %g1, 0xffffff80, %g0    ! more to csum?
+@@ -395,9 +398,9 @@
+       be,a    1f
+        srl    %g1, 1, %g4             
+       sub     %g1, 1, %g1     
+-      EX(ldub [%o0], %g5, add %g1, 1,#)
++      EX(ldub [%o0], %g5, add %g1, 1)
+       add     %o0, 1, %o0     
+-      EX2(stb %g5, [%o1],#)
++      EX2(stb %g5, [%o1])
+       srl     %g1, 1, %g4
+       add     %o1, 1, %o1
+ 1:    cmp     %g4, 0          
+@@ -406,34 +409,34 @@
+       andcc   %o0, 2, %g0     
+       be,a    1f
+        srl    %g4, 1, %g4
+-      EX(lduh [%o0], %o4, add %g1, 0,#)
++      EX(lduh [%o0], %o4, add %g1, 0)
+       sub     %g1, 2, %g1     
+       srl     %o4, 8, %g2
+       sub     %g4, 1, %g4     
+-      EX2(stb %g2, [%o1],#)
++      EX2(stb %g2, [%o1])
+       add     %o4, %g5, %g5
+-      EX2(stb %o4, [%o1 + 1],#)
++      EX2(stb %o4, [%o1 + 1])
+       add     %o0, 2, %o0     
+       srl     %g4, 1, %g4
+       add     %o1, 2, %o1
+ 1:    cmp     %g4, 0          
+       be,a    2f
+        andcc  %g1, 2, %g0
+-      EX3(ld  [%o0], %o4,#)
++      EX3(ld  [%o0], %o4)
+ 5:    srl     %o4, 24, %g2
+       srl     %o4, 16, %g3
+-      EX2(stb %g2, [%o1],#)
++      EX2(stb %g2, [%o1])
+       srl     %o4, 8, %g2
+-      EX2(stb %g3, [%o1 + 1],#)
++      EX2(stb %g3, [%o1 + 1])
+       add     %o0, 4, %o0
+-      EX2(stb %g2, [%o1 + 2],#)
++      EX2(stb %g2, [%o1 + 2])
+       addcc   %o4, %g5, %g5
+-      EX2(stb %o4, [%o1 + 3],#)
++      EX2(stb %o4, [%o1 + 3])
+       addx    %g5, %g0, %g5   ! I am now to lazy to optimize this (question it
+       add     %o1, 4, %o1     ! is worthy). Maybe some day - with the sll/srl
+       subcc   %g4, 1, %g4     ! tricks
+       bne,a   5b
+-       EX3(ld [%o0], %o4,#)
++       EX3(ld [%o0], %o4)
+       sll     %g5, 16, %g2
+       srl     %g5, 16, %g5
+       srl     %g2, 16, %g2
+@@ -441,19 +444,19 @@
+       add     %g2, %g5, %g5 
+ 2:    be,a    3f              
+        andcc  %g1, 1, %g0
+-      EX(lduh [%o0], %o4, and %g1, 3,#)
++      EX(lduh [%o0], %o4, and %g1, 3)
+       andcc   %g1, 1, %g0
+       srl     %o4, 8, %g2
+       add     %o0, 2, %o0     
+-      EX2(stb %g2, [%o1],#)
++      EX2(stb %g2, [%o1])
+       add     %g5, %o4, %g5
+-      EX2(stb %o4, [%o1 + 1],#)
++      EX2(stb %o4, [%o1 + 1])
+       add     %o1, 2, %o1
+ 3:    be,a    1f              
+        sll    %g5, 16, %o4
+-      EX(ldub [%o0], %g2, add %g0, 1,#)
++      EX(ldub [%o0], %g2, add %g0, 1)
+       sll     %g2, 8, %o4     
+-      EX2(stb %g2, [%o1],#)
++      EX2(stb %g2, [%o1])
+       add     %g5, %o4, %g5
+       sll     %g5, 16, %o4
+ 1:    addcc   %o4, %g5, %g5
+Index: linux-2.6.0-test5/arch/sparc/lib/copy_user.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/lib/copy_user.S  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/lib/copy_user.S       2003-09-27 11:38:20.110471128 +0800
+@@ -16,41 +16,44 @@
+ #include <asm/asmmacro.h>
+ #include <asm/page.h>
+-#define EX(x,y,a,b,z)                                 \
++/* Work around cpp -rob */
++#define ALLOC #alloc
++#define EXECINSTR #execinstr
++#define EX(x,y,a,b)                           \
+ 98:   x,y;                                    \
+-      .section .fixup,z##alloc,z##execinstr;  \
++      .section .fixup,ALLOC,EXECINSTR;        \
+       .align  4;                              \
+ 99:   ba fixupretl;                           \
+        a, b, %g3;                             \
+-      .section __ex_table,z##alloc;           \
++      .section __ex_table,ALLOC;              \
+       .align  4;                              \
+       .word   98b, 99b;                       \
+       .text;                                  \
+       .align  4
+-#define EX2(x,y,c,d,e,a,b,z)                  \
++#define EX2(x,y,c,d,e,a,b)                    \
+ 98:   x,y;                                    \
+-      .section .fixup,z##alloc,z##execinstr;  \
++      .section .fixup,ALLOC,EXECINSTR;        \
+       .align  4;                              \
+ 99:   c, d, e;                                \
+       ba fixupretl;                           \
+        a, b, %g3;                             \
+-      .section __ex_table,z##alloc;           \
++      .section __ex_table,ALLOC;              \
+       .align  4;                              \
+       .word   98b, 99b;                       \
+       .text;                                  \
+       .align  4
+-#define EXO2(x,y,z)                           \
+-98:   x,##y;                                  \
+-      .section __ex_table,z##alloc;           \
++#define EXO2(x,y)                             \
++98:   x, y;                                   \
++      .section __ex_table,ALLOC;              \
+       .align  4;                              \
+       .word   98b, 97f;                       \
+       .text;                                  \
+       .align  4
+-#define EXT(start,end,handler,z)              \
+-      .section __ex_table,z##alloc;           \
++#define EXT(start,end,handler)                        \
++      .section __ex_table,ALLOC;              \
+       .align  4;                              \
+       .word   start, 0, end, handler;         \
+       .text;                                  \
+@@ -121,23 +124,23 @@
+       be      4f
+        andcc  %o1, 2, %g0
+-      EXO2(ldub [%o1], %g2,#)
++      EXO2(ldub [%o1], %g2)
+       add     %o1, 1, %o1
+-      EXO2(stb %g2, [%o0],#)
++      EXO2(stb %g2, [%o0])
+       sub     %o2, 1, %o2
+       bne     3f
+        add    %o0, 1, %o0
+-      EXO2(lduh [%o1], %g2,#)
++      EXO2(lduh [%o1], %g2)
+       add     %o1, 2, %o1
+-      EXO2(sth %g2, [%o0],#)
++      EXO2(sth %g2, [%o0])
+       sub     %o2, 2, %o2
+       b       3f
+        add    %o0, 2, %o0
+ 4:
+-      EXO2(lduh [%o1], %g2,#)
++      EXO2(lduh [%o1], %g2)
+       add     %o1, 2, %o1
+-      EXO2(sth %g2, [%o0],#)
++      EXO2(sth %g2, [%o0])
+       sub     %o2, 2, %o2
+       b       3f
+        add    %o0, 2, %o0
+@@ -160,9 +163,9 @@
+       be      2f
+        mov    %o2, %g1
+-      EXO2(ld [%o1], %o4,#)
++      EXO2(ld [%o1], %o4)
+       sub     %g1, 4, %g1
+-      EXO2(st %o4, [%o0],#)
++      EXO2(st %o4, [%o0])
+       add     %o1, 4, %o1
+       add     %o0, 4, %o0
+ 2:
+@@ -177,7 +180,7 @@
+       MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+       MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ 80:
+-      EXT(5b, 80b, 50f,#)
++      EXT(5b, 80b, 50f)
+       subcc   %g7, 128, %g7
+       add     %o1, 128, %o1
+       bne     5b
+@@ -204,37 +207,37 @@
+       MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
+       MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+ copy_user_table_end:
+-      EXT(copy_user_table, copy_user_table_end, 51f,#)
++      EXT(copy_user_table, copy_user_table_end, 51f)
+       be      copy_user_last7
+        andcc  %g1, 4, %g0
+-      EX(ldd  [%o1], %g2, and %g1, 0xf,#)
++      EX(ldd  [%o1], %g2, and %g1, 0xf)
+       add     %o0, 8, %o0
+       add     %o1, 8, %o1
+-      EX(st   %g2, [%o0 - 0x08], and %g1, 0xf,#)
+-      EX2(st  %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4,#)
++      EX(st   %g2, [%o0 - 0x08], and %g1, 0xf)
++      EX2(st  %g3, [%o0 - 0x04], and %g1, 0xf, %g1, sub %g1, 4)
+ copy_user_last7:
+       be      1f
+        andcc  %g1, 2, %g0
+-      EX(ld   [%o1], %g2, and %g1, 7,#)
++      EX(ld   [%o1], %g2, and %g1, 7)
+       add     %o1, 4, %o1
+-      EX(st   %g2, [%o0], and %g1, 7,#)
++      EX(st   %g2, [%o0], and %g1, 7)
+       add     %o0, 4, %o0
+ 1:
+       be      1f
+        andcc  %g1, 1, %g0
+-      EX(lduh [%o1], %g2, and %g1, 3,#)
++      EX(lduh [%o1], %g2, and %g1, 3)
+       add     %o1, 2, %o1
+-      EX(sth  %g2, [%o0], and %g1, 3,#)
++      EX(sth  %g2, [%o0], and %g1, 3)
+       add     %o0, 2, %o0
+ 1:
+       be      1f
+        nop
+-      EX(ldub [%o1], %g2, add %g0, 1,#)
+-      EX(stb  %g2, [%o0], add %g0, 1,#)
++      EX(ldub [%o1], %g2, add %g0, 1)
++      EX(stb  %g2, [%o0], add %g0, 1)
+ 1:
+       retl
+        clr    %o0
+@@ -245,7 +248,7 @@
+       MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+       MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ 81:
+-      EXT(ldd_std, 81b, 52f,#)
++      EXT(ldd_std, 81b, 52f)
+       subcc   %g7, 128, %g7
+       add     %o1, 128, %o1
+       bne     ldd_std
+@@ -274,9 +277,9 @@
+       be      10f
+        nop
+-      EXO2(ldub [%o1], %g2,#)
++      EXO2(ldub [%o1], %g2)
+       add     %o1, 1, %o1
+-      EXO2(stb %g2, [%o0],#)
++      EXO2(stb %g2, [%o0])
+       sub     %o2, 1, %o2
+       andcc   %o2, 0xfffffff0, %o3
+       be      short_end
+@@ -285,7 +288,7 @@
+       MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+       MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5)
+ 82:
+-      EXT(10b, 82b, 53f,#)
++      EXT(10b, 82b, 53f)
+       subcc   %o3, 0x10, %o3
+       add     %o1, 0x10, %o1
+       bne     10b
+@@ -303,7 +306,7 @@
+       MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3)
+       MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3)
+ 83:
+-      EXT(byte_chunk, 83b, 54f,#)
++      EXT(byte_chunk, 83b, 54f)
+       subcc   %o3, 0x10, %o3
+       add     %o1, 0x10, %o1
+       bne     byte_chunk
+@@ -328,11 +331,11 @@
+       MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
+       MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
+ short_table_end:
+-      EXT(84b, short_table_end, 55f,#)
++      EXT(84b, short_table_end, 55f)
+       be      1f
+        nop
+-      EX(ldub [%o1], %g2, add %g0, 1,#)
+-      EX(stb  %g2, [%o0], add %g0, 1,#)
++      EX(ldub [%o1], %g2, add %g0, 1)
++      EX(stb  %g2, [%o0], add %g0, 1)
+ 1:
+       retl
+        clr    %o0
+@@ -344,11 +347,11 @@
+       be      1f
+        andcc  %o2, 4, %g0
+-      EXO2(ld [%o1 + 0x00], %g2,#)
+-      EXO2(ld [%o1 + 0x04], %g3,#)
++      EXO2(ld [%o1 + 0x00], %g2)
++      EXO2(ld [%o1 + 0x04], %g3)
+       add     %o1, 8, %o1
+-      EXO2(st %g2, [%o0 + 0x00],#)
+-      EX(st   %g3, [%o0 + 0x04], sub %o2, 4,#)
++      EXO2(st %g2, [%o0 + 0x00])
++      EX(st   %g3, [%o0 + 0x04], sub %o2, 4)
+       add     %o0, 8, %o0
+ 1:
+       b       copy_user_last7
+Index: linux-2.6.0-test5/arch/sparc/lib/memset.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/lib/memset.S     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/lib/memset.S  2003-09-27 11:38:20.112470824 +0800
+@@ -10,20 +10,23 @@
+ #include <asm/cprefix.h>
+ #include <asm/ptrace.h>
+-#define EX(x,y,a,b,z)                                 \
++/* Work around cpp -rob */
++#define ALLOC #alloc
++#define EXECINSTR #execinstr
++#define EX(x,y,a,b)                           \
+ 98:   x,y;                                    \
+-      .section .fixup,z##alloc,z##execinstr;  \
++      .section .fixup,ALLOC,EXECINSTR;        \
+       .align  4;                              \
+ 99:   ba 30f;                                 \
+        a, b, %o0;                             \
+-      .section __ex_table,z##alloc;           \
++      .section __ex_table,ALLOC;              \
+       .align  4;                              \
+       .word   98b, 99b;                       \
+       .text;                                  \
+       .align  4
+-#define EXT(start,end,handler,z)              \
+-      .section __ex_table,z##alloc;           \
++#define EXT(start,end,handler)                        \
++      .section __ex_table,ALLOC;              \
+       .align  4;                              \
+       .word   start, 0, end, handler;         \
+       .text;                                  \
+@@ -74,13 +77,13 @@
+ 3:
+       cmp     %o2, 3
+       be      2f
+-       EX(stb %g3, [%o0], sub %o1, 0,#)
++       EX(stb %g3, [%o0], sub %o1, 0)
+       cmp     %o2, 2
+       be      2f
+-       EX(stb %g3, [%o0 + 0x01], sub %o1, 1,#)
++       EX(stb %g3, [%o0 + 0x01], sub %o1, 1)
+-      EX(stb  %g3, [%o0 + 0x02], sub %o1, 2,#)
++      EX(stb  %g3, [%o0 + 0x02], sub %o1, 2)
+ 2:
+       sub     %o2, 4, %o2
+       add     %o1, %o2, %o1
+@@ -101,7 +104,7 @@
+       be      2f
+        mov    %g3, %g2
+-      EX(st   %g3, [%o0], sub %o1, 0,#)
++      EX(st   %g3, [%o0], sub %o1, 0)
+       sub     %o1, 4, %o1
+       add     %o0, 4, %o0
+ 2:
+@@ -113,7 +116,7 @@
+       subcc   %o3, 128, %o3
+       ZERO_BIG_BLOCK(%o0, 0x40, %g2)
+ 11:
+-      EXT(10b, 11b, 20f,#)
++      EXT(10b, 11b, 20f)
+       bne     10b
+        add    %o0, 128, %o0
+@@ -138,17 +141,17 @@
+       be      1f
+        andcc  %o1, 2, %g0
+-      EX(st   %g3, [%o0], and %o1, 7,#)
++      EX(st   %g3, [%o0], and %o1, 7)
+       add     %o0, 4, %o0
+ 1:
+       be      1f
+        andcc  %o1, 1, %g0
+-      EX(sth  %g3, [%o0], and %o1, 3,#)
++      EX(sth  %g3, [%o0], and %o1, 3)
+       add     %o0, 2, %o0
+ 1:
+       bne,a   8f
+-       EX(stb %g3, [%o0], and %o1, 1,#)
++       EX(stb %g3, [%o0], and %o1, 1)
+ 8:
+       retl
+        clr    %o0
+@@ -161,7 +164,7 @@
+        add    %o0, 1, %o0
+       subcc   %o1, 1, %o1
+       bne,a   8b
+-       EX(stb %g3, [%o0 - 1], add %o1, 1,#)
++       EX(stb %g3, [%o0 - 1], add %o1, 1)
+ 0:
+       retl
+        clr    %o0
+Index: linux-2.6.0-test5/arch/sparc/math-emu/sfp-util.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/math-emu/sfp-util.h      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/math-emu/sfp-util.h   2003-09-27 11:38:20.113470672 +0800
+@@ -4,8 +4,8 @@
+ #include <asm/byteorder.h>
+ #define add_ssaaaa(sh, sl, ah, al, bh, bl)                            \
+-  __asm__ ("addcc %r4,%5,%1
+-      addx %r2,%3,%0"                                                 \
++  __asm__ ("addcc %r4,%5,%1\n\t"                                              \
++         "addx %r2,%3,%0\n"                                           \
+          : "=r" ((USItype)(sh)),                                      \
+            "=&r" ((USItype)(sl))                                      \
+          : "%rJ" ((USItype)(ah)),                                     \
+@@ -14,8 +14,8 @@
+            "rI" ((USItype)(bl))                                       \
+          : "cc")
+ #define sub_ddmmss(sh, sl, ah, al, bh, bl)                            \
+-  __asm__ ("subcc %r4,%5,%1
+-      subx %r2,%3,%0"                                                 \
++  __asm__ ("subcc %r4,%5,%1\n\t"                                              \
++         "subx %r2,%3,%0\n"                                           \
+          : "=r" ((USItype)(sh)),                                      \
+            "=&r" ((USItype)(sl))                                      \
+          : "rJ" ((USItype)(ah)),                                      \
+@@ -25,46 +25,46 @@
+          : "cc")
+ #define umul_ppmm(w1, w0, u, v) \
+-  __asm__ ("! Inlined umul_ppmm
+-      wr      %%g0,%2,%%y     ! SPARC has 0-3 delay insn after a wr
+-      sra     %3,31,%%g2      ! Don't move this insn
+-      and     %2,%%g2,%%g2    ! Don't move this insn
+-      andcc   %%g0,0,%%g1     ! Don't move this insn
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,%3,%%g1
+-      mulscc  %%g1,0,%%g1
+-      add     %%g1,%%g2,%0
+-      rd      %%y,%1"                                                 \
++  __asm__ ("! Inlined umul_ppmm\n\t"                                  \
++      "wr     %%g0,%2,%%y     ! SPARC has 0-3 delay insn after a wr\n\t" \
++      "sra    %3,31,%%g2      ! Don't move this insn\n\t"             \
++      "and    %2,%%g2,%%g2    ! Don't move this insn\n\t"             \
++      "andcc  %%g0,0,%%g1     ! Don't move this insn\n\t"             \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,%3,%%g1\n\t"                                       \
++      "mulscc %%g1,0,%%g1\n\t"                                        \
++      "add    %%g1,%%g2,%0\n\t"                                       \
++      "rd     %%y,%1\n"                                               \
+          : "=r" ((USItype)(w1)),                                      \
+            "=r" ((USItype)(w0))                                       \
+          : "%rI" ((USItype)(u)),                                      \
+@@ -74,30 +74,30 @@
+ /* It's quite necessary to add this much assembler for the sparc.
+    The default udiv_qrnnd (in C) is more than 10 times slower!  */
+ #define udiv_qrnnd(q, r, n1, n0, d) \
+-  __asm__ ("! Inlined udiv_qrnnd
+-      mov     32,%%g1
+-      subcc   %1,%2,%%g0
+-1:    bcs     5f
+-       addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
+-      sub     %1,%2,%1        ! this kills msb of n
+-      addx    %1,%1,%1        ! so this can't give carry
+-      subcc   %%g1,1,%%g1
+-2:    bne     1b
+-       subcc  %1,%2,%%g0
+-      bcs     3f
+-       addxcc %0,%0,%0        ! shift n1n0 and a q-bit in lsb
+-      b       3f
+-       sub    %1,%2,%1        ! this kills msb of n
+-4:    sub     %1,%2,%1
+-5:    addxcc  %1,%1,%1
+-      bcc     2b
+-       subcc  %%g1,1,%%g1
+-! Got carry from n.  Subtract next step to cancel this carry.
+-      bne     4b
+-       addcc  %0,%0,%0        ! shift n1n0 and a 0-bit in lsb
+-      sub     %1,%2,%1
+-3:    xnor    %0,0,%0
+-      ! End of inline udiv_qrnnd"                                     \
++  __asm__ ("! Inlined udiv_qrnnd\n\t"                                 \
++         "mov 32,%%g1\n\t"                                            \
++         "subcc       %1,%2,%%g0\n\t"                                 \
++         "1:  bcs     5f\n\t"                                         \
++         "addxcc %0,%0,%0     ! shift n1n0 and a q-bit in lsb\n\t"    \
++         "sub %1,%2,%1        ! this kills msb of n\n\t"              \
++         "addx        %1,%1,%1        ! so this can't give carry\n\t" \
++         "subcc       %%g1,1,%%g1\n\t"                                \
++         "2:  bne     1b\n\t"                                         \
++         "subcc       %1,%2,%%g0\n\t"                                 \
++         "bcs 3f\n\t"                                                 \
++         "addxcc %0,%0,%0     ! shift n1n0 and a q-bit in lsb\n\t"    \
++         "b           3f\n\t"                                         \
++         "sub %1,%2,%1        ! this kills msb of n\n\t"              \
++         "4:  sub     %1,%2,%1\n\t"                                   \
++         "5:  addxcc  %1,%1,%1\n\t"                                   \
++         "bcc 2b\n\t"                                                 \
++         "subcc       %%g1,1,%%g1\n\t"                                \
++         "! Got carry from n.  Subtract next step to cancel this carry.\n\t" \
++         "bne 4b\n\t"                                                 \
++         "addcc       %0,%0,%0        ! shift n1n0 and a 0-bit in lsb\n\t" \
++         "sub %1,%2,%1\n\t"                                           \
++         "3:  xnor    %0,0,%0\n\t"                                    \
++         "! End of inline udiv_qrnnd\n"                               \
+          : "=&r" ((USItype)(q)),                                      \
+            "=&r" ((USItype)(r))                                       \
+          : "r" ((USItype)(d)),                                        \
+Index: linux-2.6.0-test5/arch/sparc/mm/srmmu.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/sparc/mm/srmmu.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/sparc/mm/srmmu.c    2003-09-27 11:38:20.132467784 +0800
+@@ -330,9 +330,6 @@
+       offset = bit_map_string_get(&srmmu_nocache_map,
+                                       size >> SRMMU_NOCACHE_BITMAP_SHIFT,
+                                       align >> SRMMU_NOCACHE_BITMAP_SHIFT);
+-/* P3 */ /* printk("srmmu: get size %d align %d, got %d (0x%x)\n",
+-   size >> SRMMU_NOCACHE_BITMAP_SHIFT, align >> SRMMU_NOCACHE_BITMAP_SHIFT,
+-   offset, offset); */
+       if (offset == -1) {
+               printk("srmmu: out of nocache %d: %d/%d\n",
+                   size, (int) srmmu_nocache_size,
+@@ -385,7 +382,6 @@
+       offset = (vaddr - SRMMU_NOCACHE_VADDR) >> SRMMU_NOCACHE_BITMAP_SHIFT;
+       size = size >> SRMMU_NOCACHE_BITMAP_SHIFT;
+-/* P3 */ /* printk("srmmu: free off %d (0x%x) size %d\n", offset, offset, size); */
+       bit_map_clear(&srmmu_nocache_map, offset, size);
+ }
+@@ -447,9 +443,6 @@
+       paddr = __pa((unsigned long)srmmu_nocache_pool);
+       vaddr = SRMMU_NOCACHE_VADDR;
+-/* P3 */ printk("srmmu: pool 0x%x vaddr 0x%x bitmap 0x%x bits %d (0x%x)\n",
+-  (int)srmmu_nocache_pool, vaddr, srmmu_nocache_bitmap, bitmap_bits, bitmap_bits);
+-
+       while (vaddr < srmmu_nocache_end) {
+               pgd = pgd_offset_k(vaddr);
+               pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr);
+Index: linux-2.6.0-test5/arch/um/config.release
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/config.release      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/config.release   2003-09-27 11:38:20.135467328 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/defconfig   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/defconfig        2003-09-27 11:38:20.138466872 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/drivers/chan_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/chan_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/chan_kern.c      2003-09-27 11:38:20.141466416 +0800
+@@ -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"
+Index: linux-2.6.0-test5/arch/um/drivers/chan_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/chan_user.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/chan_user.c      2003-09-27 11:38:20.144465960 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/drivers/cow.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow.h       2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow.h    2003-09-27 11:38:20.144465960 +0800
+@@ -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:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/cow_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow_kern.c  2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow_kern.c       2003-09-27 11:38:20.145465808 +0800
+@@ -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:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/cow_sys.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow_sys.h   2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow_sys.h        2003-09-27 11:38:20.146465656 +0800
+@@ -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:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/cow_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/cow_user.c  2003-09-27 11:38:18.441724816 +0800
++++ linux-2.6.0-test5/arch/um/drivers/cow_user.c       2003-09-27 11:38:20.147465504 +0800
+@@ -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:
++ */
+Index: linux-2.6.0-test5/arch/um/drivers/hostaudio_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/hostaudio_kern.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/hostaudio_kern.c 2003-09-27 11:38:20.149465200 +0800
+@@ -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){
+Index: linux-2.6.0-test5/arch/um/drivers/line.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/line.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/line.c   2003-09-27 11:38:20.154464440 +0800
+@@ -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);
+       }
+Index: linux-2.6.0-test5/arch/um/drivers/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/Makefile    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/Makefile 2003-09-27 11:38:20.155464288 +0800
+@@ -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 $@ $<
+Index: linux-2.6.0-test5/arch/um/drivers/mconsole_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/mconsole_kern.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/mconsole_kern.c  2003-09-27 11:38:20.159463680 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/drivers/mconsole_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/mconsole_user.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/mconsole_user.c  2003-09-27 11:38:20.161463376 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/drivers/mmapper_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/mmapper_kern.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/mmapper_kern.c   2003-09-27 11:38:20.163463072 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/drivers/net_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/net_kern.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/net_kern.c       2003-09-27 11:38:20.168462312 +0800
+@@ -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);
+ }
+Index: linux-2.6.0-test5/arch/um/drivers/port_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/port_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/port_kern.c      2003-09-27 11:38:20.171461856 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/drivers/ssl.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/ssl.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/ssl.c    2003-09-27 11:38:20.173461552 +0800
+@@ -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,
+Index: linux-2.6.0-test5/arch/um/drivers/stdio_console.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/stdio_console.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/stdio_console.c  2003-09-27 11:38:20.176461096 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/drivers/ubd_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/ubd_kern.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/ubd_kern.c       2003-09-27 11:38:20.183460032 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/drivers/ubd_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/ubd_user.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/ubd_user.c       2003-09-27 11:38:20.188459272 +0800
+@@ -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;
+Index: linux-2.6.0-test5/arch/um/drivers/xterm.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/xterm.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/xterm.c  2003-09-27 11:38:20.190458968 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/drivers/xterm_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/drivers/xterm_kern.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/drivers/xterm_kern.c     2003-09-27 11:38:20.192458664 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/dyn.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/dyn.lds.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/dyn.lds.S        2003-09-27 11:38:20.194458360 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/include/irq_kern.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/irq_kern.h  2003-09-27 11:38:18.442724664 +0800
++++ linux-2.6.0-test5/arch/um/include/irq_kern.h       2003-09-27 11:38:20.195458208 +0800
+@@ -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:
++ */
+Index: linux-2.6.0-test5/arch/um/include/kern_util.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/kern_util.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/kern_util.h      2003-09-27 11:38:20.197457904 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/include/line.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/line.h      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/line.h   2003-09-27 11:38:20.199457600 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/include/mconsole.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/mconsole.h  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/mconsole.h       2003-09-27 11:38:20.200457448 +0800
+@@ -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, 
+Index: linux-2.6.0-test5/arch/um/include/mem.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/mem.h       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/mem.h    2003-09-27 11:38:20.202457144 +0800
+@@ -13,7 +13,6 @@
+ };
+ extern void set_usable_vm(unsigned long start, unsigned long end);
+-extern void set_kmem_end(unsigned long new);
+ #endif
+Index: linux-2.6.0-test5/arch/um/include/mem_user.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/mem_user.h  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/mem_user.h       2003-09-27 11:38:20.203456992 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/include/os.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/os.h        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/os.h     2003-09-27 11:38:20.204456840 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/include/sysdep-i386/sigcontext.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/sysdep-i386/sigcontext.h    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/sysdep-i386/sigcontext.h 2003-09-27 11:38:20.206456536 +0800
+@@ -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)))
+Index: linux-2.6.0-test5/arch/um/include/ubd_user.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/ubd_user.h  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/ubd_user.h       2003-09-27 11:38:20.207456384 +0800
+@@ -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)
+ {
+Index: linux-2.6.0-test5/arch/um/include/user.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/user.h      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/user.h   2003-09-27 11:38:20.209456080 +0800
+@@ -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
+ /*
+Index: linux-2.6.0-test5/arch/um/include/user_util.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/include/user_util.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/include/user_util.h      2003-09-27 11:38:20.210455928 +0800
+@@ -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
+ /*
+Index: linux-2.6.0-test5/arch/um/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Kconfig     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Kconfig  2003-09-27 11:38:20.213455472 +0800
+@@ -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"
+@@ -105,6 +119,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"
+@@ -239,6 +263,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"
+Index: linux-2.6.0-test5/arch/um/Kconfig_block
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Kconfig_block       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Kconfig_block    2003-09-27 11:38:20.214455320 +0800
+@@ -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"
+Index: linux-2.6.0-test5/arch/um/Kconfig_net
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Kconfig_net 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Kconfig_net      2003-09-27 11:38:20.218454712 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/kernel/config.c.in
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/config.c.in  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/config.c.in       2003-09-27 11:38:20.219454560 +0800
+@@ -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)
+ {
+Index: linux-2.6.0-test5/arch/um/kernel/init_task.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/init_task.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/init_task.c       2003-09-27 11:38:20.221454256 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/irq.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/irq.c     2003-09-27 11:38:20.227453344 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/Makefile     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/Makefile  2003-09-27 11:38:20.228453192 +0800
+@@ -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:
+Index: linux-2.6.0-test5/arch/um/kernel/mem.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/mem.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/mem.c     2003-09-27 11:38:20.234452280 +0800
+@@ -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;
+Index: linux-2.6.0-test5/arch/um/kernel/mem_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/mem_user.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/mem_user.c        2003-09-27 11:38:20.236451976 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/kernel/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/process.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/process.c 2003-09-27 11:38:20.239451520 +0800
+@@ -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);
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/process_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/process_kern.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/process_kern.c    2003-09-27 11:38:20.241451216 +0800
+@@ -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);
+ }
+ /*
+Index: linux-2.6.0-test5/arch/um/kernel/ptrace.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/ptrace.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/ptrace.c  2003-09-27 11:38:20.244450760 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/kernel/sigio_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/sigio_kern.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/sigio_kern.c      2003-09-27 11:38:20.245450608 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/kernel/signal_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/signal_kern.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/signal_kern.c     2003-09-27 11:38:20.248450152 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/kernel/skas/include/mode.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/include/mode.h  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/include/mode.h       2003-09-27 11:38:20.250449848 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/kernel/skas/include/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/include/uaccess.h       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/include/uaccess.h    2003-09-27 11:38:20.252449544 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/kernel/skas/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/Makefile        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/Makefile     2003-09-27 11:38:20.253449392 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/kernel/skas/process.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/process.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/process.c    2003-09-27 11:38:20.257448784 +0800
+@@ -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);
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/skas/process_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/process_kern.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/process_kern.c       2003-09-27 11:38:20.259448480 +0800
+@@ -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;
+Index: linux-2.6.0-test5/arch/um/kernel/skas/util/mk_ptregs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/skas/util/mk_ptregs.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/skas/util/mk_ptregs.c     2003-09-27 11:38:20.261448176 +0800
+@@ -1,3 +1,4 @@
++#include <stdio.h>
+ #include <asm/ptrace.h>
+ #include <asm/user.h>
+Index: linux-2.6.0-test5/arch/um/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/smp.c        2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/smp.c     2003-09-27 11:38:20.264447720 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/kernel/syscall_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/syscall_kern.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/syscall_kern.c    2003-09-27 11:38:20.267447264 +0800
+@@ -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;
+@@ -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));
+Index: linux-2.6.0-test5/arch/um/kernel/sys_call_table.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/sys_call_table.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/sys_call_table.c  2003-09-27 11:38:20.273446352 +0800
+@@ -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 ] = 
+Index: linux-2.6.0-test5/arch/um/kernel/sysrq.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/sysrq.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/sysrq.c   2003-09-27 11:38:20.274446200 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/time.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/time.c    2003-09-27 11:38:20.276445896 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/kernel/time_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/time_kern.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/time_kern.c       2003-09-27 11:38:20.277445744 +0800
+@@ -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);
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/trap_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/trap_kern.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/trap_kern.c       2003-09-27 11:38:20.280445288 +0800
+@@ -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)
+ {
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/trap_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/trap_user.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/trap_user.c       2003-09-27 11:38:20.281445136 +0800
+@@ -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,
+Index: linux-2.6.0-test5/arch/um/kernel/tt/exec_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/exec_kern.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/exec_kern.c    2003-09-27 11:38:20.283444832 +0800
+@@ -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();
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/tt/include/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/include/uaccess.h 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/include/uaccess.h      2003-09-27 11:38:20.284444680 +0800
+@@ -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,
+Index: linux-2.6.0-test5/arch/um/kernel/tt/process_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/process_kern.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/process_kern.c 2003-09-27 11:38:20.289443920 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/kernel/tt/ptproxy/proxy.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/ptproxy/proxy.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/ptproxy/proxy.c        2003-09-27 11:38:20.292443464 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/kernel/tt/tracer.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/tracer.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/tracer.c       2003-09-27 11:38:20.296442856 +0800
+@@ -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;
+       }
+Index: linux-2.6.0-test5/arch/um/kernel/tt/uaccess_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/tt/uaccess_user.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/tt/uaccess_user.c 2003-09-27 11:38:20.297442704 +0800
+@@ -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;
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/um_arch.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/um_arch.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/um_arch.c 2003-09-27 11:38:20.301442096 +0800
+@@ -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()));
+ }
+Index: linux-2.6.0-test5/arch/um/kernel/umid.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/umid.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/umid.c    2003-09-27 11:38:20.303441792 +0800
+@@ -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);
+ /*
+Index: linux-2.6.0-test5/arch/um/kernel/user_util.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/kernel/user_util.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/kernel/user_util.c       2003-09-27 11:38:20.306441336 +0800
+@@ -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;
+Index: linux-2.6.0-test5/arch/um/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Makefile    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Makefile 2003-09-27 11:38:20.309440880 +0800
+@@ -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 
+Index: linux-2.6.0-test5/arch/um/Makefile-i386
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Makefile-i386       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Makefile-i386    2003-09-27 11:38:20.310440728 +0800
+@@ -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)
+Index: linux-2.6.0-test5/arch/um/Makefile-skas
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/Makefile-skas       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/Makefile-skas    2003-09-27 11:38:20.311440576 +0800
+@@ -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,$@)
+Index: linux-2.6.0-test5/arch/um/os-Linux/drivers/tuntap_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/os-Linux/drivers/tuntap_user.c      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/os-Linux/drivers/tuntap_user.c   2003-09-27 11:38:20.314440120 +0800
+@@ -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);
+Index: linux-2.6.0-test5/arch/um/os-Linux/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/os-Linux/file.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/os-Linux/file.c  2003-09-27 11:38:20.316439816 +0800
+@@ -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
+Index: linux-2.6.0-test5/arch/um/sys-i386/bugs.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/sys-i386/bugs.c     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/sys-i386/bugs.c  2003-09-27 11:38:20.318439512 +0800
+@@ -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);
+ }
+Index: linux-2.6.0-test5/arch/um/sys-i386/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/sys-i386/Makefile   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/sys-i386/Makefile        2003-09-27 11:38:20.319439360 +0800
+@@ -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:
+Index: linux-2.6.0-test5/arch/um/uml.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/uml.lds.S   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/uml.lds.S        2003-09-27 11:38:20.321439056 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/arch/um/util/mk_constants_kern.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/um/util/mk_constants_kern.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/um/util/mk_constants_kern.c 2003-09-27 11:38:20.322438904 +0800
+@@ -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);
+ }
+Index: linux-2.6.0-test5/arch/x86_64/boot/compressed/head.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/boot/compressed/head.S  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/boot/compressed/head.S       2003-09-27 11:38:20.324438600 +0800
+@@ -26,6 +26,7 @@
+ .code32
+ .text
++#define IN_BOOTLOADER
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+Index: linux-2.6.0-test5/arch/x86_64/boot/compressed/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/boot/compressed/misc.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/boot/compressed/misc.c       2003-09-27 11:38:20.327438144 +0800
+@@ -9,6 +9,7 @@
+  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+  */
++#define IN_BOOTLOADER
+ #include "miscsetup.h"
+ #include <asm/io.h>
+@@ -116,8 +117,8 @@
+ {
+       void *p;
+-      if (size <0) error("Malloc error\n");
+-      if (free_mem_ptr <= 0) error("Memory error\n");
++      if (size <0) error("Malloc error");
++      if (free_mem_ptr <= 0) error("Memory error");
+       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+@@ -125,7 +126,7 @@
+       free_mem_ptr += size;
+       if (free_mem_ptr >= free_mem_end_ptr)
+-              error("\nOut of memory\n");
++              error("Out of memory");
+       return p;
+ }
+@@ -215,7 +216,7 @@
+ static int fill_inbuf(void)
+ {
+       if (insize != 0) {
+-              error("ran out of input data\n");
++              error("ran out of input data");
+       }
+       inbuf = input_data;
+@@ -280,9 +281,9 @@
+ void setup_normal_output_buffer(void)
+ {
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+-      if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
++      if (EXT_MEM_K < 1024) error("Less than 2MB of memory");
+ #else
+-      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
++      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
+ #endif
+       output_data = (char *)0x100000; /* Points to 1M */
+       free_mem_end_ptr = (long)real_mode;
+@@ -297,9 +298,9 @@
+ {
+       high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ #ifdef STANDARD_MEMORY_BIOS_CALL
+-      if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
++      if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory");
+ #else
+-      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
++      if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory");
+ #endif        
+       mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+       low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
+Index: linux-2.6.0-test5/arch/x86_64/ia32/ia32_ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/ia32/ia32_ioctl.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/ia32/ia32_ioctl.c    2003-09-27 11:38:20.334437080 +0800
+@@ -35,7 +35,7 @@
+       real_tty = (struct tty_struct *)file->private_data;
+       if (!real_tty)  
+               return -EINVAL; 
+-      return put_user(real_tty->device, ptr); 
++      return put_user(tty_devnum(real_tty), ptr); 
+ } 
+Index: linux-2.6.0-test5/arch/x86_64/ia32/sys_ia32.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/ia32/sys_ia32.c 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/ia32/sys_ia32.c      2003-09-27 11:38:20.348434952 +0800
+@@ -89,27 +89,18 @@
+ #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
+ extern int overflowuid,overflowgid; 
+-
+-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
+-
+-
+-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
+-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
+-
+-
+ int cp_compat_stat(struct kstat *kbuf, struct compat_stat *ubuf)
+ {
++      if (!old_valid_dev(kbuf->dev) || !old_valid_dev(kbuf->rdev))
++              return -EOVERFLOW;
+       if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
+-          __put_user (kbuf->dev, &ubuf->st_dev) ||
++          __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
+           __put_user (kbuf->ino, &ubuf->st_ino) ||
+           __put_user (kbuf->mode, &ubuf->st_mode) ||
+           __put_user (kbuf->nlink, &ubuf->st_nlink) ||
+           __put_user (kbuf->uid, &ubuf->st_uid) ||
+           __put_user (kbuf->gid, &ubuf->st_gid) ||
+-          __put_user (kbuf->rdev, &ubuf->st_rdev) ||
++          __put_user (old_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
+           __put_user (kbuf->size, &ubuf->st_size) ||
+           __put_user (kbuf->atime.tv_sec, &ubuf->st_atime) ||
+           __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) ||
+@@ -127,26 +118,26 @@
+    support for 64bit inode numbers. */
+ static int
+-putstat64(struct stat64 *ubuf, struct stat *kbuf)
++cp_stat64(struct stat64 *ubuf, struct kstat *stat)
+ {
+       if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
+-          __put_user (kbuf->st_dev, &ubuf->st_dev) ||
+-          __put_user (kbuf->st_ino, &ubuf->__st_ino) ||
+-          __put_user (kbuf->st_ino, &ubuf->st_ino) ||
+-          __put_user (kbuf->st_mode, &ubuf->st_mode) ||
+-          __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
+-          __put_user (kbuf->st_uid, &ubuf->st_uid) ||
+-          __put_user (kbuf->st_gid, &ubuf->st_gid) ||
+-          __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
+-          __put_user (kbuf->st_size, &ubuf->st_size) ||
+-          __put_user (kbuf->st_atime, &ubuf->st_atime) ||
+-          __put_user (kbuf->st_atime_nsec, &ubuf->st_atime_nsec) ||
+-          __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
+-          __put_user (kbuf->st_mtime_nsec, &ubuf->st_mtime_nsec) ||
+-          __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
+-          __put_user (kbuf->st_ctime_nsec, &ubuf->st_ctime_nsec) ||
+-          __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
+-          __put_user (kbuf->st_blocks, &ubuf->st_blocks))
++          __put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) ||
++          __put_user (stat->ino, &ubuf->__st_ino) ||
++          __put_user (stat->ino, &ubuf->st_ino) ||
++          __put_user (stat->mode, &ubuf->st_mode) ||
++          __put_user (stat->nlink, &ubuf->st_nlink) ||
++          __put_user (stat->uid, &ubuf->st_uid) ||
++          __put_user (stat->gid, &ubuf->st_gid) ||
++          __put_user (huge_encode_dev(stat->rdev), &ubuf->st_rdev) ||
++          __put_user (stat->size, &ubuf->st_size) ||
++          __put_user (stat->atime.tv_sec, &ubuf->st_atime) ||
++          __put_user (stat->atime.tv_nsec, &ubuf->st_atime_nsec) ||
++          __put_user (stat->mtime.tv_sec, &ubuf->st_mtime) ||
++          __put_user (stat->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
++          __put_user (stat->ctime.tv_sec, &ubuf->st_ctime) ||
++          __put_user (stat->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
++          __put_user (stat->blksize, &ubuf->st_blksize) ||
++          __put_user (stat->blocks, &ubuf->st_blocks))
+               return -EFAULT;
+       return 0;
+ }
+@@ -154,50 +145,33 @@
+ asmlinkage long
+ sys32_stat64(char * filename, struct stat64 *statbuf)
+ {
+-      int ret;
+-      struct stat s;
+-      mm_segment_t old_fs = get_fs();
+-      
+-      set_fs (KERNEL_DS);
+-      ret = sys_newstat(filename, &s);
+-      set_fs (old_fs);
+-      if (putstat64 (statbuf, &s))
+-              return -EFAULT;
++      struct kstat stat;
++      int ret = vfs_stat(filename, &stat);
++      if (!ret)
++              ret = cp_stat64(statbuf, &stat);
+       return ret;
+ }
+ asmlinkage long
+ sys32_lstat64(char * filename, struct stat64 *statbuf)
+ {
+-      int ret;
+-      struct stat s;
+-      mm_segment_t old_fs = get_fs();
+-      
+-      set_fs (KERNEL_DS);
+-      ret = sys_newlstat(filename, &s);
+-      set_fs (old_fs);
+-      if (putstat64 (statbuf, &s))
+-              return -EFAULT;
++      struct kstat stat;
++      int ret = vfs_lstat(filename, &stat);
++      if (!ret)
++              ret = cp_stat64(statbuf, &stat);
+       return ret;
+ }
+ asmlinkage long
+ sys32_fstat64(unsigned int fd, struct stat64 *statbuf)
+ {
+-      int ret;
+-      struct stat s;
+-      mm_segment_t old_fs = get_fs();
+-      
+-      set_fs (KERNEL_DS);
+-      ret = sys_newfstat(fd, &s);
+-      set_fs (old_fs);
+-      if (putstat64 (statbuf, &s))
+-              return -EFAULT;
++      struct kstat stat;
++      int ret = vfs_fstat(fd, &stat);
++      if (!ret)
++              ret = cp_stat64(statbuf, &stat);
+       return ret;
+ }
+-
+-
+ /*
+  * Linux/i386 didn't use to be able to handle more than
+  * 4 system call parameters, so these system calls used a memory
+@@ -1476,7 +1450,7 @@
+ extern int sys_ustat(dev_t, struct ustat *);
+-long sys32_ustat(dev_t dev, struct ustat32 *u32p)
++long sys32_ustat(unsigned dev, struct ustat32 *u32p)
+ {
+       struct ustat u;
+       mm_segment_t seg;
+Index: linux-2.6.0-test5/arch/x86_64/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/Kconfig 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/Kconfig      2003-09-27 11:38:20.352434344 +0800
+@@ -171,14 +171,6 @@
+         See <file:Documentation/mtrr.txt> for more information.
+-config HUGETLB_PAGE
+-      bool "Huge TLB Page Support"
+-      help
+-        This enables support for huge pages.  User space applications
+-        can make use of this support with the hugetlbfs file system
+-        To actually use it you need to pass an hugepages= argument
+-        to the kernel at boot time.
+-
+ config SMP
+       bool "Symmetric multi-processing support"
+       ---help---
+Index: linux-2.6.0-test5/arch/x86_64/kernel/pci-gart.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/kernel/pci-gart.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/kernel/pci-gart.c    2003-09-27 11:38:20.358433432 +0800
+@@ -76,7 +76,6 @@
+ #define EMERGENCY_PAGES 32 /* = 128KB */ 
+ #ifdef CONFIG_AGP
+-extern int agp_init(void);
+ #define AGPEXTERN extern
+ #else
+ #define AGPEXTERN
+Index: linux-2.6.0-test5/arch/x86_64/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/kernel/setup.c  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/kernel/setup.c       2003-09-27 11:38:20.365432368 +0800
+@@ -64,7 +64,7 @@
+ unsigned long mmu_cr4_features;
+ EXPORT_SYMBOL_GPL(mmu_cr4_features);
+-int acpi_disabled __initdata = 0;
++int acpi_disabled = 0;
+ /* For PCI or other memory-mapped resources */
+ unsigned long pci_mem_start = 0x10000000;
+@@ -317,7 +317,7 @@
+ {
+       unsigned long low_mem_size;
+-      ROOT_DEV = ORIG_ROOT_DEV;
++      ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+       drive_info = DRIVE_INFO;
+       screen_info = SCREEN_INFO;
+       edid_info = EDID_INFO;
+Index: linux-2.6.0-test5/arch/x86_64/kernel/time.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/kernel/time.c   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/kernel/time.c        2003-09-27 11:38:20.370431608 +0800
+@@ -370,6 +370,19 @@
+       return IRQ_HANDLED;
+ }
++/* RED-PEN: calculation is done in 32bits with multiply for performance
++   and could overflow, it may be better (but slower)to use an 64bit division. */
++unsigned long long sched_clock(void)
++{
++      unsigned long a;
++
++      if (__vxtime.mode == VXTIME_HPET)
++              return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> 32;
++
++      rdtscll(a);
++      return (a * vxtime.tsc_quot) >> 32;
++}
++
+ unsigned long get_cmos_time(void)
+ {
+       unsigned int timeout, year, mon, day, hour, min, sec;
+Index: linux-2.6.0-test5/arch/x86_64/mm/ioremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/x86_64/mm/ioremap.c    2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/arch/x86_64/mm/ioremap.c 2003-09-27 11:38:20.373431152 +0800
+@@ -159,7 +159,7 @@
+       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;
+       }
+Index: linux-2.6.0-test5/CREDITS
+===================================================================
+--- linux-2.6.0-test5.orig/CREDITS     2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/CREDITS  2003-09-27 11:38:20.394427960 +0800
+@@ -1394,7 +1394,8 @@
+ N: Marcel Holtmann
+ E: marcel@holtmann.org
+ W: http://www.holtmann.org
+-D: Author of the Linux Bluetooth Subsystem PC Card drivers
++D: Author and maintainer of the various Bluetooth HCI drivers
++D: Various other Bluetooth related patches, cleanups and fixes
+ S: Germany
+ N: Rob W. W. Hooft
+@@ -2795,7 +2796,7 @@
+ D: Dosemu
+ N: Duncan Sands
+-E: duncan.sands@wanadoo.fr
++E: duncan.sands@free.fr
+ W: http://topo.math.u-psud.fr/~sands
+ D: Alcatel SpeedTouch USB driver
+ S: 69 rue Dunois
+@@ -3460,11 +3461,11 @@
+ S: England
+ N: Chris Wright
+-E: chris@wirex.com
++E: chrisw@osdl.org
+ D: hacking on LSM framework and security modules.
+-S: c/o WireX
+-S: 920 SW 3rd, Ste. 100
+-S: Portland, OR 97204
++S: c/o OSDL
++S: 12725 SW Millikan Way, Suite 400
++S: Beaverton, OR 97005
+ S: USA
+ N: Frank Xia
+Index: linux-2.6.0-test5/crypto/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/crypto/proc.c       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/crypto/proc.c    2003-09-27 11:38:20.396427656 +0800
+@@ -57,6 +57,7 @@
+       
+       switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+       case CRYPTO_ALG_TYPE_CIPHER:
++              seq_printf(m, "type         : cipher\n");
+               seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+               seq_printf(m, "min keysize  : %u\n",
+                                       alg->cra_cipher.cia_min_keysize);
+@@ -65,10 +66,17 @@
+               break;
+               
+       case CRYPTO_ALG_TYPE_DIGEST:
++              seq_printf(m, "type         : digest\n");
+               seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+               seq_printf(m, "digestsize   : %u\n",
+                          alg->cra_digest.dia_digestsize);
+               break;
++      case CRYPTO_ALG_TYPE_COMPRESS:
++              seq_printf(m, "type         : compression\n");
++              break;
++      default:
++              seq_printf(m, "type         : unknown\n");
++              break;
+       }
+       seq_putc(m, '\n');
+Index: linux-2.6.0-test5/Documentation/00-INDEX
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/00-INDEX      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/00-INDEX   2003-09-27 11:38:20.399427200 +0800
+@@ -64,8 +64,10 @@
+       - plain ASCII listing of all the nodes in /dev/ with major minor #'s
+ digiboard.txt
+       - info on the Digiboard PC/X{i,e,eve} multiport boards.
++digidgap.txt
++      - info about the Digiboard EPCA PCI (DGAP) serial boards.
+ digiepca.txt
+-      - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
++      - info on Digi Intl. {ISA,EISA}Xx and Xem ISA series cards.
+ dnotify.txt
+       - info about directory notification in Linux.
+ driver-model.txt
+@@ -116,8 +118,6 @@
+       - listing of various WWW + books that document kernel internals.
+ kernel-parameters.txt
+       - summary listing of command line / boot prompt args for the kernel.
+-kmod.txt
+-      - info on the kernel module loader/unloader (kerneld replacement).
+ ldm.txt
+       - a brief description of LDM (Windows Dynamic Disks).
+ locks.txt
+@@ -144,8 +144,6 @@
+       - script to make /dev entries for SMART controllers (see cciss.txt)
+ mkdev.ida
+       - script to make /dev entries for Intelligent Disk Array Controllers.
+-modules.txt
+-      - short guide on how to make kernel parts into loadable modules
+ moxa-smartio
+       - info on installing/using Moxa multiport serial driver.
+ mtrr.txt
+Index: linux-2.6.0-test5/Documentation/as-iosched.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/as-iosched.txt        2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/as-iosched.txt     2003-09-27 11:38:20.400427048 +0800
+@@ -0,0 +1,53 @@
++Anticipatory IO scheduler
++-------------------------
++Nick Piggin <piggin@cyberone.com.au>    13 Sep 2003
++
++Attention! Database servers, especially those using "TCQ" disks should
++investigate performance with the 'deadline' IO scheduler. Any system with high
++disk performance requirements should do so, in fact.
++
++If you see unusual performance characteristics of your disk systems, or you
++see big performance regressions versus the deadline scheduler, please email
++me. Database users don't bother unless you're willing to test a lot of patches
++from me ;) its a known issue.
++
++
++Selecting IO schedulers
++-----------------------
++To choose IO schedulers at boot time, use the argument 'elevator=deadline'.
++'noop' and 'as' (the default) are also available. IO schedulers are assigned
++globally at boot time only presently.
++
++
++Tuning the anticipatory IO scheduler
++------------------------------------
++When using 'as', the anticipatory IO scheduler there are 5 parameters under
++/sys/block/*/iosched/. All are units of milliseconds.
++
++The parameters are:
++* read_expire
++    Controls how long until a request becomes "expired". It also controls the
++    interval between which expired requests are served, so set to 50, a request
++    might take anywhere < 100ms to be serviced _if_ it is the next on the
++    expired list. Obviously it won't make the disk go faster. The result
++    basically equates to the timeslice a single reader gets in the presence of
++    other IO. 100*((seek time / read_expire) + 1) is very roughly the %
++    streaming read efficiency your disk should get with multiple readers.
++    
++* read_batch_expire
++    Controls how much time a batch of reads is given before pending writes are
++    served. Higher value is more efficient. This might be set below read_expire
++    if writes are to be given higher priority than reads, but reads are to be
++    as efficient as possible when there are no writes. Generally though, it
++    should be some multiple of read_expire.
++   
++* write_expire, and
++* write_batch_expire are equivalent to the above, for writes.
++
++* antic_expire
++    Controls the maximum amount of time we can anticipate a good read before
++    giving up. Many other factors may cause anticipation to be stopped early,
++    or some processes will not be "anticipated" at all. Should be a bit higher
++    for big seek time devices though not a linear correspondence - most
++    processes have only a few ms thinktime.
++
+Index: linux-2.6.0-test5/Documentation/block/biodoc.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/block/biodoc.txt      2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/block/biodoc.txt   2003-09-27 11:38:20.415424768 +0800
+@@ -6,6 +6,8 @@
+       Suparna Bhattacharya <suparna@in.ibm.com>
+ Last Updated May 2, 2002
++September 2003: Updated I/O Scheduler portions
++      Nick Piggin <piggin@cyberone.com.au>
+ Introduction:
+@@ -220,42 +222,8 @@
+ It also makes it possible to completely hide the implementation details of
+ the i/o scheduler from block drivers.
+-New routines to be used instead of accessing the queue directly:
+-
+-elv_add_request: Should be called to queue a request
+-elv_next_request: Should be called to pull of the next request to be serviced
+-  of the queue. It takes care of several things like skipping active requests,
+-  invoking the command pre-builder etc.
+-
+-Some new plugins:
+-e->elevator_next_req_fn
+-      Plugin called to extract the next request to service from the
+-      queue
+-e->elevator_add_req_fn
+-      Plugin called to add a new request to the queue
+-e->elevator_init_fn
+-      Plugin called when initializing the queue
+-e->elevator_exit_fn
+-      Plugin called when destrying the queue
+-
+-Elevator Linus and Elevator noop are the existing combinations that can be
+-directly used, but a driver can provide relevant callbacks, in case
+-it needs to do something different.
+-
+-Elevator noop only attempts to merge requests, but doesn't reorder (sort)
+-them. Even merging requires a linear scan today (except for the last merged
+-hint case discussed later) though, which takes take up some CPU cycles.
+-
+-[Note: Merging usually helps in general, because there's usually non-trivial
+-command overhead associated with setting up and starting a command. Sorting,
+-on the other hand, may not be relevant for intelligent devices that reorder
+-requests anyway]
+-
+-Elevator Linus attempts merging as well as sorting of requests on the queue.
+-The sorting happens via an insert scan whenever a request comes in.
+-Often some sorting still makes sense as the depth which most hardware can
+-handle may be less than the queue lengths during i/o loads.
+-
++I/O scheduler wrappers are to be used instead of accessing the queue directly.
++See section 4. The I/O scheduler for details.
+ 1.2 Tuning Based on High level code capabilities
+@@ -317,32 +285,6 @@
+   requests. Some bits in the bi_rw flags field in the bio structure are
+   intended to be used for this priority information.
+-  Jens has an implementation of a simple deadline i/o scheduler that
+-  makes a best effort attempt to start requests within a given expiry
+-  time limit, along with trying to optimize disk seeks as in the current
+-  elevator. It does this by sorting a request on two lists, one by
+-  the deadline and one by the sector order. It employs a policy that
+-  follows sector ordering as long as a deadline is not violated, and
+-  tries to keep up with deadlines in so far as it can batch up to at
+-  least a certain minimum number of sector ordered requests to reduce
+-  arbitrary disk seeks. This implementation is constructed in a way
+-  that makes it possible to support advanced compound i/o schedulers
+-  as a combination of several low level schedulers with an overall
+-  class-independent scheduler layered above.
+-
+-The current elevator scheme provides a latency bound over how many future
+-requests can "pass" (get placed before) a given request, and this bound
+-is determined by the request type (read, write). However, it doesn't
+-prioritize a new request over existing requests in the queue based on its
+-latency requirement. A new request could of course get serviced before
+-earlier requests based on the position on disk which it accesses. This is
+-due to the sort/merge in the  basic elevator scan logic, but irrespective
+-of the request's own priority/latency value. Interestingly the elevator
+-sequence or the latency bound setting of the new request is unaffected by the
+-number of existing requests it has passed, i.e. doesn't depend on where
+-it is positioned in the queue, but only on the number of requests that pass
+-it in the future.
+-
+ 1.3 Direct Access to Low level Device/Driver Capabilities (Bypass mode)
+     (e.g Diagnostics, Systems Management)
+@@ -964,7 +906,74 @@
+ 4. The I/O scheduler
++I/O schedulers are now per queue. They should be runtime switchable and modular
++but aren't yet. Jens has most bits to do this, but the sysfs implementation is
++missing.
++
++A block layer call to the i/o scheduler follows the convention elv_xxx(). This
++calls elevator_xxx_fn in the elevator switch (drivers/block/elevator.c). Oh,
++xxx and xxx might not match exactly, but use your imagination. If an elevator
++doesn't implement a function, the switch does nothing or some minimal house
++keeping work.
++
++4.1. I/O scheduler API
++
++The functions an elevator may implement are: (* are mandatory)
++elevator_merge_fn             called to query requests for merge with a bio
++
++elevator_merge_req_fn         " " "  with another request
++
++elevator_merged_fn            called when a request in the scheduler has been
++                              involved in a merge. It is used in the deadline
++                              scheduler for example, to reposition the request
++                              if its sorting order has changed.
++
++*elevator_next_req_fn         returns the next scheduled request, or NULL
++                              if there are none (or none are ready).
++
++*elevator_add_req_fn          called to add a new request into the scheduler
++
++elevator_queue_empty_fn               returns true if the merge queue is empty.
++                              Drivers shouldn't use this, but rather check
++                              if elv_next_request is NULL (without losing the
++                              request if one exists!)
++
++elevator_remove_req_fn                This is called when a driver claims ownership of
++                              the target request - it now belongs to the
++                              driver. It must not be modified or merged.
++                              Drivers must not lose the request! A subsequent
++                              call of elevator_next_req_fn must  return the
++                              _next_ request.
++
++elevator_requeue_req_fn               called to add a request to the scheduler. This
++                              is used when the request has alrnadebeen
++                              returned by elv_next_request, but hasn't
++                              completed. If this is not implemented then
++                              elevator_add_req_fn is called instead.
++
++elevator_former_req_fn
++elevator_latter_req_fn                These return the request before or after the
++                              one specified in disk sort order. Used by the
++                              block layer to find merge possibilities.
++
++elevator_completed_req_fn     called when a request is completed. This might
++                              come about due to being merged with another or
++                              when the device completes the request.
++
++elevator_may_queue_fn         returns true if the scheduler wants to allow the
++                              current context to queue a new request even if
++                              it is over the queue limit. This must be used
++                              very carefully!!
++
++elevator_set_req_fn
++elevator_put_req_fn           Must be used to allocate and free any elevator
++                              specific storate for a request.
++
++elevator_init_fn
++elevator_exit_fn              Allocate and free any elevator specific storage
++                              for a queue.
++4.2 I/O scheduler implementation
+ The generic i/o scheduler algorithm attempts to sort/merge/batch requests for
+ optimal disk scan and request servicing performance (based on generic
+ principles and device capabilities), optimized for:
+@@ -974,49 +983,58 @@
+ Characteristics:
+-i. Linked list for O(n) insert/merge (linear scan) right now
+-
+-This is just the same as it was in 2.4.
+-
+-There is however an added level of abstraction in the operations for adding
+-and extracting a request to/from the queue, which makes it possible to
+-try out alternative queue structures without changes to the users of the queue.
+-Some things like head-active are thus now handled within elv_next_request
+-making it possible to mark more than one request to be left alone.
+-
+-Aside:
+-1. The use of a merge hash was explored to reduce merge times and to make
+-   elevator_noop close to noop by avoiding the scan for merge. However the
+-   complexity and locking issues introduced wasn't desirable especially as
+-   with multi-page bios the incidence of merges is expected to be lower.
+-2. The use of binomial/fibonacci heaps was explored to reduce the scan time;
+-   however the idea was given up due to the complexity and added weight of
+-   data structures, complications for handling barriers, as well as the
+-   advantage of O(1) extraction and deletion (performance critical path) with
+-   the existing list implementation vs heap based implementations.
+-
+-ii. Utilizes max_phys/hw_segments, and max_request_size  parameters, to merge
+-    within the limits that the device can handle (See 3.2.2)
+-
+-iii. Last merge hint
+-
+-In 2.5, information about the last merge is saved as a hint for the subsequent
+-request. This way, if sequential data is coming down the pipe, the hint can
+-be used to speed up merges without going through a scan.
++i. Binary tree
++AS and deadline i/o schedulers use red black binary trees for disk position
++sorting and searching, and a fifo linked list for time-based searching. This
++gives good scalability and good availablility of information. Requests are
++almost always dispatched in disk sort order, so a cache is kept of the next
++request in sort order to prevent binary tree lookups.
++
++This arrangement is not a generic block layer characteristic however, so
++elevators may implement queues as they please.
++
++ii. Last merge hint
++The last merge hint is part of the generic queue layer. I/O schedulers must do
++some management on it. For the most part, the most important thing is to make
++sure q->last_merge is cleared (set to NULL) when the request on it is no longer
++a candidate for merging (for example if it has been sent to the driver).
++
++The last merge performed is cached as a hint for the subsequent request. If
++sequential data is being submitted, the hint is used to perform merges without
++any scanning. This is not sufficient when there are multiple processes doing
++I/O though, so a "merge hash" is used by some schedulers.
++
++iii. Merge hash
++AS and deadline use a hash table indexed by the last sector of a request. This
++enables merging code to quickly look up "back merge" candidates, even when
++multiple I/O streams are being performed at once on one disk.
++
++"Front merges", a new request being merged at the front of an existing request,
++are far less common than "back merges" due to the nature of most I/O patterns.
++Front merges are handled by the binary trees in AS and deadline schedulers.
+ iv. Handling barrier cases
++A request with flags REQ_HARDBARRIER or REQ_SOFTBARRIER must not be ordered
++around. That is, they must be processed after all older requests, and before
++any newer ones. This includes merges!
++
++In AS and deadline schedulers, barriers have the effect of flushing the reorder
++queue. The performance cost of this will vary from nothing to a lot depending
++on i/o patterns and device characteristics. Obviously they won't improve
++performance, so their use should be kept to a minimum.
++
++v. Handling insertion position directives
++A request may be inserted with a position directive. The directives are one of
++ELEVATOR_INSERT_BACK, ELEVATOR_INSERT_FRONT, ELEVATOR_INSERT_SORT.
++
++ELEVATOR_INSERT_SORT is a general directive for non-barrier requests.
++ELEVATOR_INSERT_BACK is used to insert a barrier to the back of the queue.
++ELEVATOR_INSERT_FRONT is used to insert a barrier to the front of the queue, and
++overrides the ordering requested by any previous barriers. In practice this is
++harmless and required, because it is used for SCSI requeueing. This does not
++require flushing the reorder queue, so does not impose a performance penalty.
+-As mentioned earlier, barrier support is new to 2.5, and the i/o scheduler
+-has been modified accordingly.
+-
+-When a barrier comes in, then since insert happens in the form of a
+-linear scan, starting from the end, it just needs to be ensured that this
+-and future scans stops barrier point. This is achieved by  skipping the
+-entire merge/scan logic for a barrier request, so it gets placed at the
+-end of the queue, and specifying a zero latency for the request containing
+-the bio so that no future requests can pass it.
+-
+-v. Plugging the queue to batch requests in anticipation of opportunities for
++vi. Plugging the queue to batch requests in anticipation of opportunities for
+   merge/sort optimizations
+ This is just the same as in 2.4 so far, though per-device unplugging
+@@ -1051,6 +1069,12 @@
+   blk_kick_queue() to unplug a specific queue (right away ?)
+   or optionally, all queues, is in the plan.
++4.3 I/O contexts
++I/O contexts provide a dynamically allocated per process data area. They may
++be used in I/O schedulers, and in the block layer (could be used for IO statis,
++priorities for example). See *io_context in drivers/block/ll_rw_blk.c, and
++as-iosched.c for an example of usage in an i/o scheduler.
++
+ 5. Scalability related changes
+Index: linux-2.6.0-test5/Documentation/cachetlb.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/cachetlb.txt  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/cachetlb.txt       2003-09-27 11:38:20.420424008 +0800
+@@ -165,15 +165,7 @@
+ 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,7 +175,7 @@
+       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
+@@ -200,7 +192,7 @@
+       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 @@
+       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'.
++
++      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 @@
+                       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 @@
+       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
+Index: linux-2.6.0-test5/Documentation/Changes
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/Changes       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/Changes    2003-09-27 11:38:20.424423400 +0800
+@@ -52,7 +52,7 @@
+ o  Gnu make               3.78                    # make --version
+ o  binutils               2.12                    # ld -v
+ o  util-linux             2.10o                   # fdformat --version
+-o  module-init-tools      0.9.9                   # depmod -V
++o  module-init-tools      0.9.10                  # depmod -V
+ o  e2fsprogs              1.29                    # tune2fs
+ o  jfsutils               1.1.3                   # fsck.jfs -V
+ o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
+@@ -62,7 +62,7 @@
+ o  PPP                    2.4.0                   # pppd --version
+ o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
+ o  nfs-utils              1.0.5                   # showmount --version
+-o  procps                 2.0.9                   # ps --version
++o  procps                 3.1.13                  # ps --version
+ o  oprofile               0.5.3                   # oprofiled --version
+ Kernel compilation
+Index: linux-2.6.0-test5/Documentation/devices.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/devices.txt   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/devices.txt        2003-09-27 11:38:20.448419752 +0800
+@@ -581,10 +581,9 @@
+               Partitions are handled the same way as for the first
+               interface (see major number 3).
+- 23 char      Digiboard serial card - alternate devices
+-                0 = /dev/cud0         Callout device for ttyD0
+-                1 = /dev/cud1         Callout device for ttyD1
+-                    ...
++ 23 char      Digiboard serial card - EPCA PCI (DGAP) driver.
++                0-255                 DGAP management devices.
++
+     block     Mitsumi proprietary CD-ROM
+                 0 = /dev/mcd          Mitsumi CD-ROM
+Index: linux-2.6.0-test5/Documentation/digiboard.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/digiboard.txt 2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/digiboard.txt      2003-09-27 11:38:20.452419144 +0800
+@@ -17,6 +17,9 @@
+ Bernhard Kaindl (bkaindl@netway.at)  6. April 1997.
++As of the 2.6 Linux kernel, Digi International no longer supports
++this version of the driver.
++
+ Configuring the Driver
+ ----------------------
+Index: linux-2.6.0-test5/Documentation/digidgap.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/digidgap.txt  2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/digidgap.txt       2003-09-27 11:38:20.452419144 +0800
+@@ -0,0 +1,18 @@
++=============================================================================
++
++      Digi Acceleport EPCA PCI (DGAP) Driver Installation Guide
++                      for Linux Kernel 2.6
++              Copyright (C) 2003, Digi International
++============================================================================
++
++      This driver supports the Digi Acceleport Xr, Xr920, Xr422, XEM, C/X
++              and EPC/X PCI cards.
++
++      This driver requires the DGAP Tools package to be installed.
++
++      The Tools package can be found at http://www.digi.com
++
++      Once the Tools package is installed, run /usr/sbin/dgap_config to
++              set up the driver.
++
++============================================================================
+Index: linux-2.6.0-test5/Documentation/digiepca.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/digiepca.txt  2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/digiepca.txt       2003-09-27 11:38:20.454418840 +0800
+@@ -2,19 +2,23 @@
+ ----------------------------
+ The Digi Intl. epca driver for Linux supports the following boards:
+-Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve 
+-Digi EISA/Xem, PCI/Xem, PCI/Xr 
++Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve ISA boards.
++Digi EISA/Xem.
+ Limitations:
+ ------------
+-Currently the driver only autoprobes for supported PCI boards. 
++This driver no longer supports PCI Digi products.
++Use the new Digi DGAP driver instead.
++For more information read Documentation/digidgap.txt
++
++As of the 2.6 Linux kernel, Digi International no longer supports
++this version of the driver.
+ The Linux MAKEDEV command does not support generating the Digiboard
+ Devices.  Users executing digiConfig to setup EISA and PC series cards
+ will have their device nodes automatically constructed (cud?? for ~CLOCAL,
+ and ttyD?? for CLOCAL).  Users wishing to boot their board from the LILO
+-prompt, or those users booting PCI cards may use buildDIGI to construct 
+-the necessary nodes. 
++prompt may use buildDIGI to construct the necessary nodes.
+ Notes:
+ ------
+@@ -26,11 +30,6 @@
+ Device names start at 0 and continue up.  Beware of this as previous Digi 
+ drivers started device names with 1.
+-PCI boards are auto-detected and configured by the driver.  PCI boards will
+-be allocated device numbers (internally) beginning with the lowest PCI slot
+-first.  In other words a PCI card in slot 3 will always have higher device
+-nodes than a PCI card in slot 1. 
+-
+ LILO config examples:
+ ---------------------
+ Using LILO's APPEND command, a string of comma separated identifiers or 
+@@ -45,10 +44,8 @@
+    I/O Port where card is configured (in HEX if using string identifiers),
+    Base of memory window (in HEX if using string identifiers), 
+-NOTE : PCI boards are auto-detected and configured.  Do not attempt to 
+-configure PCI boards with the LILO append command.  If you wish to override
+-previous configuration data (As set by digiConfig), but you do not wish to
+-configure any specific card (Example if there are PCI cards in the system) 
++NOTE : If you wish to override previous configuration data
++(As set by digiConfig), but you do not wish to configure any specific card
+ the following override command will accomplish this:
+ -> append="digi=2"
+@@ -59,7 +56,7 @@
+ Supporting Tools:
+ -----------------
+-Supporting tools include digiDload, digiConfig, buildPCI, and ditty.  See
++Supporting tools include digiDload, digiConfig, and ditty.  See
+ /usr/src/linux/Documentation/README.epca.dir/user.doc for more details.  Note,
+ this driver REQUIRES that digiDload be executed prior to it being used. 
+ Failure to do this will result in an ENODEV error.
+Index: linux-2.6.0-test5/Documentation/DocBook/gadget.tmpl
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/DocBook/gadget.tmpl   2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/DocBook/gadget.tmpl        2003-09-27 11:38:20.459418080 +0800
+@@ -468,6 +468,15 @@
+ information.
+ </para> 
++<para>For users of Intel's PXA 2xx series processors,
++a <filename>pxa2xx_udc</filename> driver is available.
++</para>
++
++<para>At this writing, there are people at work on drivers in
++this framework for several other USB device controllers,
++with plans to make many of them be widely available.
++</para>
++
+ <!-- !Edrivers/usb/gadget/net2280.c -->
+ <para>A partial USB simulator,
+@@ -500,7 +509,7 @@
+ <para>There's an <emphasis>ethernet</emphasis> gadget
+ driver, which implements one of the most useful
+-<emphasis>Communications Device Class</emphasis> models.  
++<emphasis>Communications Device Class</emphasis> (CDC) models.  
+ One of the standards for cable modem interoperability even
+ specifies the use of this ethernet model as one of two
+ mandatory options.
+@@ -509,6 +518,11 @@
+ It provides access to a network where the gadget's CPU is one host,
+ which could easily be bridging, routing, or firewalling
+ access to other networks.
++Since some hardware can't fully implement the CDC Ethernet
++requirements, this driver also implements a "good parts only"
++subset of CDC Ethernet.
++(That subset doesn't advertise itself as CDC Ethernet,
++to avoid creating problems.)
+ </para>
+ <para>There is also support for user mode gadget drivers,
+@@ -522,6 +536,17 @@
+ won't require new kernel mode software.
+ </para>
++<para>There's a USB Mass Storage class driver, which provides
++a different solution for interoperability with systems such
++as MS-Windows and MacOS.
++That <emphasis>File-backed Storage</emphasis> driver uses a
++file or block device as backing store for a drive,
++like the <filename>loop</filename> driver.
++The USB host uses the BBB, CB, or CBI versions of the mass
++storage class specification, using transparent SCSI commands
++to access the data from the backing store.
++</para>
++
+ <para>Support for other kinds of gadget is expected to
+ be developed and contributed
+ over time, as this driver framework evolves.
+Index: linux-2.6.0-test5/Documentation/DocBook/writing_usb_driver.tmpl
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/DocBook/writing_usb_driver.tmpl       2003-09-26 14:32:01.000000000 +0800
++++ linux-2.6.0-test5/Documentation/DocBook/writing_usb_driver.tmpl    2003-09-27 11:38:20.465417168 +0800
+@@ -209,7 +209,7 @@
+      The driver now needs to verify that this device is actually one that it
+      can accept. If so, it returns 0.
+      If not, or if any error occurs during initialization, an errorcode
+-     (such as <literal>-ENOMEM<literal> or <literal>-ENODEV<literal>)
++     (such as <literal>-ENOMEM</literal> or <literal>-ENODEV</literal>)
+      is returned from the probe function.
+   </para>
+   <para>
+@@ -327,6 +327,7 @@
+      talk to the device, the release function in the driver is called. In this
+      function we decrement our private usage count and wait for possible
+      pending writes:
++  </para>
+   <programlisting>
+ /* decrement our usage count for the device */
+ --skel->open_count;
+Index: linux-2.6.0-test5/Documentation/fb/neofb.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/fb/neofb.txt  2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/fb/neofb.txt       2003-09-27 11:38:20.465417168 +0800
+@@ -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
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/andthen
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/andthen     2003-09-27 11:38:18.445724208 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/andthen  2003-09-27 11:38:20.466417016 +0800
+@@ -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
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/debug-nmi.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/debug-nmi.txt       2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/debug-nmi.txt    2003-09-27 11:38:20.466417016 +0800
+@@ -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)
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdb-globals.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdb-globals.txt     2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdb-globals.txt  2003-09-27 11:38:20.467416864 +0800
+@@ -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 )
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdbinit     2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit  2003-09-27 11:38:20.467416864 +0800
+@@ -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
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit.hw
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdbinit.hw  2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit.hw       2003-09-27 11:38:20.468416712 +0800
+@@ -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
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit-modules
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/gdbinit-modules     2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/gdbinit-modules  2003-09-27 11:38:20.468416712 +0800
+@@ -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
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/kgdbeth.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/kgdbeth.txt 2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/kgdbeth.txt      2003-09-27 11:38:20.469416560 +0800
+@@ -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>.
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/kgdb.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/kgdb.txt    2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/kgdb.txt 2003-09-27 11:38:20.471416256 +0800
+@@ -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.
+Index: linux-2.6.0-test5/Documentation/i386/kgdb/loadmodule.sh
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/i386/kgdb/loadmodule.sh       2003-09-27 11:38:18.446724056 +0800
++++ linux-2.6.0-test5/Documentation/i386/kgdb/loadmodule.sh    2003-09-27 11:38:20.472416104 +0800
+@@ -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
+Index: linux-2.6.0-test5/Documentation/kernel-parameters.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/kernel-parameters.txt 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/kernel-parameters.txt      2003-09-27 11:38:20.480414888 +0800
+@@ -393,7 +393,7 @@
+                       See Documentation/ide.txt.
+       idle=           [HW]
+-                      Format: poll
++                      Format: idle=poll or idle=halt
+  
+       in2000=         [HW,SCSI]
+                       See header of drivers/scsi/in2000.c.
+@@ -786,8 +786,14 @@
+                       before loading.
+                       See Documentation/ramdisk.txt.
++      psmouse_imps2   [HW,MOUSE] Probe only for Intellimouse PS2 mouse protocol extensions
++
+       psmouse_noext   [HW,MOUSE] Disable probing for PS2 mouse protocol extensions
++      psmouse_resetafter=
++                      [HW,MOUSE] Try to reset Synaptics Touchpad after so many
++                      bad packets (0 = never).
++
+       pss=            [HW,OSS] Personal Sound System (ECHO ESC614)
+                       Format: <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
+Index: linux-2.6.0-test5/Documentation/magic-number.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/magic-number.txt      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/magic-number.txt   2003-09-27 11:38:20.484414280 +0800
+@@ -134,6 +134,9 @@
+ 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
++DGAP_BOARD_MAGIC      0x5c6df104  board_t           drivers/char/digi/dgap/dgap_driver.h
++DGAP_CHANNEL_MAGIC    0x6c6df104  channel_t         drivers/char/digi/dgap/dgap_driver.h
++DGAP_UNIT_MAGIC       0x7c6df104  un_t              drivers/char/digi/dgap/dgap_driver.h
+ KV_MAGIC              0x5f4b565f  kernel_vars_s     include/asm-mips64/sn/klkernvars.h
+ I810_STATE_MAGIC      0x63657373  i810_state        sound/oss/i810_audio.c
+ TRIDENT_STATE_MAGIC   0x63657373  trient_state      sound/oss/trident.c
+Index: linux-2.6.0-test5/Documentation/networking/bonding.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/networking/bonding.txt        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/networking/bonding.txt     2003-09-27 11:38:20.494412760 +0800
+@@ -527,9 +527,9 @@
+ 1) Bonding information files
+ ----------------------------
+-The bonding driver information files reside in the /proc/net/bond* directories.
++The bonding driver information files reside in the /proc/net/bonding directory.
+-Sample contents of /proc/net/bond0/info after the driver is loaded with 
++Sample contents of /proc/net/bonding/bond0 after the driver is loaded with 
+ parameters of mode=0 and miimon=1000 is shown below.
+  
+         Bonding Mode: load balancing (round-robin)
+Index: linux-2.6.0-test5/Documentation/networking/ifenslave.c
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/networking/ifenslave.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/networking/ifenslave.c     2003-09-27 11:38:20.504411240 +0800
+@@ -140,6 +140,7 @@
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/ioctl.h>
++#include <linux/if.h>
+ #include <net/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/if_bonding.h>
+Index: linux-2.6.0-test5/Documentation/video4linux/Zoran
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/video4linux/Zoran     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/Documentation/video4linux/Zoran  2003-09-27 11:38:20.510410328 +0800
+@@ -28,7 +28,7 @@
+ * Philips saa7111 TV decoder
+ * Philips saa7185 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-                videocodec, saa7111, saa7185, zr36060, zoran
++                videocodec, saa7111, saa7185, zr36060, zr36067
+ Inputs/outputs: Composite and S-video
+ Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+ Card number: 7
+@@ -39,7 +39,7 @@
+ * Brooktree bt819 TV decoder
+ * Brooktree bt856 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-                videocodec, bt819, bt856, zr36060, zoran
++                videocodec, bt819, bt856, zr36060, zr36067
+ Inputs/outputs: Composite and S-video
+ Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+ Card number: 5
+@@ -50,7 +50,7 @@
+ * Philips saa7114 TV decoder
+ * Analog Devices adv7170 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-                videocodec, saa7114, adv7170, zr36060, zoran
++                videocodec, saa7114, adv7170, zr36060, zr36067
+ Inputs/outputs: Composite and S-video
+ Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+ Card number: 6
+@@ -61,7 +61,7 @@
+ * Philips saa7110a TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-                videocodec, saa7110, adv7175, zr36060, zoran
++                videocodec, saa7110, adv7175, zr36060, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 1
+@@ -72,7 +72,7 @@
+ * Philips saa7110a TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-              videocodec, sa7110, adv7175, zr36060, zoran
++              videocodec, sa7110, adv7175, zr36060, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 2
+@@ -84,7 +84,7 @@
+ * Micronas vpx3220a TV decoder
+ * mse3000 TV encoder or Analog Devices adv7176 TV encoder *
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-                videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zoran
++                videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 0
+@@ -96,7 +96,7 @@
+ * Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-                videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zoran
++                videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 3
+@@ -108,7 +108,7 @@
+ * Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
+ * Analog Devices adv7176 TV encoder
+ Drivers to use: videodev, i2c-core, i2c-algo-bit,
+-              videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36015, zoran
++              videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36015, zr36067
+ Inputs/outputs: Composite, S-video and Internal
+ Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+ Card number: 4
+@@ -229,16 +229,16 @@
+ 2. How do I get this damn thing to work
+-Load zoran.o. If it can't autodetect your card, use the card=X insmod
++Load zr36067.o. If it can't autodetect your card, use the card=X insmod
+ option with X being the card number as given in the previous section.
+ To have more than one card, use card=X1[,X2[,X3,[X4[..]]]]
+ To automate this, add the following to your /etc/modules.conf:
+-options zoran card=X1[,X2[,X3[,X4[..]]]]
+-alias char-major-81-0 zoran
++options zr36067 card=X1[,X2[,X3[,X4[..]]]]
++alias char-major-81-0 zr36067
+-One thing to keep in mind is that this doesn't load zoran.o itself yet. It
++One thing to keep in mind is that this doesn't load zr36067.o itself yet. It
+ just automates loading. If you start using xawtv, the device won't load on
+ some systems, since you're trying to load modules as a user, which is not
+ allowed ("permission denied"). A quick workaround is to add 'Load "v4l"' to
+@@ -500,7 +500,7 @@
+ 7. It hangs/crashes/fails/whatevers! Help!
+ Make sure that the card has its own interrupts (see /proc/interrupts), check
+-the output of dmesg at high verbosity (load zoran.o/zr36067.o with debug=2,
++the output of dmesg at high verbosity (load zr36067.o with debug=2,
+ load all other modules with debug=1). Check that your mainboard is favorable
+ (see question 2) and if not, test the card in another computer. Also see the
+ notes given in question 3 and try lowering quality/buffersize/capturesize
+Index: linux-2.6.0-test5/drivers/acpi/ec.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/ec.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/ec.c        2003-09-27 11:38:20.516409416 +0800
+@@ -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 @@
+        * 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;
+ }
+Index: linux-2.6.0-test5/drivers/acpi/events/evregion.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/events/evregion.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/events/evregion.c   2003-09-27 11:38:20.522408504 +0800
+@@ -382,7 +382,7 @@
+       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 @@
+       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 @@
+                       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 */
+Index: linux-2.6.0-test5/drivers/acpi/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/Kconfig        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/Kconfig     2003-09-27 11:38:20.526407896 +0800
+@@ -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 
+@@ -60,14 +40,47 @@
+         available at:
+         <http://www.acpi.info>
++config ACPI_HT_ONLY
++      bool "Restrict ACPI to minimum boot code to enable HT"
++      depends on X86
++      depends on ACPI
++      depends on SMP
++      default n
++      ---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_ONLY includes just the minimal ACPI boot-time code
++        necessary to enumerate logical processors and enable HT.
++
++        CONFIG_ACPI includes this, 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_ONLY were selected.
++
++        Note that "acpi=off" can be used to disable all ACPI code in the kernel.
++
++
+ config ACPI_BOOT
+       bool
+-      depends on ACPI || ACPI_HT
++      depends on ACPI
++      default y
++
++config ACPI_INTERPRETER
++      bool
++      depends on ACPI
++      depends on !IA64_SGI_SN
++      depends on !ACPI_HT_ONLY
+       default y
+ config ACPI_SLEEP
+       bool "Sleep States (EXPERIMENTAL)"
+       depends on X86 && ACPI
++      depends on ACPI_INTERPRETER
+       depends on EXPERIMENTAL && PM
+       select SOFTWARE_SUSPEND
+       default y
+@@ -94,7 +107,8 @@
+ 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
+@@ -103,7 +117,8 @@
+ 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
+@@ -112,7 +127,7 @@
+ config ACPI_BUTTON
+       tristate "Button"
+-      depends on ACPI
++      depends on ACPI_INTERPRETER
+       depends on !IA64_SGI_SN
+       default m
+       help
+@@ -124,7 +139,7 @@
+ config ACPI_FAN
+       tristate "Fan"
+-      depends on ACPI
++      depends on ACPI_INTERPRETER
+       depends on !IA64_SGI_SN
+       default m
+       help
+@@ -133,7 +148,7 @@
+ config ACPI_PROCESSOR
+       tristate "Processor"
+-      depends on ACPI
++      depends on ACPI_INTERPRETER
+       depends on !IA64_SGI_SN
+       default m
+       help
+@@ -153,14 +168,15 @@
+ 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
+@@ -186,7 +202,8 @@
+           
+ 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
+@@ -213,7 +230,7 @@
+ config ACPI_DEBUG
+       bool "Debug Statements"
+-      depends on ACPI
++      depends on ACPI_INTERPRETER
+       depends on !IA64_SGI_SN
+       default n
+       help
+@@ -223,19 +240,14 @@
+ 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
+@@ -244,19 +256,19 @@
+ 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
+@@ -265,7 +277,7 @@
+ config ACPI_EFI
+       bool
+-      depends on ACPI
++      depends on ACPI_INTERPRETER
+       depends on IA64
+       default y
+Index: linux-2.6.0-test5/drivers/acpi/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/Makefile       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/Makefile    2003-09-27 11:38:20.527407744 +0800
+@@ -18,7 +18,7 @@
+ # 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)
+Index: linux-2.6.0-test5/drivers/acpi/pci_link.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/pci_link.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/pci_link.c  2003-09-27 11:38:20.533406832 +0800
+@@ -220,7 +220,6 @@
+       return AE_CTRL_TERMINATE;
+ }
+-
+ static int
+ acpi_pci_link_get_current (
+       struct acpi_pci_link    *link)
+@@ -279,6 +278,28 @@
+       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 @@
+       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 @@
+               }
+       }
++      /* 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 @@
+               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 @@
+       }
+       /* 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);
+       }
+@@ -458,14 +502,14 @@
+               irq = link->irq.possible[0];
+       }
+-              /* 
+-               * 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];
+-              }
++      /* 
++       * 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 @@
+               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 */
+Index: linux-2.6.0-test5/drivers/acpi/sleep/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/sleep/main.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/sleep/main.c        2003-09-27 11:38:20.535406528 +0800
+@@ -41,7 +41,6 @@
+ static int acpi_pm_prepare(u32 state)
+ {
+-      int error = 0;
+       u32 acpi_state = acpi_suspend_states[state];
+       if (!sleep_states[acpi_state])
+@@ -56,21 +55,9 @@
+               acpi_set_firmware_waking_vector(
+                       (acpi_physical_address) acpi_wakeup_address);
+       }
+-
+       ACPI_FLUSH_CPU_CACHE();
+-
+-      /* Do arch specific saving of state. */
+-      if (state > PM_SUSPEND_STANDBY) {
+-              if ((error = acpi_save_state_mem()))
+-                      goto Err;
+-      }
+-
+       acpi_enter_sleep_state_prep(acpi_state);
+-
+       return 0;
+- Err:
+-      acpi_set_firmware_waking_vector(0);
+-      return error;
+ }
+@@ -90,6 +77,15 @@
+       u32 acpi_state = acpi_suspend_states[state];
+       ACPI_FLUSH_CPU_CACHE();
++
++      /* Do arch specific saving of state. */
++      if (state > PM_SUSPEND_STANDBY) {
++              int error = acpi_save_state_mem();
++              if (error)
++                      return error;
++      }
++
++
+       local_irq_save(flags);
+       switch (state)
+       {
+@@ -114,6 +110,15 @@
+       local_irq_restore(flags);
+       printk(KERN_DEBUG "Back to C!\n");
++      /* restore processor state
++       * We should only be here if we're coming back from STR or STD.
++       * And, in the case of the latter, the memory image should have already
++       * been loaded from disk.
++       */
++      if (state > PM_SUSPEND_STANDBY)
++              acpi_restore_state_mem();
++
++
+       return ACPI_SUCCESS(status) ? 0 : -EFAULT;
+ }
+@@ -130,14 +135,6 @@
+ {
+       acpi_leave_sleep_state(state);
+-      /* restore processor state
+-       * We should only be here if we're coming back from STR or STD.
+-       * And, in the case of the latter, the memory image should have already
+-       * been loaded from disk.
+-       */
+-      if (state > ACPI_STATE_S1)
+-              acpi_restore_state_mem();
+-
+       /* reset firmware waking vector */
+       acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+@@ -149,6 +146,20 @@
+ }
++int acpi_suspend(u32 acpi_state)
++{
++      u32 states[] = {
++              [1]     = PM_SUSPEND_STANDBY,
++              [3]     = PM_SUSPEND_MEM,
++              [4]     = PM_SUSPEND_DISK,
++      };
++
++      if (acpi_state <= 4 && states[acpi_state])
++              return pm_suspend(states[acpi_state]);
++      return -EINVAL;
++}
++
++
+ static struct pm_ops acpi_pm_ops = {
+       .prepare        = acpi_pm_prepare,
+       .enter          = acpi_pm_enter,
+Index: linux-2.6.0-test5/drivers/acpi/sleep/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/sleep/proc.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/sleep/proc.c        2003-09-27 11:38:20.538406072 +0800
+@@ -13,12 +13,71 @@
+ #include "sleep.h"
++#define ACPI_SYSTEM_FILE_SLEEP                "sleep"
+ #define ACPI_SYSTEM_FILE_ALARM                "alarm"
+ #define _COMPONENT            ACPI_SYSTEM_COMPONENT
+ ACPI_MODULE_NAME              ("sleep")
++static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
++{
++      int                     i;
++
++      ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
++
++      for (i = 0; i <= ACPI_STATE_S5; i++) {
++              if (sleep_states[i]) {
++                      seq_printf(seq,"S%d ", i);
++                      if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
++                              seq_printf(seq, "S4bios ");
++              }
++      }
++
++      seq_puts(seq, "\n");
++
++      return 0;
++}
++
++static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
++{
++      return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
++}
++
++static int
++acpi_system_write_sleep (
++      struct file             *file,
++      const char              *buffer,
++      size_t                  count,
++      loff_t                  *ppos)
++{
++      char    str[12];
++      u32     state = 0;
++      int     error = 0;
++
++      if (count > sizeof(str) - 1)
++              goto Done;
++      memset(str,0,sizeof(str));
++      if (copy_from_user(str, buffer, count))
++              return -EFAULT;
++
++      /* Check for S4 bios request */
++      if (!strcmp(str,"4b")) {
++              error = acpi_suspend(4);
++              goto Done;
++      }
++      state = simple_strtoul(str, NULL, 0);
++#ifdef CONFIG_SOFTWARE_SUSPEND
++      if (state == 4) {
++              software_suspend();
++              goto Done;
++      }
++#endif
++      error = acpi_suspend(state);
++ Done:
++      return error ? error : count;
++}
++
+ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
+ {
+       u32                     sec, min, hr;
+@@ -294,6 +353,14 @@
+ }
++static struct file_operations acpi_system_sleep_fops = {
++      .open           = acpi_system_sleep_open_fs,
++      .read           = seq_read,
++      .write          = acpi_system_write_sleep,
++      .llseek         = seq_lseek,
++      .release        = single_release,
++};
++
+ static struct file_operations acpi_system_alarm_fops = {
+       .open           = acpi_system_alarm_open_fs,
+       .read           = seq_read,
+@@ -307,6 +374,12 @@
+ {
+       struct proc_dir_entry   *entry = NULL;
++      /* 'sleep' [R/W]*/
++      entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
++                                S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
++      if (entry)
++              entry->proc_fops = &acpi_system_sleep_fops;
++
+       /* 'alarm' [R/W] */
+       entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
+               S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+Index: linux-2.6.0-test5/drivers/acpi/sleep/sleep.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/sleep/sleep.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/sleep/sleep.h       2003-09-27 11:38:20.539405920 +0800
+@@ -1,5 +1,4 @@
+ extern u8 sleep_states[];
+-
+-extern acpi_status acpi_suspend (u32 state);
++extern int acpi_suspend (u32 state);
+Index: linux-2.6.0-test5/drivers/acpi/utilities/utdelete.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/acpi/utilities/utdelete.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/acpi/utilities/utdelete.c        2003-09-27 11:38:20.544405160 +0800
+@@ -417,6 +417,8 @@
+       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 @@
+               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 @@
+                                */
+                               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 @@
+                       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 @@
+                       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 @@
+                       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 @@
+                       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;
+Index: linux-2.6.0-test5/drivers/atm/eni.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/eni.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/eni.c        2003-09-27 11:38:20.561402576 +0800
+@@ -2272,8 +2272,6 @@
+       DPRINTK("eni_init_one\n");
+-      MOD_INC_USE_COUNT; /* @@@ we don't support unloading yet */
+-
+       if (pci_enable_device(pci_dev)) {
+               error = -EIO;
+               goto out0;
+@@ -2307,7 +2305,6 @@
+ out1:
+       kfree(eni_dev);
+ out0:
+-      MOD_DEC_USE_COUNT; /* @@@ we don't support unloading yet */
+       return error;
+ }
+@@ -2351,16 +2348,7 @@
+ }
+-static void __exit eni_cleanup(void)
+-{
+-      /*
+-       * Well, there's no way to get rid of the driver yet, so we don't
+-       * have to clean up, right ? :-)
+-       */
+-}
+-
+-
+ module_init(eni_init);
+-module_exit(eni_cleanup);
++/* @@@ since exit routine not defined, this module can not be unloaded */
+ MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/atm/firestream.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/firestream.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/firestream.c 2003-09-27 11:38:20.576400296 +0800
+@@ -250,7 +250,7 @@
+ };
+-struct reginit_item PHY_NTC_INIT[] __initdata = {
++struct reginit_item PHY_NTC_INIT[] __devinitdata = {
+       { PHY_CLEARALL, 0x40 }, 
+       { 0x12,  0x0001 },
+       { 0x13,  0x7605 },
+@@ -1282,9 +1282,7 @@
+       .open =         fs_open,
+       .close =        fs_close,
+       .send =         fs_send,
+-#if 0
+       .owner =        THIS_MODULE,
+-#endif
+       /* ioctl:          fs_ioctl, */
+       /* getsockopt:     fs_getsockopt, */
+       /* setsockopt:     fs_setsockopt, */
+@@ -1296,7 +1294,7 @@
+ };
+-static void __init undocumented_pci_fix (struct pci_dev *pdev)
++static void __devinit undocumented_pci_fix (struct pci_dev *pdev)
+ {
+       int tint;
+@@ -1320,13 +1318,13 @@
+  *                              PHY routines                              *
+  **************************************************************************/
+-static void __init write_phy (struct fs_dev *dev, int regnum, int val)
++static void __devinit write_phy (struct fs_dev *dev, int regnum, int val)
+ {
+       submit_command (dev,  &dev->hp_txq, QE_CMD_PRP_WR | QE_CMD_IMM_INQ,
+                       regnum, val, 0);
+ }
+-static int __init init_phy (struct fs_dev *dev, struct reginit_item *reginit)
++static int __devinit init_phy (struct fs_dev *dev, struct reginit_item *reginit)
+ {
+       int i;
+@@ -1382,7 +1380,7 @@
+       }
+ }
+-static void __init *aligned_kmalloc (int size, int flags, int alignment)
++static void __devinit *aligned_kmalloc (int size, int flags, int alignment)
+ {
+       void  *t;
+@@ -1399,7 +1397,7 @@
+       return NULL;
+ }
+-static int __init init_q (struct fs_dev *dev, 
++static int __devinit init_q (struct fs_dev *dev, 
+                         struct queue *txq, int queue, int nentries, int is_rq)
+ {
+       int sz = nentries * sizeof (struct FS_QENTRY);
+@@ -1435,7 +1433,7 @@
+ }
+-static int __init init_fp (struct fs_dev *dev, 
++static int __devinit init_fp (struct fs_dev *dev, 
+                          struct freepool *fp, int queue, int bufsize, int nr_buffers)
+ {
+       func_enter ();
+@@ -1655,7 +1653,7 @@
+ }
+ #endif
+-static int __init fs_init (struct fs_dev *dev)
++static int __devinit fs_init (struct fs_dev *dev)
+ {
+       struct pci_dev  *pci_dev;
+       int isr, to;
+@@ -1890,7 +1888,7 @@
+       return 0;
+ }
+-static int __init firestream_init_one (struct pci_dev *pci_dev,
++static int __devinit firestream_init_one (struct pci_dev *pci_dev,
+                                      const struct pci_device_id *ent) 
+ {
+       struct atm_dev *atm_dev;
+Index: linux-2.6.0-test5/drivers/atm/idt77252.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/idt77252.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/idt77252.c   2003-09-27 11:38:20.600396648 +0800
+@@ -147,7 +147,8 @@
+       .phy_put        = idt77252_phy_put,
+       .phy_get        = idt77252_phy_get,
+       .change_qos     = idt77252_change_qos,
+-      .proc_read      = idt77252_proc_read
++      .proc_read      = idt77252_proc_read,
++      .owner          = THIS_MODULE
+ };
+ static struct idt77252_dev *idt77252_chain = NULL;
+@@ -2544,7 +2545,6 @@
+       }
+       set_bit(ATM_VF_READY, &vcc->flags);
+-      MOD_INC_USE_COUNT;
+       up(&card->mutex);
+       return 0;
+@@ -2631,7 +2631,6 @@
+               free_scq(card, vc->scq);
+       }
+-      MOD_DEC_USE_COUNT;
+       up(&card->mutex);
+ }
+Index: linux-2.6.0-test5/drivers/atm/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/Kconfig      2003-09-27 11:38:20.605395888 +0800
+@@ -241,7 +241,7 @@
+ config ATM_AMBASSADOR
+       tristate "Madge Ambassador (Collage PCI 155 Server)"
+-      depends on PCI && ATM && BROKEN_ON_SMP
++      depends on PCI && ATM
+       help
+         This is a driver for ATMizer based ATM card produced by Madge
+         Networks Ltd. Say Y (or M to compile as a module named ambassador)
+Index: linux-2.6.0-test5/drivers/atm/lanai.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/lanai.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/lanai.c      2003-09-27 11:38:20.628392392 +0800
+@@ -2242,7 +2242,6 @@
+               printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");
+               goto error_vcctable;
+       }
+-      MOD_INC_USE_COUNT;              /* At this point we can't fail */
+       mb();                           /* Make sure that all that made it */
+       intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));
+       /* 3.11: initialize loop mode (i.e. turn looping off) */
+@@ -2312,7 +2311,6 @@
+       service_buffer_deallocate(lanai);
+       iounmap((void *) lanai->base);
+       kfree(lanai);
+-      MOD_DEC_USE_COUNT;
+ }
+ /* close a vcc */
+@@ -2686,7 +2684,8 @@
+       .phy_put        = NULL,
+       .phy_get        = NULL,
+       .change_qos     = lanai_change_qos,
+-      .proc_read      = lanai_proc_read
++      .proc_read      = lanai_proc_read,
++      .owner          = THIS_MODULE
+ };
+ /* initialize one probed card */
+Index: linux-2.6.0-test5/drivers/atm/uPD98402.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/uPD98402.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/uPD98402.c   2003-09-27 11:38:20.630392088 +0800
+@@ -246,7 +246,7 @@
+ };
+-int __init uPD98402_init(struct atm_dev *dev)
++int uPD98402_init(struct atm_dev *dev)
+ {
+ DPRINTK("phy_init\n");
+       dev->phy = &uPD98402_ops;
+@@ -254,22 +254,13 @@
+ }
+-#ifdef MODULE
+ MODULE_LICENSE("GPL");
+ EXPORT_SYMBOL(uPD98402_init);
+- 
+-int init_module(void)
++static __init int uPD98402_module_init(void)
+ {
+-      MOD_INC_USE_COUNT;
+       return 0;
+ }
+-
+-
+-void cleanup_module(void)
+-{
+-      /* Nay */
+-}
+- 
+-#endif
++module_init(uPD98402_module_init);
++/* module_exit not defined so not unloadable */
+Index: linux-2.6.0-test5/drivers/atm/zatm.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/atm/zatm.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/atm/zatm.c       2003-09-27 11:38:20.641390416 +0800
+@@ -1619,11 +1619,10 @@
+ out:
+       kfree(zatm_dev);
+-      /* XXX: currently the driver is not unloadable.. */
+-      MOD_INC_USE_COUNT;
+       return 0;
+ }
+ MODULE_LICENSE("GPL");
+ module_init(zatm_module_init);
++/* module_exit not defined so not unloadable */
+Index: linux-2.6.0-test5/drivers/base/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/core.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/core.c      2003-09-27 11:38:20.645389808 +0800
+@@ -225,28 +225,30 @@
+               dev->kobj.parent = &parent->kobj;
+       if ((error = kobject_add(&dev->kobj)))
+-              goto register_done;
+-
+-      /* now take care of our own registration */
+-
++              goto Error;
++      if ((error = device_pm_add(dev)))
++              goto PMError;
++      if ((error = bus_add_device(dev)))
++              goto BusError;
+       down_write(&devices_subsys.rwsem);
+       if (parent)
+               list_add_tail(&dev->node,&parent->children);
+       up_write(&devices_subsys.rwsem);
+-      bus_add_device(dev);
+-
+-      device_pm_add(dev);
+-
+       /* notify platform of device entry */
+       if (platform_notify)
+               platform_notify(dev);
+-
+- register_done:
+-      if (error && parent)
+-              put_device(parent);
++ Done:
+       put_device(dev);
+       return error;
++ BusError:
++      device_pm_remove(dev);
++ PMError:
++      kobject_unregister(&dev->kobj);
++ Error:
++      if (parent)
++              put_device(parent);
++      goto Done;
+ }
+@@ -312,8 +314,6 @@
+ {
+       struct device * parent = dev->parent;
+-      device_pm_remove(dev);
+-
+       down_write(&devices_subsys.rwsem);
+       if (parent)
+               list_del_init(&dev->node);
+@@ -324,14 +324,11 @@
+        */
+       if (platform_notify_remove)
+               platform_notify_remove(dev);
+-
+       bus_remove_device(dev);
+-
++      device_pm_remove(dev);
+       kobject_del(&dev->kobj);
+-
+       if (parent)
+               put_device(parent);
+-
+ }
+ /**
+Index: linux-2.6.0-test5/drivers/base/power/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/main.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/main.c        2003-09-27 11:38:20.646389656 +0800
+@@ -36,12 +36,14 @@
+ static inline void device_pm_hold(struct device * dev)
+ {
+-      atomic_inc(&dev->power.pm_users);
++      if (dev)
++              atomic_inc(&dev->power.pm_users);
+ }
+ static inline void device_pm_release(struct device * dev)
+ {
+-      atomic_inc(&dev->power.pm_users);
++      if (dev)
++              atomic_dec(&dev->power.pm_users);
+ }
+@@ -61,11 +63,9 @@
+ void device_pm_set_parent(struct device * dev, struct device * parent)
+ {
+       struct device * old_parent = dev->power.pm_parent;
+-      if (old_parent)
+-              device_pm_release(old_parent);
++      device_pm_release(old_parent);
+       dev->power.pm_parent = parent;
+-      if (parent)
+-              device_pm_hold(parent);
++      device_pm_hold(parent);
+ }
+ EXPORT_SYMBOL(device_pm_set_parent);
+@@ -91,6 +91,7 @@
+                dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+       down(&dpm_sem);
+       dpm_sysfs_remove(dev);
++      device_pm_release(dev->power.pm_parent);
+       list_del(&dev->power.entry);
+       up(&dpm_sem);
+ }
+Index: linux-2.6.0-test5/drivers/base/power/power.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/power.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/power.h       2003-09-27 11:38:20.648389352 +0800
+@@ -58,7 +58,8 @@
+ /*
+  * resume.c 
+  */
+-extern int dpm_resume(void);
++
++extern void dpm_resume(void);
+ extern void dpm_power_up(void);
+ extern int resume_device(struct device *);
+Index: linux-2.6.0-test5/drivers/base/power/resume.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/resume.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/resume.c      2003-09-27 11:38:20.649389200 +0800
+@@ -28,6 +28,19 @@
+ }
++
++void dpm_resume(void)
++{
++      while(!list_empty(&dpm_off)) {
++              struct list_head * entry = dpm_off.next;
++              struct device * dev = to_device(entry);
++              list_del_init(entry);
++              resume_device(dev);
++              list_add_tail(entry,&dpm_active);
++      }
++}
++
++
+ /**
+  *    device_resume - Restore state of each device in system.
+  *
+@@ -38,13 +51,7 @@
+ void device_resume(void)
+ {
+       down(&dpm_sem);
+-      while(!list_empty(&dpm_off)) {
+-              struct list_head * entry = dpm_off.next;
+-              struct device * dev = to_device(entry);
+-              list_del_init(entry);
+-              resume_device(dev);
+-              list_add_tail(entry,&dpm_active);
+-      }
++      dpm_resume();
+       up(&dpm_sem);
+ }
+Index: linux-2.6.0-test5/drivers/base/power/suspend.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/base/power/suspend.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/base/power/suspend.c     2003-09-27 11:38:20.651388896 +0800
+@@ -81,14 +81,18 @@
+       while(!list_empty(&dpm_active)) {
+               struct list_head * entry = dpm_active.prev;
+               struct device * dev = to_device(entry);
+-              if ((error = suspend_device(dev,state)))
+-                      goto Error;
++              if ((error = suspend_device(dev,state))) {
++                      if (error != -EAGAIN)
++                              goto Error;
++                      else
++                              error = 0;
++              }
+       }
+  Done:
+       up(&dpm_sem);
+       return error;
+  Error:
+-      device_resume();
++      dpm_resume();
+       goto Done;
+ }
+Index: linux-2.6.0-test5/drivers/block/acsi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/acsi.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/acsi.c     2003-09-27 11:38:20.663387072 +0800
+@@ -1729,10 +1729,14 @@
+       for( i = 0; i < NDevices; ++i ) {
+               struct gendisk *disk = acsi_gendisk[i];
+               sprintf(disk->disk_name, "ad%c", 'a'+i);
++              aip = &acsi_info[NDevices];
++              sprintf(disk->devfs_name, "ad/target%d/lun%d", aip->target, aip->lun);
+               disk->major = ACSI_MAJOR;
+               disk->first_minor = i << 4;
+-              if (acsi_info[i].type != HARDDISK)
++              if (acsi_info[i].type != HARDDISK) {
+                       disk->minors = 1;
++                      strcat(disk->devfs_name, "/disc");
++              }
+               disk->fops = &acsi_fops;
+               disk->private_data = &acsi_info[i];
+               set_capacity(disk, acsi_info[i].size);
+Index: linux-2.6.0-test5/drivers/block/as-iosched.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/as-iosched.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/as-iosched.c       2003-09-27 11:38:20.675385248 +0800
+@@ -162,7 +162,7 @@
+       unsigned long expires;
+       unsigned int is_sync;
+-      enum arq_state state; /* debug only */
++      enum arq_state state;
+ };
+ #define RQ_DATA(rq)   ((struct as_rq *) (rq)->elevator_private)
+@@ -344,11 +344,19 @@
+       }
+ }
+-static struct as_rq *__as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
++/*
++ * Add the request to the rb tree if it is unique.  If there is an alias (an
++ * existing request against the same sector), which can happen when using
++ * direct IO, then return the alias.
++ */
++static struct as_rq *as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+ {
+       struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node;
+       struct rb_node *parent = NULL;
+       struct as_rq *__arq;
++      struct request *rq = arq->request;
++
++      arq->rb_key = rq_rb_key(rq);
+       while (*p) {
+               parent = *p;
+@@ -363,28 +371,9 @@
+       }
+       rb_link_node(&arq->rb_node, parent, p);
+-      return 0;
+-}
+-
+-static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq);
+-/*
+- * Add the request to the rb tree if it is unique.  If there is an alias (an
+- * existing request against the same sector), which can happen when using
+- * direct IO, then move the alias to the dispatch list and then add the
+- * request.
+- */
+-static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+-{
+-      struct as_rq *alias;
+-      struct request *rq = arq->request;
+-
+-      arq->rb_key = rq_rb_key(rq);
+-
+-      /* This can be caused by direct IO */
+-      while ((alias = __as_add_arq_rb(ad, arq)))
+-              as_move_to_dispatch(ad, alias);
+-
+       rb_insert_color(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
++
++      return NULL;
+ }
+ static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq)
+@@ -1021,6 +1010,7 @@
+               }
+       }
+ }
++
+ /*
+  * as_remove_request is called when a driver has finished with a request.
+  * This should be only called for dispatched requests, but for some reason
+@@ -1095,6 +1085,7 @@
+  */
+ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
+ {
++      struct list_head *insert;
+       const int data_dir = arq->is_sync;
+       BUG_ON(!ON_RB(&arq->rb_node));
+@@ -1109,8 +1100,6 @@
+       ad->last_sector[data_dir] = arq->request->sector
+                                       + arq->request->nr_sectors;
+-      ad->nr_dispatched++;
+-
+       if (data_dir == REQ_SYNC) {
+               /* In case we have to anticipate after this */
+               copy_io_context(&ad->io_context, &arq->io_context);
+@@ -1131,12 +1120,33 @@
+        * take it off the sort and fifo list, add to dispatch queue
+        */
+       as_remove_queued_request(ad->q, arq->request);
+-      list_add_tail(&arq->request->queuelist, ad->dispatch);
++
++      insert = ad->dispatch->prev;
++
++      while (!list_empty(&arq->request->queuelist)) {
++              struct request *rq = list_entry_rq(arq->request->queuelist.next);
++              struct as_rq *__arq = RQ_DATA(rq);
++
++              list_move_tail(&rq->queuelist, ad->dispatch);
++
++              if (__arq->io_context && __arq->io_context->aic)
++                      atomic_inc(&__arq->io_context->aic->nr_dispatched);
++
++              WARN_ON(__arq->state != AS_RQ_QUEUED);
++              __arq->state = AS_RQ_DISPATCHED;
++
++              ad->nr_dispatched++;
++      }
++
++      list_add(&arq->request->queuelist, insert);
+       if (arq->io_context && arq->io_context->aic)
+               atomic_inc(&arq->io_context->aic->nr_dispatched);
+       WARN_ON(arq->state != AS_RQ_QUEUED);
+       arq->state = AS_RQ_DISPATCHED;
++
++      ad->nr_dispatched++;
++
+ }
+ /*
+@@ -1290,10 +1300,31 @@
+ }
+ /*
++ * Add arq to a list behind alias
++ */
++static inline void
++as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
++{
++      /*
++       * 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);
++
++      /*
++       * Don't want to have to handle merges.
++       */
++      as_remove_merge_hints(ad->q, arq);
++
++}
++
++/*
+  * add arq to rbtree and fifo
+  */
+ static void as_add_request(struct as_data *ad, struct as_rq *arq)
+ {
++      struct as_rq *alias;
+       int data_dir;
+       if (rq_data_dir(arq->request) == READ
+@@ -1310,15 +1341,40 @@
+               as_update_iohist(arq->io_context->aic, arq->request);
+       }
+-      as_add_arq_rb(ad, arq);
++      alias = as_add_arq_rb(ad, arq);
++      if (!alias) {
++              /*
++               * set expire time (only used for reads) and add to fifo list
++               */
++              arq->expires = jiffies + ad->fifo_expire[data_dir];
++              list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
++
++              if (rq_mergeable(arq->request)) {
++                      as_add_arq_hash(ad, arq);
++
++                      if (!ad->q->last_merge)
++                              ad->q->last_merge = arq->request;
++              }
++              as_update_arq(ad, arq); /* keep state machine up to date */
++
++      } else {
++              as_add_aliased_request(ad, arq, alias);
++              /*
++               * have we been anticipating this request?
++               * or does it come from the same process as the one we are
++               * anticipating for?
++               */
++              if (ad->antic_status == ANTIC_WAIT_REQ
++                              || ad->antic_status == ANTIC_WAIT_NEXT) {
++                      if (as_can_break_anticipation(ad, arq))
++                              as_antic_stop(ad);
++              }
++      }
++
++
++
+-      /*
+-       * set expire time (only used for reads) and add to fifo list
+-       */
+-      arq->expires = jiffies + ad->fifo_expire[data_dir];
+-      list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
+       arq->state = AS_RQ_QUEUED;
+-      as_update_arq(ad, arq); /* keep state machine up to date */
+ }
+ /*
+@@ -1352,6 +1408,11 @@
+       struct as_data *ad = q->elevator.elevator_data;
+       struct as_rq *arq = RQ_DATA(rq);
++      /* barriers must flush the reorder queue */
++      if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
++                      && where == ELEVATOR_INSERT_SORT))
++              where = ELEVATOR_INSERT_BACK;
++
+       switch (where) {
+               case ELEVATOR_INSERT_BACK:
+                       while (ad->next_arq[REQ_SYNC])
+@@ -1359,7 +1420,9 @@
+                       while (ad->next_arq[REQ_ASYNC])
+                               as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
++
+                       list_add_tail(&rq->queuelist, ad->dispatch);
++                      as_antic_stop(ad);
+                       break;
+               case ELEVATOR_INSERT_FRONT:
+                       list_add(&rq->queuelist, ad->dispatch);
+@@ -1373,13 +1436,6 @@
+                       printk("%s: bad insert point %d\n", __FUNCTION__,where);
+                       return;
+       }
+-
+-      if (rq_mergeable(rq)) {
+-              as_add_arq_hash(ad, arq);
+-
+-              if (!q->last_merge)
+-                      q->last_merge = rq;
+-      }
+ }
+ /*
+@@ -1494,8 +1550,18 @@
+        * if the merge was a front merge, we need to reposition request
+        */
+       if (rq_rb_key(req) != arq->rb_key) {
++              struct as_rq *alias;
++
++              /*
++               * Note! We should really be moving any old aliased requests
++               * off this request and try to insert them into the rbtree. We
++               * currently don't bother. Ditto the next function.
++               */
+               as_del_arq_rb(ad, arq);
+-              as_add_arq_rb(ad, arq);
++              if ((alias = as_add_arq_rb(ad, arq)) ) {
++                      list_del_init(&arq->fifo);
++                      as_add_aliased_request(ad, arq, alias);
++              }
+               /*
+                * Note! At this stage of this and the next function, our next
+                * request may not be optimal - eg the request may have "grown"
+@@ -1525,8 +1591,12 @@
+       as_add_arq_hash(ad, arq);
+       if (rq_rb_key(req) != arq->rb_key) {
++              struct as_rq *alias;
+               as_del_arq_rb(ad, arq);
+-              as_add_arq_rb(ad, arq);
++              if ((alias = as_add_arq_rb(ad, arq)) ) {
++                      list_del_init(&arq->fifo);
++                      as_add_aliased_request(ad, arq, alias);
++              }
+       }
+       /*
+@@ -1865,7 +1935,7 @@
+       .elevator_exit_fn =             as_exit,
+       .elevator_ktype =               &as_ktype,
+-      .elevator_name =                "anticipatory scheduling",
++      .elevator_name =                "anticipatory",
+ };
+ EXPORT_SYMBOL(iosched_as);
+Index: linux-2.6.0-test5/drivers/block/cciss.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/cciss.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/cciss.c    2003-09-27 11:38:20.695382208 +0800
+@@ -243,7 +243,7 @@
+  * Get us a file in /proc/cciss that says something about each controller.
+  * Create /proc/cciss if it doesn't exist yet.
+  */
+-static void __init cciss_procinit(int i)
++static void __devinit cciss_procinit(int i)
+ {
+       struct proc_dir_entry *pde;
+@@ -754,16 +754,24 @@
+                       status = -ENOMEM;
+                       goto cleanup1;
+               }
+-              if (copy_from_user(ioc, (void *) arg, sizeof(*ioc)))
+-                      return -EFAULT;
++              if (copy_from_user(ioc, (void *) arg, sizeof(*ioc))) {
++                      status = -EFAULT;
++                      goto cleanup1;
++              }
+               if ((ioc->buf_size < 1) &&
+-                      (ioc->Request.Type.Direction != XFER_NONE))
+-                              return -EINVAL;
++                      (ioc->Request.Type.Direction != XFER_NONE)) {
++                              status = -EINVAL;
++                              goto cleanup1;
++              }
+               /* Check kmalloc limits  using all SGs */
+-              if (ioc->malloc_size > MAX_KMALLOC_SIZE)
+-                      return -EINVAL;
+-              if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES)
+-                      return -EINVAL;
++              if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
++                      status = -EINVAL;
++                      goto cleanup1;
++              }
++              if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
++                      status = -EINVAL;
++                      goto cleanup1;
++              }
+               buff = (unsigned char **) kmalloc(MAXSGENTRIES * 
+                               sizeof(char *), GFP_KERNEL);
+               if (!buff) {
+@@ -2427,7 +2435,7 @@
+  *  stealing all these major device numbers.
+  *  returns the number of block devices registered.
+  */
+-static int __init cciss_init_one(struct pci_dev *pdev,
++static int __devinit cciss_init_one(struct pci_dev *pdev,
+       const struct pci_device_id *ent)
+ {
+       request_queue_t *q;
+@@ -2531,6 +2539,7 @@
+               struct gendisk *disk = hba[i]->gendisk[j];
+               sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
++              sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j);
+               disk->major = COMPAQ_CISS_MAJOR + i;
+               disk->first_minor = j << NWD_SHIFT;
+               disk->fops = &cciss_fops;
+Index: linux-2.6.0-test5/drivers/block/cfq-iosched.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/cfq-iosched.c 2003-09-27 11:38:18.447723904 +0800
++++ linux-2.6.0-test5/drivers/block/cfq-iosched.c      2003-09-27 11:38:20.697381904 +0800
+@@ -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);
+Index: linux-2.6.0-test5/drivers/block/DAC960.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/DAC960.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/DAC960.c   2003-09-27 11:38:20.759372480 +0800
+@@ -71,7 +71,7 @@
+ {
+       struct gendisk *disk = inode->i_bdev->bd_disk;
+       DAC960_Controller_T *p = disk->queue->queuedata;
+-      int drive_nr = (int)disk->private_data;
++      int drive_nr = (long)disk->private_data;
+       if (p->FirmwareType == DAC960_V1_Controller) {
+               if (p->V1.LogicalDriveInformation[drive_nr].
+@@ -96,7 +96,7 @@
+ {
+       struct gendisk *disk = inode->i_bdev->bd_disk;
+       DAC960_Controller_T *p = disk->queue->queuedata;
+-      int drive_nr = (int)disk->private_data;
++      int drive_nr = (long)disk->private_data;
+       struct hd_geometry g, *loc = (struct hd_geometry *)arg;
+       if (cmd != HDIO_GETGEO || !loc)
+@@ -136,7 +136,7 @@
+ static int DAC960_media_changed(struct gendisk *disk)
+ {
+       DAC960_Controller_T *p = disk->queue->queuedata;
+-      int drive_nr = (int)disk->private_data;
++      int drive_nr = (long)disk->private_data;
+       if (!p->LogicalDriveInitiallyAccessible[drive_nr])
+               return 1;
+@@ -146,7 +146,7 @@
+ static int DAC960_revalidate_disk(struct gendisk *disk)
+ {
+       DAC960_Controller_T *p = disk->queue->queuedata;
+-      int unit = (int)disk->private_data;
++      int unit = (long)disk->private_data;
+       set_capacity(disk, disk_size(p, unit));
+       return 0;
+@@ -1603,6 +1603,26 @@
+     DAC960PU/PD/PL        3.51 and above
+     DAC960PU/PD/PL/P      2.73 and above
+   */
++#if defined(CONFIG_ALPHA)
++  /*
++    DEC Alpha machines were often equipped with DAC960 cards that were
++    OEMed from Mylex, and had their own custom firmware. Version 2.70,
++    the last custom FW revision to be released by DEC for these older
++    controllers, appears to work quite well with this driver.
++
++    Cards tested successfully were several versions each of the PD and
++    PU, called by DEC the KZPSC and KZPAC, respectively, and having
++    the Manufacturer Numbers (from Mylex), usually on a sticker on the
++    back of the board, of:
++
++    KZPSC:  D040347 (1-channel) or D040348 (2-channel) or D040349 (3-channel)
++    KZPAC:  D040395 (1-channel) or D040396 (2-channel) or D040397 (3-channel)
++  */
++# define FIRMWARE_27X "2.70"
++#else
++# define FIRMWARE_27X "2.73"
++#endif
++
+   if (Enquiry2->FirmwareID.MajorVersion == 0)
+     {
+       Enquiry2->FirmwareID.MajorVersion =
+@@ -1622,7 +1642,7 @@
+       (Controller->FirmwareVersion[0] == '3' &&
+        strcmp(Controller->FirmwareVersion, "3.51") >= 0) ||
+       (Controller->FirmwareVersion[0] == '2' &&
+-       strcmp(Controller->FirmwareVersion, "2.73") >= 0)))
++       strcmp(Controller->FirmwareVersion, FIRMWARE_27X) >= 0)))
+     {
+       DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
+       DAC960_Error("Firmware Version = '%s'\n", Controller,
+@@ -2485,7 +2505,7 @@
+       disk->queue = RequestQueue;
+       sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
+-      sprintf(disk->devfs_name, "rd/c%dd%d", Controller->ControllerNumber, n);
++      sprintf(disk->devfs_name, "rd/host%d/target%d", Controller->ControllerNumber, n);
+       disk->major = MajorNumber;
+       disk->first_minor = n << DAC960_MaxPartitionsBits;
+       disk->fops = &DAC960_BlockDeviceOperations;
+@@ -2708,12 +2728,12 @@
+         break;
+   }
+-  pci_set_drvdata(PCI_Device, (void *)((int)Controller->ControllerNumber));
++  pci_set_drvdata(PCI_Device, (void *)((long)Controller->ControllerNumber));
+   for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
+       Controller->disks[i] = alloc_disk(1<<DAC960_MaxPartitionsBits);
+       if (!Controller->disks[i])
+               goto Failure;
+-      Controller->disks[i]->private_data = (void *)i;
++      Controller->disks[i]->private_data = (void *)((long)i);
+   }
+   init_waitqueue_head(&Controller->CommandWaitQueue);
+   init_waitqueue_head(&Controller->HealthStatusWaitQueue);
+@@ -3097,7 +3117,7 @@
+ static void DAC960_Remove(struct pci_dev *PCI_Device)
+ {
+-  int Controller_Number = (int)pci_get_drvdata(PCI_Device);
++  int Controller_Number = (long)pci_get_drvdata(PCI_Device);
+   DAC960_Controller_T *Controller = DAC960_Controllers[Controller_Number];
+   if (Controller != NULL)
+       DAC960_FinalizeController(Controller);
+@@ -3272,7 +3292,7 @@
+     Command->CommandType = DAC960_WriteCommand;
+   }
+   Command->Completion = Request->waiting;
+-  Command->LogicalDriveNumber = (int)Request->rq_disk->private_data;
++  Command->LogicalDriveNumber = (long)Request->rq_disk->private_data;
+   Command->BlockNumber = Request->sector;
+   Command->BlockCount = Request->nr_sectors;
+   Command->Request = Request;
+Index: linux-2.6.0-test5/drivers/block/deadline-iosched.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/deadline-iosched.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/deadline-iosched.c 2003-09-27 11:38:20.766371416 +0800
+@@ -287,8 +287,11 @@
+  * add drq to rbtree and fifo
+  */
+ static inline void
+-deadline_add_request(struct deadline_data *dd, struct deadline_rq *drq)
++deadline_add_request(struct request_queue *q, struct request *rq)
+ {
++      struct deadline_data *dd = q->elevator.elevator_data;
++      struct deadline_rq *drq = RQ_DATA(rq);
++
+       const int data_dir = rq_data_dir(drq->request);
+       deadline_add_drq_rb(dd, drq);
+@@ -297,6 +300,13 @@
+        */
+       drq->expires = jiffies + dd->fifo_expire[data_dir];
+       list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
++
++      if (rq_mergeable(rq)) {
++              deadline_add_drq_hash(dd, drq);
++
++              if (!q->last_merge)
++                      q->last_merge = rq;
++      }
+ }
+ /*
+@@ -616,7 +626,11 @@
+ deadline_insert_request(request_queue_t *q, struct request *rq, int where)
+ {
+       struct deadline_data *dd = q->elevator.elevator_data;
+-      struct deadline_rq *drq = RQ_DATA(rq);
++
++      /* barriers must flush the reorder queue */
++      if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
++                      && where == ELEVATOR_INSERT_SORT))
++              where = ELEVATOR_INSERT_BACK;
+       switch (where) {
+               case ELEVATOR_INSERT_BACK:
+@@ -629,19 +643,12 @@
+                       break;
+               case ELEVATOR_INSERT_SORT:
+                       BUG_ON(!blk_fs_request(rq));
+-                      deadline_add_request(dd, drq);
++                      deadline_add_request(q, rq);
+                       break;
+               default:
+                       printk("%s: bad insert point %d\n", __FUNCTION__,where);
+                       return;
+       }
+-
+-      if (rq_mergeable(rq)) {
+-              deadline_add_drq_hash(dd, drq);
+-
+-              if (!q->last_merge)
+-                      q->last_merge = rq;
+-      }
+ }
+ static int deadline_queue_empty(request_queue_t *q)
+Index: linux-2.6.0-test5/drivers/block/floppy.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/floppy.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/floppy.c   2003-09-27 11:38:20.800366248 +0800
+@@ -219,6 +219,7 @@
+  */
+ static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED;
++static struct completion device_release;
+ static unsigned short virtual_dma_port=0x3f0;
+ irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+@@ -2152,18 +2153,20 @@
+ static void bad_flp_intr(void)
+ {
++      int err_count;
++
+       if (probing){
+               DRS->probed_format++;
+               if (!next_valid_format())
+                       return;
+       }
+-      (*errors)++;
+-      INFBOUND(DRWE->badness, *errors);
+-      if (*errors > DP->max_errors.abort)
++      err_count = ++(*errors);
++      INFBOUND(DRWE->badness, err_count);
++      if (err_count > DP->max_errors.abort)
+               cont->done(0);
+-      if (*errors > DP->max_errors.reset)
++      if (err_count > DP->max_errors.reset)
+               FDCS->reset = 1;
+-      else if (*errors > DP->max_errors.recal)
++      else if (err_count > DP->max_errors.recal)
+               DRS->track = NEED_2_RECAL;
+ }
+@@ -4203,9 +4206,17 @@
+ static int have_no_fdc= -ENODEV;
++static void floppy_device_release(struct device *dev)
++{
++      complete(&device_release);
++}
++
+ static struct platform_device floppy_device = {
+       .name           = "floppy",
+       .id             = 0,
++      .dev            = {
++                      .release = floppy_device_release,
++      }
+ };
+ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+@@ -4576,11 +4587,15 @@
+ void cleanup_module(void)
+ {
+       int drive;
+-              
++
++      init_completion(&device_release);
+       platform_device_unregister(&floppy_device);
+       blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+       unregister_blkdev(FLOPPY_MAJOR, "fd");
++
+       for (drive = 0; drive < N_DRIVE; drive++) {
++              del_timer_sync(&motor_off_timer[drive]);
++
+               if ((allowed_drive_mask & (1 << drive)) &&
+                   fdc_state[FDC(drive)].version != FDC_NONE) {
+                       del_gendisk(disks[drive]);
+@@ -4590,9 +4605,17 @@
+       }
+       devfs_remove("floppy");
++      del_timer_sync(&fd_timeout);
++      del_timer_sync(&fd_timer);
+       blk_cleanup_queue(floppy_queue);
++
++      if (usage_count)
++              floppy_release_irq_and_dma();
++
+       /* eject disk, if any */
+       fd_eject(0);
++
++      wait_for_completion(&device_release);
+ }
+ MODULE_PARM(floppy,"s");
+Index: linux-2.6.0-test5/drivers/block/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/Kconfig       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/Kconfig    2003-09-27 11:38:20.805365488 +0800
+@@ -44,7 +44,7 @@
+ config BLK_DEV_PS2
+       tristate "PS/2 ESDI hard disk support"
+-      depends on MCA
++      depends on MCA && MCA_LEGACY
+       help
+         Say Y here if you have a PS/2 machine with a MCA bus and an ESDI
+         hard disk.
+Index: linux-2.6.0-test5/drivers/block/Kconfig.iosched
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/Kconfig.iosched       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/Kconfig.iosched    2003-09-27 11:38:20.806365336 +0800
+@@ -27,3 +27,10 @@
+         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.
+Index: linux-2.6.0-test5/drivers/block/ll_rw_blk.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/ll_rw_blk.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/ll_rw_blk.c        2003-09-27 11:38:20.826362296 +0800
+@@ -458,16 +458,19 @@
+       if (!bqt)
+               return;
+-      BUG_ON(bqt->busy);
+-      BUG_ON(!list_empty(&bqt->busy_list));
++      if (atomic_dec_and_test(&bqt->refcnt)) {
++              BUG_ON(bqt->busy);
++              BUG_ON(!list_empty(&bqt->busy_list));
+-      kfree(bqt->tag_index);
+-      bqt->tag_index = NULL;
++              kfree(bqt->tag_index);
++              bqt->tag_index = NULL;
+-      kfree(bqt->tag_map);
+-      bqt->tag_map = NULL;
++              kfree(bqt->tag_map);
++              bqt->tag_map = NULL;
++
++              kfree(bqt);
++      }
+-      kfree(bqt);
+       q->queue_tags = NULL;
+       q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);
+ }
+@@ -503,6 +506,9 @@
+       for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++)
+               __set_bit(i, tags->tag_map);
++      INIT_LIST_HEAD(&tags->busy_list);
++      tags->busy = 0;
++      atomic_set(&tags->refcnt, 1);
+       return 0;
+ fail:
+       kfree(tags->tag_index);
+@@ -514,19 +520,18 @@
+  * @q:  the request queue for the device
+  * @depth:  the maximum queue depth supported
+  **/
+-int blk_queue_init_tags(request_queue_t *q, int depth)
++int blk_queue_init_tags(request_queue_t *q, int depth,
++                      struct blk_queue_tag *tags)
+ {
+-      struct blk_queue_tag *tags;
+-
+-      tags = kmalloc(sizeof(struct blk_queue_tag),GFP_ATOMIC);
+-      if (!tags)
+-              goto fail;
+-
+-      if (init_tag_map(q, tags, depth))
+-              goto fail;
++      if (!tags) {
++              tags = kmalloc(sizeof(struct blk_queue_tag), GFP_ATOMIC);
++              if (!tags)
++                      goto fail;
+-      INIT_LIST_HEAD(&tags->busy_list);
+-      tags->busy = 0;
++              if (init_tag_map(q, tags, depth))
++                      goto fail;
++      } else
++              atomic_inc(&tags->refcnt);
+       /*
+        * assign it, all done
+@@ -1016,7 +1021,13 @@
+ void blk_plug_device(request_queue_t *q)
+ {
+       WARN_ON(!irqs_disabled());
+-      if (!blk_queue_plugged(q)) {
++
++      /*
++       * don't plug a stopped queue, it must be paired with blk_start_queue()
++       * which will restart the queueing
++       */
++      if (!blk_queue_plugged(q)
++          && !test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) {
+               spin_lock(&blk_plug_lock);
+               list_add_tail(&q->plug_list, &blk_plug_list);
+               mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
+@@ -1239,6 +1250,8 @@
+       &iosched_as;
+ #elif defined(CONFIG_IOSCHED_DEADLINE)
+       &iosched_deadline;
++#elif defined(CONFIG_IOSCHED_CFQ)
++      &iosched_cfq;
+ #elif defined(CONFIG_IOSCHED_NOOP)
+       &elevator_noop;
+ #else
+@@ -1257,6 +1270,10 @@
+       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;
+@@ -1769,25 +1786,50 @@
+ }
+ /**
+- * 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
+  */
+Index: linux-2.6.0-test5/drivers/block/loop.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/loop.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/loop.c     2003-09-27 11:38:20.835360928 +0800
+@@ -757,7 +757,7 @@
+               blk_queue_merge_bvec(lo->lo_queue, q->merge_bvec_fn);
+       }
+-      kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      kernel_thread(loop_thread, lo, CLONE_KERNEL);
+       down(&lo->lo_sem);
+       fput(file);
+@@ -931,9 +931,9 @@
+               return error;
+       memset(info, 0, sizeof(*info));
+       info->lo_number = lo->lo_number;
+-      info->lo_device = stat.dev;
++      info->lo_device = huge_encode_dev(stat.dev);
+       info->lo_inode = stat.ino;
+-      info->lo_rdevice = lo->lo_device ? stat.rdev : stat.dev;
++      info->lo_rdevice = huge_encode_dev(lo->lo_device ? stat.rdev : stat.dev);
+       info->lo_offset = lo->lo_offset;
+       info->lo_sizelimit = lo->lo_sizelimit;
+       info->lo_flags = lo->lo_flags;
+Index: linux-2.6.0-test5/drivers/block/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/Makefile      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/Makefile   2003-09-27 11:38:20.836360776 +0800
+@@ -18,6 +18,7 @@
+ 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
+Index: linux-2.6.0-test5/drivers/block/ps2esdi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/ps2esdi.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/ps2esdi.c  2003-09-27 11:38:20.844359560 +0800
+@@ -62,8 +62,6 @@
+ static void reset_ctrl(void);
+-int ps2esdi_init(void);
+-
+ static int ps2esdi_geninit(void);
+ static void do_ps2esdi_request(request_queue_t * q);
+@@ -141,7 +139,7 @@
+ static struct gendisk *ps2esdi_gendisk[2];
+ /* initialization routine called by ll_rw_blk.c   */
+-int __init ps2esdi_init(void)
++static int __init ps2esdi_init(void)
+ {
+       int error = 0;
+@@ -169,9 +167,11 @@
+       return 0;
+ }                             /* ps2esdi_init */
++#ifndef MODULE
++
+ module_init(ps2esdi_init);
+-#ifdef MODULE
++#else
+ static int cyl[MAX_HD] = {-1,-1};
+ static int head[MAX_HD] = {-1, -1};
+@@ -187,7 +187,7 @@
+       int drive;
+       for(drive = 0; drive < MAX_HD; drive++) {
+-              struct ps2_esdi_i_struct *info = &ps2esdi_info[drive];
++              struct ps2esdi_i_struct *info = &ps2esdi_info[drive];
+               if (cyl[drive] != -1) {
+                       info->cyl = info->lzone = cyl[drive];
+@@ -204,6 +204,7 @@
+ void
+ cleanup_module(void) {
++      int i;
+       if(ps2esdi_slot) {
+               mca_mark_as_unused(ps2esdi_slot);
+               mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
+@@ -421,6 +422,7 @@
+               disk->major = PS2ESDI_MAJOR;
+               disk->first_minor = i<<6;
+               sprintf(disk->disk_name, "ed%c", 'a'+i);
++              sprintf(disk->devfs_name, "ed/target%d", i);
+               disk->fops = &ps2esdi_fops;
+               ps2esdi_gendisk[i] = disk;
+       }
+Index: linux-2.6.0-test5/drivers/block/rd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/rd.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/rd.c       2003-09-27 11:38:20.848358952 +0800
+@@ -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 @@
+  * 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 @@
+  *               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 @@
+       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 @@
+       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 @@
+  * 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,7 +244,8 @@
+       return 0;
+ } 
+-static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++static int rd_ioctl(struct inode *inode, struct file *file,
++                      unsigned int cmd, unsigned long arg)
+ {
+       int error;
+       struct block_device *bdev = inode->i_bdev;
+@@ -250,9 +253,11 @@
+       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,7 +273,7 @@
+       .memory_backed  = 1,    /* Does not contribute to dirty memory */
+ };
+-static int rd_open(struct inode * inode, struct file * filp)
++static int rd_open(struct inode *inode, struct file *filp)
+ {
+       unsigned unit = iminor(inode);
+@@ -295,12 +300,14 @@
+       .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 +318,19 @@
+               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 +371,8 @@
+       /* 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:
+Index: linux-2.6.0-test5/drivers/block/scsi_ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/scsi_ioctl.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/scsi_ioctl.c       2003-09-27 11:38:20.852358344 +0800
+@@ -319,7 +319,7 @@
+               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);
+Index: linux-2.6.0-test5/drivers/block/umem.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/umem.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/umem.c     2003-09-27 11:38:20.861356976 +0800
+@@ -52,7 +52,6 @@
+ #include <linux/fcntl.h>        /* O_ACCMODE */
+ #include <linux/hdreg.h>  /* HDIO_GETGEO */
+-#include <linux/devfs_fs_kernel.h>
+ #include <linux/umem.h>
+@@ -1204,11 +1203,10 @@
+                       goto out;
+       }
+-      devfs_mk_dir("umem");
+-
+       for (i = 0; i < num_cards; i++) {
+               struct gendisk *disk = mm_gendisk[i];
+               sprintf(disk->disk_name, "umem%c", 'a'+i);
++              sprintf(disk->devfs_name, "umem/card%d", i);
+               spin_lock_init(&cards[i].lock);
+               disk->major = major_nr;
+               disk->first_minor  = i << MM_SHIFT;
+@@ -1245,7 +1243,6 @@
+               del_gendisk(mm_gendisk[i]);
+               put_disk(mm_gendisk[i]);
+       }
+-      devfs_remove("umem");
+       pci_unregister_driver(&mm_pci_driver);
+Index: linux-2.6.0-test5/drivers/block/xd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/xd.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/xd.c       2003-09-27 11:38:20.870355608 +0800
+@@ -45,7 +45,6 @@
+ #include <linux/ioport.h>
+ #include <linux/init.h>
+ #include <linux/wait.h>
+-#include <linux/devfs_fs_kernel.h>
+ #include <linux/blkdev.h>
+ #include <linux/blkpg.h>
+@@ -182,7 +181,6 @@
+       if (!xd_queue)
+               goto out1a;
+-      devfs_mk_dir("xd");
+       if (xd_detect(&controller,&address)) {
+               printk("Detected a%s controller (type %d) at address %06x\n",
+@@ -213,6 +211,7 @@
+               disk->major = XT_DISK_MAJOR;
+               disk->first_minor = i<<6;
+               sprintf(disk->disk_name, "xd%c", i+'a');
++              sprintf(disk->devfs_name, "xd/target%d", i);
+               disk->fops = &xd_fops;
+               disk->private_data = p;
+               disk->queue = xd_queue;
+@@ -249,7 +248,6 @@
+ out3:
+       release_region(xd_iobase,4);
+ out2:
+-      devfs_remove("xd");
+       blk_cleanup_queue(xd_queue);
+ out1a:
+       unregister_blkdev(XT_DISK_MAJOR, "xd");
+@@ -1064,7 +1062,6 @@
+       }
+       blk_cleanup_queue(xd_queue);
+       release_region(xd_iobase,4);
+-      devfs_remove("xd");
+       if (xd_drives) {
+               free_irq(xd_irq, NULL);
+               free_dma(xd_dma);
+Index: linux-2.6.0-test5/drivers/block/z2ram.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/block/z2ram.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/block/z2ram.c    2003-09-27 11:38:20.874355000 +0800
+@@ -354,6 +354,7 @@
+     z2ram_gendisk->first_minor = 0;
+     z2ram_gendisk->fops = &z2_fops;
+     sprintf(z2ram_gendisk->disk_name, "z2ram");
++    strcpy(z2ram_gendisk->devfs_name, z2ram_gendisk->disk_name);
+     z2ram_gendisk->queue = z2_queue;
+     add_disk(z2ram_gendisk);
+Index: linux-2.6.0-test5/drivers/bluetooth/hci_usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/bluetooth/hci_usb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/bluetooth/hci_usb.c      2003-09-27 11:38:20.880354088 +0800
+@@ -302,7 +302,8 @@
+                       hci_usb_bulk_rx_submit(husb);
+ #ifdef CONFIG_BT_USB_SCO
+-              hci_usb_isoc_rx_submit(husb);
++              if (husb->isoc_iface)
++                      hci_usb_isoc_rx_submit(husb);
+ #endif
+       } else {
+               clear_bit(HCI_RUNNING, &hdev->flags);
+Index: linux-2.6.0-test5/drivers/cdrom/gscd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cdrom/gscd.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cdrom/gscd.c     2003-09-27 11:38:20.885353328 +0800
+@@ -965,7 +965,7 @@
+       gscd_queue = blk_init_queue(do_gscd_request, &gscd_lock);
+       if (!gscd_queue) {
+-              ret -ENOMEM;
++              ret = -ENOMEM;
+               goto err_out3;
+       }
+Index: linux-2.6.0-test5/drivers/cdrom/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cdrom/Kconfig       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cdrom/Kconfig    2003-09-27 11:38:20.889352720 +0800
+@@ -267,7 +267,7 @@
+ config CDU535
+       tristate "Sony CDU535 CDROM support"
+-      depends on CD_NO_IDESCSI && BROKEN_ON_SMP
++      depends on CD_NO_IDESCSI
+       ---help---
+         This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM
+         drives. Please read the file <file:Documentation/cdrom/sonycd535>.
+Index: linux-2.6.0-test5/drivers/cdrom/sonycd535.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cdrom/sonycd535.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cdrom/sonycd535.c        2003-09-27 11:38:20.902350744 +0800
+@@ -36,6 +36,10 @@
+  *                module_init & module_exit.
+  *                  Torben Mathiasen <tmm@image.dk>
+  *
++ * September 2003 - Fix SMP support by removing cli/sti calls.
++ *                  Using spinlocks with a wait_queue instead.
++ *                  Felipe Damasio <felipewd@terra.com.br>
++ *
+  * Things to do:
+  *  - handle errors and status better, put everything into a single word
+  *  - use interrupts (code mostly there, but a big hole still missing)
+@@ -340,10 +344,14 @@
+       if (sony535_irq_used <= 0) {    /* poll */
+               yield();
+       } else {        /* Interrupt driven */
+-              cli();
++              DEFINE_WAIT(wait);
++              
++              spin_lock_irq(&sonycd535_lock);
+               enable_interrupts();
+-              interruptible_sleep_on(&cdu535_irq_wait);
+-              sti();
++              prepare_to_wait(&cdu535_irq_wait, &wait, TASK_INTERRUPTIBLE);
++              spin_unlock_irq(&sonycd535_lock);
++              schedule();
++              finish_wait(&cdu535_irq_wait, &wait);
+       }
+ }
+@@ -804,14 +812,14 @@
+               block = req->sector;
+               nsect = req->nr_sectors;
+-              if (!(req->flags & REQ_CMD))
+-                      continue;       /* FIXME */
++              if (!blk_fs_request(req)) {
++                      end_request(req, 0);
++                      continue;
++              }
+               if (rq_data_dir(req) == WRITE) {
+                       end_request(req, 0);
+                       continue;
+               }
+-              if (rq_data_dir(req) != READ)
+-                      panic("Unknown SONY CD cmd");
+               /*
+                * If the block address is invalid or the request goes beyond
+                * the end of the media, return an error.
+@@ -888,8 +896,10 @@
+                                       }
+                                       if (readStatus == BAD_STATUS) {
+                                               /* Sleep for a while, then retry */
+-                                              current->state = TASK_INTERRUPTIBLE;
++                                              set_current_state(TASK_INTERRUPTIBLE);
++                                              spin_unlock_irq(&sonycd535_lock);
+                                               schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
++                                              spin_lock_irq(&sonycd535_lock);
+                                       }
+ #if DEBUG > 0
+                                       printk(CDU535_MESSAGE_NAME
+@@ -1473,7 +1483,7 @@
+       /* look for the CD-ROM, follows the procedure in the DOS driver */
+       inb(select_unit_reg);
+       /* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
+-      current->state = TASK_INTERRUPTIBLE;
++      set_current_state(TASK_INTERRUPTIBLE);
+       schedule_timeout((HZ+17)*40/18);
+       inb(result_reg);
+Index: linux-2.6.0-test5/drivers/char/agp/alpha-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/alpha-agp.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/alpha-agp.c     2003-09-27 11:38:20.904350440 +0800
+@@ -183,7 +183,7 @@
+       alpha_bridge->dev = pdev;
+       alpha_bridge->mode = agp->capability.lw;
+-      printk(KERN_INFO "Detected AGP on hose %d\n", agp->hose->index);
++      printk(KERN_INFO PFX "Detected AGP on hose %d\n", agp->hose->index);
+       return agp_add_bridge(alpha_bridge);
+  fail:
+Index: linux-2.6.0-test5/drivers/char/agp/amd64-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/amd64-agp.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/amd64-agp.c     2003-09-27 11:38:20.909349680 +0800
+@@ -8,6 +8,7 @@
+  * work is done in the northbridge(s).
+  */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+@@ -252,15 +253,15 @@
+       static int not_first_call; 
+       u32 pfn, c;
+       if (aper == 0) { 
+-              printk(KERN_ERR "No aperture\n");
++              printk(KERN_ERR PFX "No aperture\n");
+               return 0; 
+       }
+       if (size < 32*1024*1024) {
+-              printk(KERN_ERR "Aperture too small (%d MB)\n", size>>20);
++              printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20);
+               return 0;
+       }
+       if (aper + size > 0xffffffff) { 
+-              printk(KERN_ERR "Aperture out of bounds\n"); 
++              printk(KERN_ERR PFX "Aperture out of bounds\n"); 
+               return 0;
+       } 
+       pfn = aper >> PAGE_SHIFT;
+@@ -268,7 +269,7 @@
+               if (!pfn_valid(pfn + c))
+                       break;
+               if (!PageReserved(pfn_to_page(pfn + c))) { 
+-                      printk(KERN_ERR "Aperture pointing to RAM\n");
++                      printk(KERN_ERR PFX "Aperture pointing to RAM\n");
+                       return 0;
+               }
+       }
+@@ -279,7 +280,7 @@
+          Maybe better to use pci_assign_resource/pci_enable_device instead trusting
+          the bridges? */
+       if (!not_first_call && request_mem_region(aper, size, "aperture") < 0) { 
+-              printk(KERN_ERR "Aperture conflicts with PCI mapping.\n"); 
++              printk(KERN_ERR PFX "Aperture conflicts with PCI mapping.\n"); 
+               return 0;
+       }
+@@ -328,7 +329,7 @@
+       pci_read_config_dword(agp, 0x10, &aper_low);
+       pci_read_config_dword(agp, 0x14, &aper_hi);
+       aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); 
+-      printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
++      printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
+       if (order < 0 || !aperture_valid(aper, (32*1024*1024)<<order))
+               return -1; 
+       
+@@ -347,17 +348,17 @@
+       while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) 
+                       != NULL) {
+               if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) { 
+-                      printk("No usable aperture found.\n");
++                      printk(KERN_INFO PFX "No usable aperture found.\n");
+ #ifdef __x86_64__ 
+                       /* should port this to i386 */
+-                      printk("Consider rebooting with iommu=memaper=2 to get a good aperture.\n");
++                      printk(KERN_INFO PFX "Consider rebooting with iommu=memaper=2 to get a good aperture.\n");
+ #endif 
+                       return -1;  
+               }
+               hammers[i++] = loop_dev;
+               nr_garts = i;
+               if (i == MAX_HAMMER_GARTS) { 
+-                      printk(KERN_INFO "Too many northbridges for AGP\n");
++                      printk(KERN_INFO PFX "Too many northbridges for AGP\n");
+                       return -1;
+               }
+       }
+@@ -495,14 +496,14 @@
+       int err = 0;
+       if (agp_off)
+               return -EINVAL;
+-      if (pci_module_init(&agp_amd64_pci_driver) == 0) { 
++      if (pci_module_init(&agp_amd64_pci_driver) > 0) { 
+               struct pci_dev *dev;
+               if (!agp_try_unsupported && !agp_try_unsupported_boot) { 
+-                      printk(KERN_INFO "No supported AGP bridge found.\n");
++                      printk(KERN_INFO PFX "No supported AGP bridge found.\n");
+ #ifdef MODULE                 
+-                      printk(KERN_INFO "You can try agp_try_unsupported=1\n");
++                      printk(KERN_INFO PFX "You can try agp_try_unsupported=1\n");
+ #else
+-                      printk(KERN_INFO "You can boot with agp=try_unsupported\n");
++                      printk(KERN_INFO PFX "You can boot with agp=try_unsupported\n");
+ #endif                        
+                       return -ENODEV;
+               }
+Index: linux-2.6.0-test5/drivers/char/agp/ati-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/ati-agp.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/ati-agp.c       2003-09-27 11:38:20.913349072 +0800
+@@ -214,7 +214,7 @@
+         /*
+       pci_read_config_dword(agp_bridge.dev, AGP_APBASE, &temp);
+       agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+-      printk(KERN_INFO "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
++      printk(KERN_INFO PFX "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
+         */
+       OUTREG32(ati_generic_private.registers, ATI_GART_FEATURE_ID, 0x60000);
+@@ -226,8 +226,6 @@
+       OUTREG32(ati_generic_private.registers, ATI_GART_BASE,
+                agp_bridge->gatt_bus_addr);
+-      /* Flush the tlb */
+-      OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1);
+       return 0;
+ }
+@@ -491,7 +489,7 @@
+       agp_put_bridge(bridge);
+ }
+-static struct pci_device_id agp_ati_pci_table[] __initdata = {
++static struct pci_device_id agp_ati_pci_table[] = {
+       {
+       .class          = (PCI_CLASS_BRIDGE_HOST << 8),
+       .class_mask     = ~0,
+Index: linux-2.6.0-test5/drivers/char/agp/backend.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/backend.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/backend.c       2003-09-27 11:38:20.916348616 +0800
+@@ -26,7 +26,6 @@
+  * TODO: 
+  * - Allocate more than order 0 pages to avoid too much linear map splitting.
+  */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+@@ -34,6 +33,7 @@
+ #include <linux/miscdevice.h>
+ #include <linux/pm.h>
+ #include <linux/agp_backend.h>
++#include <linux/agpgart.h>
+ #include <linux/vmalloc.h>
+ #include <asm/io.h>
+ #include "agp.h"
+@@ -318,6 +318,7 @@
+ {
+ }
++#ifdef MODULE
+ static __init int agp_setup(char *s)
+ {
+       if (!strcmp(s,"off"))
+@@ -327,6 +328,7 @@
+       return 1;       
+ }
+ __setup("agp=", agp_setup);
++#endif
+ MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+ MODULE_DESCRIPTION("AGP GART driver");
+Index: linux-2.6.0-test5/drivers/char/agp/hp-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/hp-agp.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/hp-agp.c        2003-09-27 11:38:20.920348008 +0800
+@@ -42,6 +42,8 @@
+ /* AGP bridge need not be PCI device, but DRM thinks it is. */
+ static struct pci_dev fake_bridge_dev;
++static int hp_zx1_gart_found;
++
+ static struct aper_size_info_fixed hp_zx1_sizes[] =
+ {
+       {0, 0, 0},              /* filled in by hp_zx1_fetch_size() */
+@@ -386,8 +388,6 @@
+       struct agp_bridge_data *bridge;
+       int error;
+-      printk(KERN_INFO PFX "Detected HP ZX1 AGP chipset (ioc=%lx, lba=%lx)\n", ioc_hpa, lba_hpa);
+-
+       error = hp_zx1_ioc_init(ioc_hpa, lba_hpa);
+       if (error)
+               return error;
+@@ -416,7 +416,7 @@
+       status = hp_acpi_csr_space(obj, &lba_hpa, &length);
+       if (ACPI_FAILURE(status))
+-              return 1;
++              return AE_OK;
+       /* Look for an enclosing IOC scope and find its CSR space */
+       handle = obj;
+@@ -436,7 +436,7 @@
+                               else {
+                                       printk(KERN_ERR PFX "Detected HP ZX1 "
+                                              "AGP LBA but no IOC.\n");
+-                                      return status;
++                                      return AE_OK;
+                               }
+                       }
+               }
+@@ -446,22 +446,28 @@
+       } while (ACPI_SUCCESS(status));
+       if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
+-              return 1;
+-      return 0;
++              return AE_OK;
++
++      printk(KERN_INFO PFX "Detected HP ZX1 %s AGP chipset (ioc=%lx, lba=%lx)\n",
++              (char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
++
++      hp_zx1_gart_found = 1;
++      return AE_CTRL_TERMINATE;
+ }
+ static int __init
+ agp_hp_init (void)
+ {
+-      acpi_status status;
+-      status = acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003 AGP LBA", NULL);
+-      if (!(ACPI_SUCCESS(status))) {
+-              agp_bridge->type = NOT_SUPPORTED;
+-              printk(KERN_INFO PFX "Failed to initialize zx1 AGP.\n");
+-              return -ENODEV;
+-      }
+-      return 0;
++      acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
++      if (hp_zx1_gart_found)
++              return 0;
++
++      acpi_get_devices("HWP0007", zx1_gart_probe, "HWP0007", NULL);
++      if (hp_zx1_gart_found)
++              return 0;
++
++      return -ENODEV;
+ }
+ static void __exit
+Index: linux-2.6.0-test5/drivers/char/agp/intel-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/intel-agp.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/intel-agp.c     2003-09-27 11:38:20.931346336 +0800
+@@ -445,7 +445,7 @@
+       num_entries = A_SIZE_FIX(temp)->num_entries;
+       if (pg_start < intel_i830_private.gtt_entries) {
+-              printk (KERN_DEBUG "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
++              printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
+                               pg_start,intel_i830_private.gtt_entries);
+               printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
+Index: linux-2.6.0-test5/drivers/char/agp/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/Kconfig    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/Kconfig 2003-09-27 11:38:20.933346032 +0800
+@@ -80,8 +80,8 @@
+       tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
+       depends on AGP && X86 && !X86_64
+       help
+-        This option gives you AGP support for the GLX component of
+-        XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860
++        This option gives you AGP support for the GLX component of XFree86 4.x
++        on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875,
+         E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G,
+         852GM, 855GM and 865G integrated graphics chipsets.
+Index: linux-2.6.0-test5/drivers/char/agp/nvidia-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/nvidia-agp.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/nvidia-agp.c    2003-09-27 11:38:20.937345424 +0800
+@@ -196,7 +196,7 @@
+                       pci_read_config_dword(nvidia_private.dev_1,
+                                       NVIDIA_1_WBC, &wbc_reg);
+                       if ((signed)(end - jiffies) <= 0) {
+-                              printk(KERN_ERR
++                              printk(KERN_ERR PFX
+                                   "TLB flush took more than 3 seconds.\n");
+                       }
+               } while (wbc_reg & nvidia_private.wbc_mask);
+Index: linux-2.6.0-test5/drivers/char/agp/sis-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/sis-agp.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/sis-agp.c       2003-09-27 11:38:20.939345120 +0800
+@@ -215,7 +215,7 @@
+       agp_put_bridge(bridge);
+ }
+-static struct pci_device_id agp_sis_pci_table[] __initdata = {
++static struct pci_device_id agp_sis_pci_table[] = {
+       {
+       .class          = (PCI_CLASS_BRIDGE_HOST << 8),
+       .class_mask     = ~0,
+Index: linux-2.6.0-test5/drivers/char/agp/uninorth-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/uninorth-agp.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/uninorth-agp.c  2003-09-27 11:38:20.943344512 +0800
+@@ -350,7 +350,7 @@
+       agp_put_bridge(bridge);
+ }
+-static struct pci_device_id agp_uninorth_pci_table[] __initdata = {
++static struct pci_device_id agp_uninorth_pci_table[] = {
+       {
+       .class          = (PCI_CLASS_BRIDGE_HOST << 8),
+       .class_mask     = ~0,
+Index: linux-2.6.0-test5/drivers/char/agp/via-agp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/agp/via-agp.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/agp/via-agp.c       2003-09-27 11:38:20.946344056 +0800
+@@ -432,7 +432,7 @@
+       agp_put_bridge(bridge);
+ }
+-static struct pci_device_id agp_via_pci_table[] __initdata = {
++static struct pci_device_id agp_via_pci_table[] = {
+       {
+       .class          = (PCI_CLASS_BRIDGE_HOST << 8),
+       .class_mask     = ~0,
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_conf.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_conf.h  2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_conf.h       2003-09-27 11:38:20.947343904 +0800
+@@ -0,0 +1,283 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *****************************************************************************
++ *
++ *    dgap_conf.h - Header file for installations and parse files.
++ *
++ *    $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef _DGAP_CONF_H
++#define _DGAP_CONF_H
++
++#define NULLNODE 0            /* header node, not used */
++#define BNODE 1                       /* Board node */
++#define LNODE 2                       /* Line node */
++#define CNODE 3                       /* Concentrator node */
++#define MNODE 4                       /* EBI Module node */
++#define TNODE 5                       /* tty name prefix node */
++#define       CUNODE 6                /* cu name prefix (non-SCO) */
++#define PNODE 7                       /* trans. print prefix node */
++#define JNODE 8                       /* maJor number node */
++#define ANODE 9                       /* altpin */
++#define       TSNODE 10               /* tty structure size */
++#define CSNODE 11             /* channel structure size */
++#define BSNODE 12             /* board structure size */
++#define USNODE 13             /* unit schedule structure size */
++#define FSNODE 14             /* f2200 structure size */
++#define VSNODE 15             /* size of VPIX structures */
++#define INTRNODE 16           /* enable interrupt */
++
++/* Enumeration of tokens */
++#define       BEGIN   1
++#define       END     2
++#define       BOARD   10
++
++#define EPCFS 11 /* start of EPC family definitions */
++#define       ICX             11
++#define       MCX             13
++#define PCX   14
++#define       IEPC    15
++#define       EEPC    16
++#define       MEPC    17
++#define       IPCM    18
++#define       EPCM    19
++#define       MPCM    20
++#define PEPC  21
++#define PPCM  22
++#ifdef CP
++#define ICP     23
++#define ECP     24
++#define MCP     25
++#endif
++#define EPCFE 25 /* end of EPC family definitions */
++#define       PC2E    26
++#define       PC4E    27
++#define       PC4E8K  28
++#define       PC8E    29
++#define       PC8E8K  30
++#define       PC16E   31
++#define MC2E8K  34
++#define MC4E8K  35
++#define MC8E8K  36
++
++#define AVANFS        42      /* start of Avanstar family definitions */
++#define A8P   42
++#define A16P  43
++#define AVANFE        43      /* end of Avanstar family definitions */
++
++#define DA2000FS      44      /* start of AccelePort 2000 family definitions */
++#define DA22          44 /* AccelePort 2002 */
++#define DA24          45 /* AccelePort 2004 */
++#define DA28          46 /* AccelePort 2008 */
++#define DA216         47 /* AccelePort 2016 */
++#define DAR4          48 /* AccelePort RAS 4 port */
++#define DAR8          49 /* AccelePort RAS 8 port */
++#define DDR24         50 /* DataFire RAS 24 port */
++#define DDR30         51 /* DataFire RAS 30 port */
++#define DDR48         52 /* DataFire RAS 48 port */
++#define DDR60         53 /* DataFire RAS 60 port */
++#define DA2000FE      53 /* end of AccelePort 2000/RAS family definitions */
++
++#define PCXRFS        106     /* start of PCXR family definitions */
++#define       APORT4  106
++#define       APORT8  107
++#define PAPORT4 108
++#define PAPORT8 109
++#define APORT4_920I   110
++#define APORT8_920I   111
++#define APORT4_920P   112
++#define APORT8_920P   113
++#define APORT2_920P 114
++#define PCXRFE        117     /* end of PCXR family definitions */
++
++#define       LINE    82
++#ifdef T1
++#define T1M   83
++#define E1M   84
++#endif
++#define       CONC    64
++#define       CX      65
++#define       EPC     66
++#define       MOD     67
++#define       PORTS   68
++#define METHOD        69
++#define CUSTOM        70
++#define BASIC 71
++#define STATUS        72
++#define MODEM 73
++/* The following tokens can appear in multiple places */
++#define       SPEED   74
++#define       NPORTS  75
++#define       ID      76
++#define CABLE 77
++#define CONNECT       78
++#define       IO      79
++#define       MEM     80
++#define DPSZ  81
++
++#define       TTYN    90
++#define       CU      91
++#define       PRINT   92
++#define       XPRINT  93
++#define CMAJOR   94
++#define ALTPIN  95
++#define STARTO 96
++#define USEINTR  97
++
++#define       TTSIZ   100
++#define       CHSIZ   101
++#define BSSIZ 102
++#define       UNTSIZ  103
++#define       F2SIZ   104
++#define       VPSIZ   105
++
++#define       TOTAL_BOARD     2
++#define       CURRENT_BRD     4
++#define       BOARD_TYPE      6
++#define       IO_ADDRESS      8
++#define       MEM_ADDRESS     10
++
++#define       FIELDS_PER_PAGE 18
++
++#define TB_FIELD      1
++#define CB_FIELD      3
++#define BT_FIELD      5
++#define IO_FIELD      7
++#define ID_FIELD      8
++#define ME_FIELD      9
++#define TTY_FIELD     11
++#define CU_FIELD      13
++#define PR_FIELD      15
++#define MPR_FIELD     17
++
++#define       MAX_FIELD       512
++
++#define       INIT            0
++#define       NITEMS          128
++#define MAX_ITEM      512
++
++#define       DSCRINST        1
++#define       DSCRNUM         3
++#define       ALTPINQ         5
++#define       SSAVE           7
++
++#define       DSCR            "32"
++#define       ONETONINE       "123456789"
++#define       ALL             "1234567890"
++
++
++struct cnode {
++      struct cnode *next;
++      int type;
++      int numbrd;
++
++      union {
++              struct {
++                      char  type;     /* Board Type           */
++                      short port;     /* I/O Address          */
++                      char  *portstr; /* I/O Address in string */
++                      long  addr;     /* Memory Address       */
++                      char  *addrstr; /* Memory Address in string */
++                      char  nport;    /* Number of Ports      */
++                      char  *id;      /* tty id               */
++                      int   start;    /* start of tty counting */
++                      char  *method;  /* Install method       */
++                      char  v_type;
++                      char  v_port;
++                      char  v_addr;
++                      char  v_nport;
++                      char  v_id;
++                      char  v_start;
++                      char  v_method;
++                      char  line1;
++                      char  line2;
++                      char  conc1;   /* total concs in line1 */
++                      char  conc2;   /* total concs in line2 */
++                      char  module1; /* total modules for line1 */
++                      char  module2; /* total modules for line2 */
++                      char  *status; /* config status */
++                      char  *dimstatus;        /* Y/N */
++                      int   status_index; /* field pointer */
++              } board;
++
++              struct {
++                      char  *cable;
++                      char  v_cable;
++                      char  speed;
++                      char  v_speed;
++              } line;
++
++              struct {
++                      char  type;
++                      char  *connect;
++                      char  speed;
++                      char  nport;
++                      char  *id;
++                      char  *idstr;
++                      int   start;
++                      char  v_type;
++                      char  v_connect;
++                      char  v_speed;
++                      char  v_nport;
++                      char  v_id;
++                      char  v_start;
++              } conc;
++
++              struct {
++                      char type;
++                      char nport;
++                      char *id;
++                      char *idstr;
++                      int  start;
++                      char v_type;
++                      char v_nport;
++                      char v_id;
++                      char v_start;
++              } module;
++
++              char *ttyname;
++
++              char *cuname;
++
++              char *printname;
++
++              int  majornumber;
++
++              int  altpin;
++
++              int  ttysize;
++
++              int  chsize;
++
++              int  bssize;
++
++              int  unsize;
++
++              int  f2size;
++
++              int  vpixsize;
++
++              int  useintr;
++      } u;
++};
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_downld.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_downld.h        2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_downld.h     2003-09-27 11:38:20.947343904 +0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *      Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ */
++
++/*
++** downld.h
++**  - describes the interface between the user level download process
++**    and the concentrator download driver.
++*/
++
++#ifndef _DGAP_DOWNLD_H_
++#define _DGAP_DOWNLD_H_
++
++
++struct fepimg {
++    int type;                         /* board type */
++    int       len;                            /* length of image */
++    char fepimage[1];                 /* begining of image */
++};
++
++struct downldio {
++    unsigned int req_type;            /* FEP or concentrator */
++    unsigned int bdid;                        /* opaque board identifier */
++    union {
++      struct downld_t dl;             /* download structure */
++      struct fepimg   fi;             /* fep/bios image structure */
++    } image;
++};
++
++#define DIGI_DLREQ_GET        (('d'<<8) | 220)
++#define DIGI_DLREQ_SET        (('d'<<8) | 221)
++
++#define DIGI_DL_NUKE    (('d'<<8) | 222) /* Not really a dl request, but
++                                        dangerous enuff to not put in
++                                        digi.h */
++/* Packed bits of intarg for DIGI_DL_NUKE */
++#define DIGI_NUKE_RESET_ALL    (1 << 31)
++#define DIGI_NUKE_INHIBIT_POLLER (1 << 30)
++#define DIGI_NUKE_BRD_NUMB        0x0f
++
++
++
++#define       DLREQ_BIOS      0
++#define       DLREQ_FEP       1
++#define       DLREQ_CONC      2
++#define       DLREQ_CONFIG    3
++#define DLREQ_DEVCREATE 4
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_driver.c        2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.c     2003-09-27 11:38:20.950343448 +0800
+@@ -0,0 +1,1561 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *
++ *    NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
++ *
++ *    This is shared code between Digi's CVS archive and the
++ *    Linux Kernel sources.
++ *    Changing the source just for reformatting needlessly breaks
++ *    our CVS diff history.
++ *
++ *    Send any bug fixes/changes to:  Eng.Linux at digi dot com.
++ *    Thank you.
++ *
++ */
++
++char *dgap_version = "$Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $";
++
++/*
++ * Our driver specific include files.
++ */
++#include "dgap_driver.h"
++#include "dgap_proc.h"
++#include "dgap_pci.h"
++#include "dgap_fep5.h"
++#include "dgap_tty.h"
++#include "dgap_conf.h"
++#include "dgap_parse.h"
++#include "dgap_mgmt.h"
++
++
++/*
++ * Because this driver is supported on older versions of Linux
++ * as well, lets be safe, and just make sure on this one.
++ */
++#if defined(MODULE_LICENSE)
++      MODULE_LICENSE("GPL");
++#endif
++
++MODULE_AUTHOR("Digi International, http://www.digi.com");
++MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line");
++MODULE_SUPPORTED_DEVICE("dgap");
++
++/*
++ * insmod command line overrideable parameters
++ *
++ * NOTE: we use a set of macros to create the variables, which allows
++ * us to specify the variable type, name, initial value, and description.
++ */
++PARM_INT(debug,               0x00,           "Driver debugging level");
++PARM_INT(rawreadok,   1,              "Bypass flip buffers on input");
++PARM_INT(trcbuf_size, 0x100000,       "Debugging trace buffer size. 1M default.");
++
++/*
++ * A generic list of Product names, PCI Vendor ID, and PCI Device ID.
++ */
++struct board_id {
++      uint config_type;
++      uchar *name;
++      u16 vendor;
++      u16 device;
++      uint maxports;
++      u16 dpatype;
++};
++
++static struct board_id Ids[] =
++{
++      {       PPCM,                   PCI_DEVICE_XEM_NAME,    DIGI_VID,
++              PCI_DEVICE_XEM_DID,     64,                     (T_PCXM | T_PCLITE | T_PCIBUS)  },
++
++      {       PCX,                    PCI_DEVICE_CX_NAME,     DIGI_VID,
++              PCI_DEVICE_CX_DID,      128,                    (T_CX | T_PCIBUS)               },
++
++      {       PCX,                    PCI_DEVICE_CX_IBM_NAME, DIGI_VID,
++              PCI_DEVICE_CX_IBM_DID,128,                      (T_CX | T_PCIBUS)               },
++
++      {       PEPC,                   PCI_DEVICE_EPCJ_NAME,   DIGI_VID,
++              PCI_DEVICE_EPCJ_DID,    224,                    (T_EPC  | T_PCIBUS)             },
++
++      {       APORT2_920P,            PCI_DEVICE_920_2_NAME,  DIGI_VID,
++              PCI_DEVICE_920_2_DID,   2,                      (T_PCXR | T_PCLITE | T_PCIBUS)  },
++
++      {       APORT4_920P,            PCI_DEVICE_920_4_NAME,  DIGI_VID,
++              PCI_DEVICE_920_4_DID,   4,                      (T_PCXR | T_PCLITE | T_PCIBUS)  },
++
++      {       APORT8_920P,            PCI_DEVICE_920_8_NAME,  DIGI_VID,
++              PCI_DEVICE_920_8_DID,   8,                      (T_PCXR | T_PCLITE | T_PCIBUS)  },
++
++      {       PAPORT8,                PCI_DEVICE_XR_NAME,     DIGI_VID,
++              PCI_DEVICE_XR_DID,      8,                      (T_PCXR | T_PCLITE | T_PCIBUS)  },
++
++      {       PAPORT8,                PCI_DEVICE_XRJ_NAME,    DIGI_VID,
++              PCI_DEVICE_XRJ_DID,     8,                      (T_PCXR | T_PCLITE | T_PCIBUS)  },
++
++      {       PAPORT8,                PCI_DEVICE_XR_422_NAME, DIGI_VID,
++              PCI_DEVICE_XR_422_DID,8,                        (T_PCXR | T_PCLITE | T_PCIBUS)  },
++
++      {       PAPORT8,                PCI_DEVICE_XR_IBM_NAME, DIGI_VID,
++              PCI_DEVICE_XR_IBM_DID, 8,                       (T_PCXR | T_PCLITE | T_PCIBUS)  },
++
++};
++#define       NIDS    (sizeof(Ids)/sizeof(struct board_id))
++
++
++char *dgap_state_text[] = {
++      "Board Failed",
++      "Configuration for board not found.\n\t\t\t Use /usr/bin/dgap_config to configure board.",
++      "Board Found",
++      "Need Reset",
++      "Finished Reset",
++      "Need Config",
++      "Finished Config",
++      "Need Device Creation",
++      "Requested Device Creation",
++      "Finished Device Creation",
++      "Need BIOS Load",
++      "Requested BIOS",
++      "Doing BIOS Load",
++      "Finished BIOS Load",
++      "Need FEP Load",
++      "Requested FEP",
++      "Doing FEP Load",
++      "Finished FEP Load",
++      "Board READY",
++};
++
++char *dgap_driver_state_text[] = {
++      "Driver Initialized",
++      "Driver needs configuration load.",
++      "Driver requested configuration from download daemon.",
++      "Driver Ready."
++};
++
++
++/**************************************************************************
++ *
++ * protos for this file
++ *
++ */
++
++/* Driver load/unload functions */
++int                   dgap_init_module(void);
++void                  dgap_cleanup_module(void);
++int                   dgap_start(void);
++int                   dgap_finalize_board_init(struct board_t *brd);
++
++static void           dgap_init_globals(void);
++static int            dgap_scan(void);
++static int            dgap_found_board(struct pci_dev *pdev, int id);
++static void           dgap_cleanup_board(struct board_t *brd);
++static void           dgap_poll_handler(ulong dummy);
++
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++
++static irqreturn_t    dgap_intr(int irq, void *voidbrd, struct pt_regs *regs);
++module_init(dgap_init_module);
++module_exit(dgap_cleanup_module);
++
++#else
++
++static void           dgap_intr(int irq, void *voidbrd, struct pt_regs *regs);
++/*
++ * Older 2.4 kernels do not support module_init/exit calls.
++ * So we do it this way for now.
++ */
++int                   init_module(void);
++void                  cleanup_module(void);
++#define dgap_init_module init_module
++#define dgap_cleanup_module cleanup_module
++
++#endif
++
++
++/*
++ * File operations permitted on Control/Management major.
++ */
++static struct file_operations BoardFops =
++{
++      owner:          THIS_MODULE,
++      read:           NULL,
++      write:          NULL,
++      ioctl:          dgap_mgmt_ioctl,
++      mmap:           NULL,
++      open:           dgap_mgmt_open,
++      release:        dgap_mgmt_close
++};
++
++
++/*
++ * Statics/Globals
++ */
++struct board_t                *dgap_Board[MAXBOARDS];
++uchar                 dgap_NumBoards;
++spinlock_t            dgap_global_lock = SPIN_LOCK_UNLOCKED;
++ulong                 dgap_poll_counter = 0;
++static int            dgap_Major_Control_Registered = FALSE;
++int                   dgap_driver_state = DRIVER_INITIALIZED;
++
++spinlock_t            dgap_dl_lock = SPIN_LOCK_UNLOCKED;
++wait_queue_head_t     dgap_dl_wait;
++int                   dgap_dl_action;
++
++/* Poller stuff */
++static spinlock_t     dgap_poll_lock = SPIN_LOCK_UNLOCKED;    /* Poll scheduling lock */
++static ulong          dgap_poll_time;                         /* Time of next poll */
++static ulong          dgap_poll_tick = 20;                    /* Poll interval - 20 ms */
++static struct timer_list dgap_poll_timer = { function: dgap_poll_handler };
++
++static char           *dgap_config_buf;                       /* The config file buffer */
++
++
++/************************************************************************
++ *
++ * Driver load/unload functions
++ *
++ ************************************************************************/
++
++/*
++ * init_module()
++ *
++ * Module load.  This is where it all starts.
++ */
++int dgap_init_module(void)
++{
++      APR(("%s, Digi International Part Number %s\n", DG_NAME, DG_PART));
++      return dgap_start();
++}
++
++
++/*
++ * Start of driver.
++ */
++int dgap_start(void)
++{
++      int rc = 0;
++      unsigned long flags;
++
++        /* make sure that the globals are init'd before we do anything else */
++        dgap_init_globals();
++
++      dgap_NumBoards = 0;
++
++      APR(("For the tools package or updated drivers please visit http://www.digi.com\n"));
++
++      /*
++       * Register our base character device into the kernel.
++       * This allows the download daemon to connect to the downld device
++       * before any of the boards are init'ed.
++       */
++      if (!dgap_Major_Control_Registered) {
++              /*
++               * Register management/dpa devices
++               */
++              rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &BoardFops);
++              if (rc < 0) {
++                      APR(("Can't register dgap driver device (%d)\n", rc));
++                      return (rc);
++              }
++              dgap_Major_Control_Registered = TRUE;
++      }
++
++      /*
++       * Register our basic stuff in /proc/dgap
++       */
++      dgap_proc_register_basic_prescan();
++
++      /*
++       * Init any global tty stuff.
++       */
++      dgap_tty_preinit();
++
++      /*
++       * Find and configure all the cards
++       */
++      rc = dgap_scan();
++
++      /*
++       * If something went wrong in the scan, bail out of driver.
++       */
++      if (rc) {
++              dgap_cleanup_module();
++      }
++      else {
++              /* Start the poller */
++              if (dgap_NumBoards > 0) {
++                      DGAP_LOCK(dgap_poll_lock, flags);
++                      dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick);
++                      dgap_poll_timer.expires = dgap_poll_time;
++                      DGAP_UNLOCK(dgap_poll_lock, flags);
++
++                      add_timer(&dgap_poll_timer);
++
++              }
++
++              dgap_driver_state = DRIVER_NEED_CONFIG_LOAD;
++      }
++
++      return (rc);
++}
++
++
++
++int dgap_after_config_loaded(void)
++{
++      int i = 0;
++      int rc = 0;
++
++      /*
++       * Register our ttys, now that we have the config loaded.
++       */
++      for (i = 0; i < dgap_NumBoards; ++i) {
++
++              /*
++               * Initialize KME waitqueues...
++               */
++              init_waitqueue_head(&(dgap_Board[i]->kme_wait));
++
++              /*
++               * allocate flip buffer for board.
++               */
++              dgap_Board[i]->flipbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC);
++      }
++
++      dgap_proc_register_basic_postscan();
++
++      dgap_proc_register_fep();
++
++      return (rc);
++}
++
++
++
++/*
++ * dgap_cleanup_module()
++ *
++ * Module unload.  This is where it all ends.
++ */
++void dgap_cleanup_module(void)
++{
++      int i;
++      ulong lock_flags;
++
++      /* Turn off poller right away. */
++      DGAP_LOCK(dgap_poll_lock, lock_flags );
++      del_timer_sync( &dgap_poll_timer );
++      DGAP_UNLOCK(dgap_poll_lock, lock_flags );
++
++      dgap_proc_unregister_all();
++
++      if (dgap_Major_Control_Registered)
++              unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
++
++      if (dgap_config_buf)
++              kfree(dgap_config_buf);
++
++      for (i = 0; i < dgap_NumBoards; ++i) {
++              dgap_tty_uninit(dgap_Board[i]);
++              dgap_cleanup_board(dgap_Board[i]);
++      }
++
++      dgap_tty_post_uninit();
++
++#if defined(DGAP_TRACER)
++      /* last thing, make sure we release the tracebuffer */
++      dgap_tracer_free();
++#endif
++}
++
++
++/*
++ * dgap_cleanup_board()
++ *
++ * Free all the memory associated with a board
++ */
++static void dgap_cleanup_board(struct board_t *brd)
++{
++      int i = 0;
++
++        if(!brd || brd->magic != DGAP_BOARD_MAGIC)
++                return;
++
++      if (brd->intr_used && brd->irq)
++              free_irq(brd->irq, brd);
++
++      tasklet_kill(&brd->helper_tasklet);
++
++      if (brd->re_map_port) {
++              DGAP_IOUNMAP(brd->re_map_port);
++              brd->re_map_port = 0;
++      }
++
++      if (brd->re_map_membase) {
++              DGAP_IOUNMAP(brd->re_map_membase);
++              brd->re_map_membase = 0;
++      }
++
++        if (brd->msgbuf_head) {
++                unsigned long flags;
++
++                DGAP_LOCK(dgap_global_lock, flags);
++                brd->msgbuf = NULL;
++                printk(brd->msgbuf_head);
++                DGAP_VFREE(brd->msgbuf_head);
++                brd->msgbuf_head = NULL;
++                DGAP_UNLOCK(dgap_global_lock, flags);
++        }
++
++      /* Free all allocated channels structs */
++      for (i = 0; i < MAXPORTS ; i++) {
++              if (brd->channels[i]) {
++                      kfree(brd->channels[i]);
++                      brd->channels[i] = NULL;
++              }
++      }
++
++      if (brd->flipbuf)
++              kfree(brd->flipbuf);
++
++      dgap_Board[brd->boardnum] = NULL;
++
++        DGAP_VFREE(brd);
++}
++
++
++/*
++ * dgap_init_globals()
++ *
++ * This is where we initialize the globals from the static insmod
++ * configuration variables.  These are declared near the head of
++ * this file.
++ */
++static void dgap_init_globals(void)
++{
++      int i = 0;
++
++      dgap_rawreadok          = rawreadok;
++        dgap_trcbuf_size      = trcbuf_size;
++      dgap_debug              = debug;
++
++      for (i = 0; i < MAXBOARDS; i++) {
++              dgap_Board[i] = NULL;
++      }
++
++      init_timer( &dgap_poll_timer );
++
++      init_waitqueue_head(&dgap_dl_wait);
++      dgap_dl_action = 0;
++}
++
++
++/*
++ *      dgap_ioctl_name() : Returns a text version of each ioctl value.
++ */
++char *dgap_ioctl_name(int cmd)
++{
++      switch(cmd) {
++
++      case TCGETA:            return("TCGETA");
++      case TCGETS:            return("TCGETS");
++      case TCSETA:            return("TCSETA");
++      case TCSETS:            return("TCSETS");
++      case TCSETAW:           return("TCSETAW");
++      case TCSETSW:           return("TCSETSW");
++      case TCSETAF:           return("TCSETAF");
++      case TCSETSF:           return("TCSETSF");
++      case TCSBRK:            return("TCSBRK");
++      case TCXONC:            return("TCXONC");
++      case TCFLSH:            return("TCFLSH");
++      case TIOCGSID:          return("TIOCGSID");
++
++      case TIOCGETD:          return("TIOCGETD");
++      case TIOCSETD:          return("TIOCSETD");
++      case TIOCGWINSZ:        return("TIOCGWINSZ");
++      case TIOCSWINSZ:        return("TIOCSWINSZ");
++
++      case TIOCMGET:          return("TIOCMGET");
++      case TIOCMSET:          return("TIOCMSET");
++      case TIOCMBIS:          return("TIOCMBIS");
++      case TIOCMBIC:          return("TIOCMBIC");
++
++      /* from digi.h */
++      case DIGI_SETA:         return("DIGI_SETA");
++      case DIGI_SETAW:        return("DIGI_SETAW");
++      case DIGI_SETAF:        return("DIGI_SETAF");
++      case DIGI_SETFLOW:      return("DIGI_SETFLOW");
++      case DIGI_SETAFLOW:     return("DIGI_SETAFLOW");
++      case DIGI_GETFLOW:      return("DIGI_GETFLOW");
++      case DIGI_GETAFLOW:     return("DIGI_GETAFLOW");
++      case DIGI_GETA:         return("DIGI_GETA");
++      case DIGI_GEDELAY:      return("DIGI_GEDELAY");
++      case DIGI_SEDELAY:      return("DIGI_SEDELAY");
++#if 0
++      case DIGI_GETCUSTOMBAUD: return("DIGI_GETCUSTOMBAUD");
++      case DIGI_SETCUSTOMBAUD: return("DIGI_SETCUSTOMBAUD");
++#endif
++      case TIOCMODG:          return("TIOCMODG");
++      case TIOCMODS:          return("TIOCMODS");
++      case TIOCSDTR:          return("TIOCSDTR");
++      case TIOCCDTR:          return("TIOCCDTR");
++
++      default:                return("unknown");
++      }
++}
++
++
++
++void dgap_do_config_load(uchar *uaddr, int len)
++{
++      int orig_len = len;
++      char *to_addr;
++      char *from_addr = uaddr;
++      static char buf[U2BSIZE];
++      int n;
++
++      to_addr = dgap_config_buf = dgap_driver_kzmalloc(len + 1, GFP_ATOMIC);
++      if (!dgap_config_buf) {
++              DPR_INIT(("dgap_do_config_load - unable to allocate memory for file\n"));
++              dgap_driver_state = DRIVER_NEED_CONFIG_LOAD;
++              return;
++      }
++
++      n = U2BSIZE;
++      while (len) {
++
++              if (n > len)
++                      n = len;
++
++              if (copy_from_user((char *) &buf, from_addr, n) == -1 ) {
++                      /* TODO, SOMETHING SANE */
++                      return;
++              }
++
++              /* Copy data from buffer to kernel memory */
++              memcpy(to_addr, buf, n);
++
++              /* increment counts */
++              len -= n;
++              to_addr += n;
++              from_addr += n;
++              n = U2BSIZE;
++        }
++
++      dgap_config_buf[orig_len] = '\0';
++
++      to_addr = dgap_config_buf;
++      dgap_parsefile(&to_addr, TRUE);
++
++      DPR_INIT(("dgap_config_load() finish\n"));
++
++      return;
++}
++
++
++/*
++ * Remap PCI memory.
++ */
++static void dgap_do_remap(struct board_t *brd)
++{
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      brd->re_map_port = DGAP_IOREMAP((brd->membase + PCI_IO_OFFSET), 0x200000);
++      brd->re_map_membase = DGAP_IOREMAP(brd->membase, 0x200000);
++
++      DPR_INIT(("remapped io: 0x%p  remapped mem: 0x%p\n",
++              brd->re_map_port, brd->re_map_membase));
++}
++
++
++/*=======================================================================
++ *
++ *      usertoboard - copy from user space to board space.
++ *
++ *=======================================================================*/
++
++int dgap_usertoboard(struct board_t *brd, char *to_addr, char *from_addr, int len)
++{
++      static char buf[U2BSIZE];
++      int n = U2BSIZE;
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++              return(-EFAULT);
++
++      while (len) {
++              if (n > len)
++                      n = len;
++
++              if (copy_from_user((char *) &buf, from_addr, n) == -1 ) {
++                      return(-EFAULT);
++              }
++
++              /* Copy data from buffer to card memory */
++              memcpy_toio(to_addr, buf, n);
++
++              /* increment counts */
++              len -= n;
++              to_addr += n;
++              from_addr += n;
++              n = U2BSIZE;
++        }
++      return(0);
++}
++
++
++void dgap_do_bios_load(struct board_t *brd, uchar *ubios, int len)
++{
++      u32 bios;
++      uchar *addr = brd->re_map_membase;
++      int i;
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_INIT(("dgap_do_bios_load() start\n"));
++
++      /*
++       * clear POST area
++       */
++      for (i = 0; i < 16; i++)
++              writeb(0, addr + POSTAREA + i);
++
++      /*
++       * Download bios
++       */
++      bios = 0x1000;
++      if (dgap_usertoboard(brd, addr + bios, ubios, len) == -1 ) {
++              brd->state = BOARD_FAILED;
++              brd->dpastatus = BD_NOFEP;
++              return;
++      }
++
++      writel(0x0bf00401, addr);
++      writel(0, (addr + 4));
++
++      /* Clear the reset, and change states. */
++      writeb(FEPCLR, brd->re_map_port);
++      brd->state = WAIT_BIOS_LOAD;
++}
++
++
++static void dgap_do_wait_for_bios(struct board_t *brd)
++{
++      uchar *addr;
++      u16 word;
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      addr = brd->re_map_membase;
++      word = readw(addr + POSTAREA);
++
++      /* Check to see if BIOS thinks board is good. (GD). */
++      if (word == *(u16 *) "GD") {
++              DPR_INIT(("GOT GD in memory, moving states.\n"));
++              brd->state = FINISHED_BIOS_LOAD;
++              return;
++      }
++
++      /* Give up on board after too long of time taken */
++      if (brd->wait_for_bios++ > 5000) {
++              u16 err1 = readw(addr + SEQUENCE);
++              u16 err2 = readw(addr + ERROR);
++              APR(("***WARNING*** %s failed diagnostics.  Error #(%x,%x).\n",
++                      brd->name, err1, err2));
++              brd->state = BOARD_FAILED;
++              brd->dpastatus = BD_NOFEP;
++      }
++}
++
++void dgap_do_fep_load(struct board_t *brd, uchar *ufep, int len)
++{
++      u32 fepos;
++      uchar *addr;
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      addr = brd->re_map_membase;
++
++      DPR_INIT(("dgap_do_fep_load() for board %s : start\n", brd->name));
++
++      /*
++       * Download FEP
++       */
++
++      /* TODO: don't hard code this stuff */
++      fepos = 0x1000;
++
++      if (dgap_usertoboard(brd, addr + fepos, ufep, len) == -1 ) {
++              brd->state = BOARD_FAILED;
++              brd->dpastatus = BD_NOFEP;
++              return;
++      }
++
++      /*
++       * If board is a concentrator product, we need to give
++       * it its config string describing how the concentrators look.
++       */
++      if ((brd->type == PCX) || (brd->type == PEPC)) {
++              uchar string[100];
++              uchar *config, *xconfig;
++              int i = 0;
++
++              xconfig = dgap_create_config_string(brd, string);
++
++              /* Write string to board memory */
++              config = addr + CONFIG;
++              for (; i < CONFIGSIZE; i++, config++, xconfig++) {
++                      writeb(*xconfig, config);
++                      if ((*xconfig & 0xff) == 0xff)
++                              break;
++              }
++      }
++
++      writel(0xbfc01004, (addr + 0xc34));
++      writel(0x3, (addr + 0xc30));
++
++      /* change states. */
++      brd->state = WAIT_FEP_LOAD;
++
++      DPR_INIT(("dgap_do_fep_load() for board %s : finish\n", brd->name));
++
++}
++
++
++static void dgap_do_wait_for_fep(struct board_t *brd)
++{
++      uchar *addr;
++      u16 word;
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC) {
++              return;
++      }
++
++      addr = brd->re_map_membase;
++
++      if (!addr) {
++              APR(("dgap_do_wait_for_fep() addr is NULL\n"));
++              brd->state = BOARD_FAILED;
++              brd->dpastatus = BD_NOFEP;
++              return;
++      }
++
++      DPR_INIT(("dgap_do_wait_for_fep() for board %s : start. addr: %p\n", brd->name, addr));
++
++      word = readw(addr + FEPSTAT);
++
++      /* Check to see if FEP is up and running now. */
++      if (word == *(u16 *) "OS") {
++              DPR_INIT(("GOT OS in memory for board %s, moving states.\n", brd->name));
++              brd->state = FINISHED_FEP_LOAD;
++              return;
++      }
++
++      /* Give up on board after too long of time taken */
++      if (brd->wait_for_fep++ > 5000) {
++              u16 err1 = readw(addr + SEQUENCE);
++              u16 err2 = readw(addr + ERROR);
++              APR(("***WARNING*** FEPOS for %s not functioning.  Error #(%x,%x).\n",
++                      brd->name, err1, err2));
++              brd->state = BOARD_FAILED;
++              brd->dpastatus = BD_NOFEP;
++      }
++
++      DPR_INIT(("dgap_do_wait_for_fep() for board %s : finish\n", brd->name));
++}
++
++
++static void dgap_do_reset_board(struct board_t *brd)
++{
++      uchar check;
++      u32 check1;
++      u32 check2;
++      int i = 0;
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_INIT(("dgap_do_reset_board() start\n"));
++
++      /* FEPRST does not vary among supported boards */
++      writeb(FEPRST, brd->re_map_port);
++
++      for (i = 0; i <= 1000; i++) {
++              check = readb(brd->re_map_port) & 0xe;
++              if (check == FEPRST)
++                      break;
++              udelay(10);
++
++      }
++      if (i > 1000) {
++              APR(("*** WARNING *** Board not resetting...  Failing board.\n"));
++              brd->state = BOARD_FAILED;
++              brd->dpastatus = BD_NOFEP;
++              goto failed;
++      }
++
++      /*
++       * Make sure there really is memory out there.
++       */
++      writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM));
++      writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM));
++      check1 = readl(brd->re_map_membase + LOWMEM);
++      check2 = readl(brd->re_map_membase + HIGHMEM);
++
++      if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) {
++              APR(("*** Warning *** No memory at %p for board.\n", brd->re_map_membase));
++              brd->state = BOARD_FAILED;
++              brd->dpastatus = BD_NOFEP;
++              goto failed;
++      }
++
++      if (brd->state != BOARD_FAILED)
++              brd->state = FINISHED_RESET;
++
++failed:
++      DPR_INIT(("dgap_do_reset_board() finish\n"));
++}
++
++
++void dgap_do_conc_load(struct board_t *brd, uchar *uaddr, int len)
++{
++      char *vaddr;
++      u16 offset = 0;
++      struct downld_t *to_dp;
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      vaddr = brd->re_map_membase;
++
++      if (!vaddr)
++              return;
++
++      offset = readw((u16 *) (vaddr + DOWNREQ));
++      to_dp = (struct downld_t *) (vaddr + (int) offset);
++
++      memcpy_toio((char *) to_dp, uaddr, sizeof(struct downld_t));
++
++      /* Tell card we have data for it */
++      writew(0, vaddr + (DOWNREQ));
++
++      brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
++
++}
++
++
++/*
++ * Our board poller function.
++ */
++static void poll_tasklet(unsigned long data)
++{
++        struct board_t *bd = (struct board_t *) data;
++      ulong  lock_flags;
++      ulong  lock_flags2;
++      u32 head, tail;
++      char *vaddr;
++      u16 *chk_addr;
++      u16 check = 0;
++
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC) {
++              APR(("poll_tasklet() - NULL or bad bd.\n"));
++              return;
++      }
++
++      if (bd->inhibit_poller)
++              return;
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++
++      vaddr = bd->re_map_membase;
++
++      /*
++       * If board is ready, parse deeper to see if there is anything to do.
++       */
++      if (bd->state == BOARD_READY) {
++
++              struct ev_t *eaddr = NULL;
++
++              if (!bd->re_map_membase) {
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      return;
++              }
++              if (!bd->re_map_port) {
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      return;
++              }
++
++              if (!bd->nasync) {
++                      goto out;
++              }
++
++              /*
++               * If this is a CX or EPCX, we need to see if the firmware
++               * is requesting a concentrator image from us.
++               */
++              if ((bd->type == PCX) || (bd->type == PEPC)) {
++                      chk_addr = (u16 *) (vaddr + DOWNREQ);
++                      check = readw(chk_addr);
++                      /* Nonzero if FEP is requesting concentrator image. */
++                      if (check) {
++                              if (bd->conc_dl_status == NO_PENDING_CONCENTRATOR_REQUESTS)
++                                      bd->conc_dl_status = NEED_CONCENTRATOR;
++                              /*
++                               * Signal downloader, its got some work to do.
++                               */
++                              DGAP_LOCK(dgap_dl_lock, lock_flags2);
++                              if (dgap_dl_action != 1) {
++                                      dgap_dl_action = 1;
++                                      wake_up_interruptible(&dgap_dl_wait);
++                              }
++                              DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++
++                      }
++              }
++
++              eaddr = (struct ev_t *) (vaddr + EVBUF);
++
++              /* Get our head and tail */
++              head = readw(&(eaddr->ev_head));
++              tail = readw(&(eaddr->ev_tail));
++
++              /*
++               * If there is an event pending. Go service it.
++               */
++              if (head != tail) {
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      dgap_event(bd);
++                      DGAP_LOCK(bd->bd_lock, lock_flags);
++              }
++
++out:
++              /*
++               * If board is doing interrupts, ACK the interrupt.
++               */
++              if (bd && bd->intr_running) {
++                      readb(bd->re_map_port + 2);
++              }
++
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return;
++      }
++
++      /* Our state machine to get the board up and running */
++
++      /* Reset board */
++      if (bd->state == NEED_RESET) {
++              dgap_do_reset_board(bd);
++      }
++
++      /* Move to next state */
++      if (bd->state == FINISHED_RESET) {
++              bd->state = NEED_CONFIG;
++      }
++
++      if (bd->state == NEED_CONFIG) {
++              /*
++               * Match this board to a config the user created for us.
++               */
++              bd->bd_config = dgap_find_config(bd->type);
++
++              /*
++               * Register the ttys (if any) into the kernel.
++               */
++              if (bd->bd_config) {
++                      bd->state = FINISHED_CONFIG;
++              }
++              else {
++                      bd->state = CONFIG_NOT_FOUND;
++              }
++      }
++
++      /* Move to next state */
++      if (bd->state == FINISHED_CONFIG) {
++              bd->state = NEED_DEVICE_CREATION;
++      }
++
++      /* Move to next state */
++      if (bd->state == NEED_DEVICE_CREATION) {
++              /*
++               * Signal downloader, its got some work to do.
++               */
++              DGAP_LOCK(dgap_dl_lock, lock_flags2);
++              if (dgap_dl_action != 1) {
++                      dgap_dl_action = 1;
++                      wake_up_interruptible(&dgap_dl_wait);
++              }
++              DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++      }
++
++      /* Move to next state */
++      if (bd->state == FINISHED_DEVICE_CREATION) {
++              bd->state = NEED_BIOS_LOAD;
++      }
++
++      /* Move to next state */
++      if (bd->state == NEED_BIOS_LOAD) {
++              /*
++               * Signal downloader, its got some work to do.
++               */
++              DGAP_LOCK(dgap_dl_lock, lock_flags2);
++              if (dgap_dl_action != 1) {
++                      dgap_dl_action = 1;
++                      wake_up_interruptible(&dgap_dl_wait);
++              }
++              DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++      }
++
++      /* Wait for BIOS to test board... */
++      if (bd->state == WAIT_BIOS_LOAD) {
++              dgap_do_wait_for_bios(bd);
++      }
++
++      /* Move to next state */
++      if (bd->state == FINISHED_BIOS_LOAD) {
++              bd->state = NEED_FEP_LOAD;
++
++              /*
++               * Signal downloader, its got some work to do.
++               */
++              DGAP_LOCK(dgap_dl_lock, lock_flags2);
++              if (dgap_dl_action != 1) {
++                      dgap_dl_action = 1;
++                      wake_up_interruptible(&dgap_dl_wait);
++              }
++              DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++      }
++
++      /* Wait for FEP to load on board... */
++      if (bd->state == WAIT_FEP_LOAD) {
++              dgap_do_wait_for_fep(bd);
++      }
++
++      /* Move to next state */
++      if (bd->state == FINISHED_FEP_LOAD) {
++
++              /*
++               * Do tty device initialization.
++               */
++              int rc = dgap_tty_init(bd);
++              if (rc < 0) {
++                      dgap_tty_uninit(bd);
++                      APR(("Can't init tty devices (%d)\n", rc));
++                      bd->state = BOARD_FAILED;
++                      bd->dpastatus = BD_NOFEP;
++              }
++              else {
++                      bd->state = BOARD_READY;
++                      bd->dpastatus = BD_RUNNING;
++
++                      /*
++                       * If user requested the board to run in interrupt mode,
++                       * go and set it up on the board.
++                       */
++                      if (bd->intr_used) {
++                              writew(1, (bd->re_map_membase + ENABLE_INTR));
++                              /*
++                               * Tell the board to poll the UARTS as fast as possible.
++                               */
++                              writew(FEPPOLL_MIN, (bd->re_map_membase + FEPPOLL));
++                              bd->intr_running = 1;
++                      }
++              }
++      }
++
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++}
++
++
++/*****************************************************************************
++*
++* Function:
++*
++*    dgap_poll_handler
++*
++* Author:
++*
++*    Scott H Kilau
++*
++* Parameters:
++*
++*    dummy -- ignored
++*
++* Return Values:
++*
++*    none
++*
++* Description:
++*
++*    As each timer expires, it determines (a) whether the "transmit"
++*    waiter needs to be woken up, and (b) whether the poller needs to
++*    be rescheduled.
++*
++******************************************************************************/
++
++static void dgap_poll_handler(ulong dummy)
++{
++      int i;
++        struct board_t *brd;
++        unsigned long lock_flags;
++        unsigned long lock_flags2;
++
++      dgap_poll_counter++;
++
++
++      /*
++       * If driver needs the config file still,
++       * keep trying to wake up the downloader to
++       * send us the file.
++       */
++        if (dgap_driver_state == DRIVER_NEED_CONFIG_LOAD) {
++              /*
++               * Signal downloader, its got some work to do.
++               */
++              DGAP_LOCK(dgap_dl_lock, lock_flags2);
++              if (dgap_dl_action != 1) {
++                      dgap_dl_action = 1;
++                      wake_up_interruptible(&dgap_dl_wait);
++              }
++              DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
++              goto schedule_poller;
++        }
++      /*
++       * Do not start the board state machine until
++       * driver tells us its up and running, and has
++       * everything it needs.
++       */
++      else if (dgap_driver_state != DRIVER_READY) {
++              goto schedule_poller;
++      }
++
++      /*
++       * If we have just 1 board, or the system is not SMP,
++       * then use the typical old style poller.
++       * Otherwise, use our new tasklet based poller, which should
++       * speed things up for multiple boards.
++       */
++      if ( (dgap_NumBoards == 1) || (DGAP_NUM_CPUS <= 1) ) {
++              for (i = 0; i < dgap_NumBoards; i++) {
++
++                      brd = dgap_Board[i];
++
++                      if (brd->state == BOARD_FAILED) {
++                              continue;
++                      }
++                      if (!brd->intr_running) {
++                              /* Call the real board poller directly */
++                              poll_tasklet((unsigned long) brd);
++                      }
++              }
++      }
++      else {
++              /* Go thru each board, kicking off a tasklet for each if needed */
++              for (i = 0; i < dgap_NumBoards; i++) {
++                      brd = dgap_Board[i];
++
++                      /*
++                       * Attempt to grab the board lock.
++                       *
++                       * If we can't get it, no big deal, the next poll will get it.
++                       * Basically, I just really don't want to spin in here, because I want
++                       * to kick off my tasklets as fast as I can, and then get out the poller.
++                       */
++                      if (!spin_trylock(&brd->bd_lock)) {
++                              continue;
++                      }
++
++                      /* If board is in a failed state, don't bother scheduling a tasklet */
++                      if (brd->state == BOARD_FAILED) {
++                              spin_unlock(&brd->bd_lock);
++                              continue;
++                      }
++
++                      /* Schedule a poll helper task */
++                      if (!brd->intr_running) {
++                              tasklet_schedule(&brd->helper_tasklet);
++                      }
++
++                      /*
++                       * Can't do DGAP_UNLOCK here, as we don't have
++                       * lock_flags because we did a trylock above.
++                       */
++                      spin_unlock(&brd->bd_lock);
++              }
++      }
++
++schedule_poller:
++
++      /*
++       * Schedule ourself back at the nominal wakeup interval.
++       */
++      if (dgap_NumBoards > 0) {
++              ulong time;
++
++              DGAP_LOCK(dgap_poll_lock, lock_flags );
++              dgap_poll_time +=  dgap_jiffies_from_ms(dgap_poll_tick);
++
++              time = dgap_poll_time - jiffies;
++
++              if ((ulong) time >= 2 * dgap_poll_tick) {
++                      dgap_poll_time = jiffies +  dgap_jiffies_from_ms(dgap_poll_tick);
++              }
++
++              dgap_poll_timer.expires = dgap_poll_time;
++              DGAP_UNLOCK(dgap_poll_lock, lock_flags );
++
++              add_timer(&dgap_poll_timer);
++      }
++
++}
++
++
++/*
++ * dgap_scan()
++ *
++ * Scan for all boards
++ *
++ * Because of the way the PCI device list is scanned, we will always detect
++ * boards in the order that they are listed in the Ids table defined near the
++ * top of this file.
++ *
++ */
++static int dgap_scan(void)
++{
++      int id;
++      int rc = 0;
++        int i;
++
++      for (id = 0; id < NIDS; id++) {
++              struct pci_dev *pdev;
++
++              pdev = NULL;
++              while ((pdev = pci_find_device(Ids[id].vendor,
++                                             Ids[id].device, pdev))) {
++
++                      rc = dgap_found_board(pdev, id);
++                      if (rc == 0) {
++                                dgap_NumBoards++;
++                        }
++              }
++      }
++
++        for (i = 0; i < dgap_NumBoards ; i++) {
++                unsigned long flags;
++
++                if(!dgap_Board[i])
++                        continue;
++
++                DPR_INIT(("dgap_scan(%d) - printing out the msgbuf\n", i));
++                DGAP_LOCK(dgap_global_lock, flags);
++                dgap_Board[i]->msgbuf = NULL;
++                printk(dgap_Board[i]->msgbuf_head);
++                DGAP_VFREE(dgap_Board[i]->msgbuf_head);
++                dgap_Board[i]->msgbuf_head = NULL;
++                DGAP_UNLOCK(dgap_global_lock, flags);
++                if (rc) {
++                        dgap_cleanup_board(dgap_Board[i]);
++                        APR(("dgap_finalize_board_init failed - %d\n", rc));
++                }
++        }
++
++      if (!dgap_NumBoards) {
++                DPR_INIT(("dgap_scan() - returning ENODEV\n"));
++              return(-ENODEV);
++      } else {
++                DPR_INIT(("dgap_scan() - done\n"));
++              return(0);
++        }
++}
++
++
++/*
++ * dgap_found_board()
++ *
++ * A board has been found, init it.
++ */
++static int dgap_found_board(struct pci_dev *pdev, int id)
++{
++        struct board_t *brd;
++      DGAP_PCI_IRQ_TYPE pci_irq;
++      int i = 0;
++
++        /* get the board structure and prep it */
++        brd = dgap_Board[dgap_NumBoards] =
++        (struct board_t *) DGAP_VMALLOC(sizeof(struct board_t));
++        if (!brd) {
++                return(-ENOMEM);
++        }
++        memset(brd, 0, sizeof(struct board_t));
++
++        /* make a temporary message buffer for the boot messages */
++        brd->msgbuf = brd->msgbuf_head =
++                (char *) DGAP_VMALLOC(sizeof(char) * 8192);
++        if(!brd->msgbuf) {
++                DGAP_VFREE(brd);
++                return(-ENOMEM);
++        }
++        memset(brd->msgbuf_head, 0, sizeof(sizeof(char) * 8192));
++
++      /* store the info for the board we've found */
++      brd->magic = DGAP_BOARD_MAGIC;
++      brd->boardnum = dgap_NumBoards;
++      brd->firstminor = 0;
++      brd->vendor = Ids[id].vendor;
++      brd->device = Ids[id].device;
++      brd->name = Ids[id].name;
++      brd->maxports = Ids[id].maxports;
++      brd->type = Ids[id].config_type;
++      brd->dpatype = Ids[id].dpatype;
++      brd->dpastatus = BD_NOFEP;
++
++      DGAP_SPINLOCK_INIT(brd->bd_lock);
++
++      brd->state              = BOARD_FOUND;
++      brd->runwait            = 0;
++      brd->inhibit_poller     = FALSE;
++      brd->wait_for_bios      = 0;
++      brd->wait_for_fep       = 0;
++
++      for (i = 0; i < MAXPORTS; i++) {
++              brd->channels[i] = NULL;
++      }
++
++      /* store which card & revision we have */
++      pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor);
++      pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice);
++      pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev);
++
++      pci_irq = pdev->irq;
++      brd->irq = pci_irq;
++
++      /* get the PCI Base Address Registers */
++
++      /* Xr Jupiter and EPC use BAR 2 */
++      if (brd->device == PCI_DEVICE_XRJ_DID || brd->device == PCI_DEVICE_EPCJ_DID) {
++              brd->membase     = pci_resource_start(pdev, 2);
++              brd->membase_end = pci_resource_end(pdev, 2);
++      }
++      /* Everyone else uses BAR 0 */
++      else {
++              brd->membase     = pci_resource_start(pdev, 0);
++              brd->membase_end = pci_resource_end(pdev, 0);
++      }
++
++      if (brd->membase & 1)
++              brd->membase &= ~3;
++      else
++              brd->membase &= ~15;
++
++      /*
++       * On the PCI boards, there is no IO space allocated
++       * The I/O registers will be in the first 3 bytes of the
++       * upper 2MB of the 4MB memory space.  The board memory
++       * will be mapped into the low 2MB of the 4MB memory space
++       */
++      brd->port = brd->membase + PCI_IO_OFFSET;
++      brd->port_end = brd->port + PCI_IO_SIZE;
++
++
++      /*
++       * Special initialization for non-PLX boards
++       */
++      if (brd->device != PCI_DEVICE_XRJ_DID && brd->device != PCI_DEVICE_EPCJ_DID) {
++
++              pci_write_config_byte(pdev, 0x40, 0);
++              pci_write_config_byte(pdev, 0x46, 0);
++
++              /* Limit burst length to 2 doubleword transactions */
++              pci_write_config_byte(pdev, 0x42, 1);
++      }
++
++      /* init our poll helper tasklet */
++      tasklet_init(&brd->helper_tasklet, poll_tasklet, (unsigned long) brd);
++
++       /* Log the information about the board */
++      dgap_mbuf(brd, DRVSTR": board %d: %s (rev %d), irq %d\n",
++              dgap_NumBoards, brd->name, brd->rev, brd->irq);
++
++      dgap_do_remap(brd);
++
++      brd->state = NEED_RESET;
++
++        return(0);
++}
++
++
++int dgap_finalize_board_init(struct board_t *brd) {
++
++        int rc;
++
++        DPR_INIT(("dgap_finalize_board_init() - start\n"));
++
++      if (!brd || brd->magic != DGAP_BOARD_MAGIC)
++                return(-ENODEV);
++
++        DPR_INIT(("dgap_finalize_board_init() - start #2\n"));
++
++      brd->use_interrupts = dgap_config_get_useintr(brd);
++
++      /*
++       * Set up our interrupt handler if we are set to do interrupts.
++       */
++      if (brd->use_interrupts && brd->irq) {
++
++              rc = request_irq(brd->irq, dgap_intr, SA_SHIRQ, "DGAP", brd);
++
++              if (rc) {
++                      dgap_mbuf(brd, DRVSTR": Failed to hook IRQ %d. Board will work in poll mode.\n",
++                                  brd->irq);
++                      brd->intr_used = 0;
++              }
++              else
++                      brd->intr_used = 1;
++      } else {
++              brd->intr_used = 0;
++      }
++
++      return(0);
++}
++
++
++/*
++ * dgap_intr()
++ *
++ * Driver interrupt handler.
++ */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++static irqreturn_t dgap_intr(int irq, void *voidbrd, struct pt_regs *regs)
++#else
++static void dgap_intr(int irq, void *voidbrd, struct pt_regs *regs)
++#endif
++{
++      struct board_t *brd = (struct board_t *) voidbrd;
++
++      if (!brd) {
++              APR(("Received interrupt (%d) with null board associated\n", irq));
++              DGAP_IRQ_RETURN(IRQ_NONE);
++      }
++
++      /*
++       * Check to make sure its for us.
++       */
++      if (brd->magic != DGAP_BOARD_MAGIC) {
++              APR(("Received interrupt (%d) with a board pointer that wasn't ours!\n", irq));
++              DGAP_IRQ_RETURN(IRQ_NONE);
++      }
++
++      brd->intr_count++;
++
++      /*
++       * Schedule tasklet to run at a better time.
++       */
++      tasklet_schedule(&brd->helper_tasklet);
++
++      DGAP_IRQ_RETURN(IRQ_HANDLED);
++}
++
++
++/************************************************************************
++ *
++ * Utility functions
++ *
++ ************************************************************************/
++
++
++/*
++ * dgap_driver_kzmalloc()
++ *
++ * Malloc and clear memory,
++ */
++void *dgap_driver_kzmalloc(size_t size, int priority)
++{
++      void *p = kmalloc(size, priority);
++      if(p)
++              memset(p, 0, size);
++      return(p);
++}
++
++
++/*
++ * dgap_mbuf()
++ *
++ * Used to print to the message buffer during board init.
++ */
++void dgap_mbuf(struct board_t *brd, const char *fmt, ...) {
++      va_list         ap;
++      char            buf[1024];
++      int             i;
++      unsigned long   flags;
++
++      DGAP_LOCK(dgap_global_lock, flags);
++
++      /* Format buf using fmt and arguments contained in ap. */
++      va_start(ap, fmt);
++      i = vsprintf(buf, fmt,  ap);
++      va_end(ap);
++
++      DPR((buf));
++
++      if (!brd || !brd->msgbuf) {
++              printk(buf);
++              DGAP_UNLOCK(dgap_global_lock, flags);
++              return;
++      }
++
++      memcpy(brd->msgbuf, buf, strlen(buf));
++      brd->msgbuf += strlen(buf);
++      *brd->msgbuf = (char) NULL;
++
++      DGAP_UNLOCK(dgap_global_lock, flags);
++}
++
++
++
++/*
++ * dgap_sleep()
++ *
++ * Put the driver to sleep for "ticks" clock ticks
++ *
++ * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal.
++ */
++int dgap_sleep(int ticks)
++{
++      current->state = TASK_INTERRUPTIBLE;
++      if (HZ == 1000)
++              ticks *= 10;
++      schedule_timeout(ticks);
++      return (signal_pending(current));
++}
++
++
++/*
++ * dgap_ms_sleep()
++ *
++ * Put the driver to sleep for x ms's
++ *
++ * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal.
++ */
++int dgap_ms_sleep(u32 ms)
++{
++      current->state = TASK_INTERRUPTIBLE;
++      schedule_timeout((ms * HZ) / 1000);
++      return (signal_pending(current));
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_driver.h        2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_driver.h     2003-09-27 11:38:20.952343144 +0800
+@@ -0,0 +1,809 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *      Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ *************************************************************************
++ *
++ * Driver includes
++ *
++ *************************************************************************/
++
++#ifndef __DGAP_DRIVER_H
++#define __DGAP_DRIVER_H
++
++#define TRC_TO_CONSOLE 1
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/errno.h>
++#include <linux/socket.h>
++#include <linux/in.h>
++#include <linux/ioport.h>
++#include <linux/version.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <asm/irq.h>
++
++#include <linux/pci.h>
++
++#include <linux/major.h>
++#include <linux/signal.h>
++
++#include <linux/mm.h>
++
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <linux/stddef.h>
++#include <asm/atomic.h>
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/byteorder.h>
++#include <asm/system.h>
++
++#include <linux/tty.h>
++#include <linux/termios.h>
++#include <linux/poll.h>
++#include <linux/types.h>
++
++#include <linux/serial.h>     /* for struct async_serial */
++
++#include "dgap_types.h"               /* Additional types needed by header files */
++#include "digi.h"
++
++#include "dgap_pci.h"
++#include "dgap_fep5.h"
++#include "dgap_conf.h"
++
++/*************************************************************************
++ *
++ * Driver defines
++ *
++ *************************************************************************/
++
++/*
++ * Driver identification, error and debugging statments
++ *
++ * In theory, you can change all occurances of "digi" in the next
++ * three lines, and the driver printk's will all automagically change.
++ *
++ * APR((fmt, args, ...));     Always prints message
++ * DPR((fmt, args, ...));     Only prints if DGAP_TRACER is defined at
++ *                              compile time and dgap_debug!=0
++ */
++#define       PROCSTR         "dgap"                  /* /proc entries         */
++#define       DEVSTR          "/dev/dg/dgap"          /* /dev entries          */
++#define       DRVSTR          "dgap"                  /* Driver name string
++                                               * displayed by APR      */
++#define       APR(args)       do { PRINTF_TO_KMEM(args); printk(DRVSTR": "); printk args; \
++                         } while (0)
++#define       RAPR(args)      do { PRINTF_TO_KMEM(args); printk args; } while (0)
++
++/*
++ * Debugging levels can be set using debug insmod variable
++ * They can also be compiled out completely.
++ */
++
++#define       DBG_INIT                (dgap_debug & 0x01)
++#define       DBG_BASIC               (dgap_debug & 0x02)
++#define       DBG_CORE                (dgap_debug & 0x04)
++
++#define       DBG_OPEN                (dgap_debug & 0x08)
++#define       DBG_CLOSE               (dgap_debug & 0x10)
++#define       DBG_READ                (dgap_debug & 0x20)
++#define       DBG_WRITE               (dgap_debug & 0x40)
++
++#define       DBG_IOCTL               (dgap_debug & 0x80)
++
++#define       DBG_PROC                (dgap_debug & 0x100)
++#define       DBG_PARAM               (dgap_debug & 0x200)
++#define       DBG_PSCAN               (dgap_debug & 0x400)
++#define       DBG_EVENT               (dgap_debug & 0x800)
++
++#define       DBG_DRAIN               (dgap_debug & 0x1000)
++#define       DBG_CARR                (dgap_debug & 0x2000)
++
++#define       DBG_MGMT                (dgap_debug & 0x4000)
++
++
++#if defined(DGAP_TRACER)
++
++# if defined(TRC_TO_KMEM)
++/* Choose one: */
++#  define TRC_ON_OVERFLOW_WRAP_AROUND
++#  undef  TRC_ON_OVERFLOW_SHIFT_BUFFER
++# endif //TRC_TO_KMEM
++
++# define TRC_MAXMSG           1024
++# define TRC_OVERFLOW         "(OVERFLOW)"
++# define TRC_DTRC             "/usr/bin/dtrc"
++
++#if defined TRC_TO_CONSOLE
++#define PRINTF_TO_CONSOLE(args) { printk(DRVSTR": "); printk args; }
++#else //!defined TRACE_TO_CONSOLE
++#define PRINTF_TO_CONSOLE(args)
++#endif
++
++#if defined TRC_TO_KMEM
++#define PRINTF_TO_KMEM(args) dgap_tracef args
++#else //!defined TRC_TO_KMEM
++#define PRINTF_TO_KMEM(args)
++#endif
++
++#define       TRC(args)       { PRINTF_TO_KMEM(args); PRINTF_TO_CONSOLE(args) }
++
++# define DPR_INIT(ARGS)               if (DBG_INIT) TRC(ARGS)
++# define DPR_BASIC(ARGS)      if (DBG_BASIC) TRC(ARGS)
++# define DPR_CORE(ARGS)               if (DBG_CORE) TRC(ARGS)
++# define DPR_OPEN(ARGS)               if (DBG_OPEN)  TRC(ARGS)
++# define DPR_CLOSE(ARGS)      if (DBG_CLOSE)  TRC(ARGS)
++# define DPR_READ(ARGS)               if (DBG_READ)  TRC(ARGS)
++# define DPR_WRITE(ARGS)      if (DBG_WRITE) TRC(ARGS)
++# define DPR_IOCTL(ARGS)      if (DBG_IOCTL) TRC(ARGS)
++# define DPR_PROC(ARGS)               if (DBG_PROC)  TRC(ARGS)
++# define DPR_PARAM(ARGS)      if (DBG_PARAM)  TRC(ARGS)
++# define DPR_PSCAN(ARGS)      if (DBG_PSCAN)  TRC(ARGS)
++# define DPR_EVENT(ARGS)      if (DBG_EVENT)  TRC(ARGS)
++# define DPR_DRAIN(ARGS)      if (DBG_DRAIN)  TRC(ARGS)
++# define DPR_CARR(ARGS)               if (DBG_CARR)  TRC(ARGS)
++# define DPR_MGMT(ARGS)               if (DBG_MGMT)  TRC(ARGS)
++
++# define DPR(ARGS)            if (dgap_debug) TRC(ARGS)
++# define P(X)                 dgap_tracef(#X "=%p\n", X)
++# define X(X)                 dgap_tracef(#X "=%x\n", X)
++
++#else//!defined DGAP_TRACER
++
++#define PRINTF_TO_KMEM(args)
++# define TRC(ARGS)
++# define DPR_INIT(ARGS)
++# define DPR_BASIC(ARGS)
++# define DPR_CORE(ARGS)
++# define DPR_OPEN(ARGS)
++# define DPR_CLOSE(ARGS)
++# define DPR_READ(ARGS)
++# define DPR_WRITE(ARGS)
++# define DPR_IOCTL(ARGS)
++# define DPR_PROC(ARGS)
++# define DPR_PARAM(ARGS)
++# define DPR_PSCAN(ARGS)
++# define DPR_EVENT(ARGS)
++# define DPR_DRAIN(ARGS)
++# define DPR_CARR(ARGS)
++# define DPR_MGMT(ARGS)
++
++# define DPR(args)
++
++#endif//DGAP_TRACER
++
++/* Number of boards we support at once. */
++#define       MAXBOARDS       32
++#define       MAXPORTS        224
++#define MAXTTYNAMELEN 200
++
++/* Our 3 magic numbers for our board, channel and unit structs */
++#define DGAP_BOARD_MAGIC      0x5c6df104
++#define DGAP_CHANNEL_MAGIC    0x6c6df104
++#define DGAP_UNIT_MAGIC               0x7c6df104
++
++/* Serial port types */
++#define DGAP_SERIAL           0
++#define DGAP_PRINT            1
++
++#define       SERIAL_TYPE_NORMAL      1
++
++/* 4 extra for alignment play space */
++#define WRITEBUFLEN           ((4096) + 4)
++#define MYFLIPLEN             N_TTY_BUF_SIZE
++
++#define SBREAK_TIME 0x25
++#define U2BSIZE 0x400
++#define dgap_jiffies_from_ms(a) (((a) * HZ) / 1000)
++
++/*
++ * Our major for the mgmt devices.
++ *
++ * We can use 22, because Digi was allocated 22 and 23 for the epca driver.
++ * 22 has now become obsolete now that the "cu" devices have
++ * been removed from 2.6.
++ * Also, this *IS* the epca driver, just PCI only now.
++ */
++#ifndef DIGI_DGAP_MAJOR
++# define DIGI_DGAP_MAJOR         22
++#endif
++
++/*
++ * The parameters we use to define the periods of the moving averages.
++ */
++#define               MA_PERIOD       (HZ / 10)
++#define               SMA_DUR         (1 * HZ)
++#define               EMA_DUR         (1 * HZ)
++#define               SMA_NPERIODS    (SMA_DUR / MA_PERIOD)
++#define               EMA_NPERIODS    (EMA_DUR / MA_PERIOD)
++
++/*
++ * Define a local default termios struct. All ports will be created
++ * with this termios initially.  This is the same structure that is defined
++ * as the default in tty_io.c with the same settings overriden as in serial.c
++ *
++ * In short, this should match the internal serial ports' defaults.
++ */
++#define       DEFAULT_IFLAGS  (ICRNL | IXON)
++#define       DEFAULT_OFLAGS  (OPOST | ONLCR)
++#define       DEFAULT_CFLAGS  (B9600 | CS8 | CREAD | HUPCL | CLOCAL)
++#define       DEFAULT_LFLAGS  (ISIG | ICANON | ECHO | ECHOE | ECHOK | \
++                      ECHOCTL | ECHOKE | IEXTEN)
++
++
++/*************************************************************************
++ *
++ * Utility defines - should be defined elsewhere, but be paranoid
++ *
++ *************************************************************************/
++
++#if !defined(KERNEL_VERSION) /* defined in version.h in later kernels */
++# define KERNEL_VERSION(a,b,c)        (((a) << 16) + ((b) << 8) + (c))
++#endif
++
++/* The number of elements in an array */
++#if !defined(asizeof)
++# define asizeof(X)   (sizeof(X) / sizeof(X[0]))
++#endif
++
++/*
++ * All the possible states the driver can be while being loaded.
++ */
++enum {
++      DRIVER_INITIALIZED = 0,
++      DRIVER_NEED_CONFIG_LOAD,
++      DRIVER_REQUESTED_CONFIG,
++      DRIVER_READY
++};
++
++/*
++ * All the possible states the board can be while booting up.
++ */
++enum {
++      BOARD_FAILED = 0,
++      CONFIG_NOT_FOUND,
++      BOARD_FOUND,
++      NEED_RESET,
++      FINISHED_RESET,
++      NEED_CONFIG,
++      FINISHED_CONFIG,
++      NEED_DEVICE_CREATION,
++      REQUESTED_DEVICE_CREATION,
++      FINISHED_DEVICE_CREATION,
++      NEED_BIOS_LOAD,
++      REQUESTED_BIOS,
++      WAIT_BIOS_LOAD,
++      FINISHED_BIOS_LOAD,
++      NEED_FEP_LOAD,
++      REQUESTED_FEP,
++      WAIT_FEP_LOAD,
++      FINISHED_FEP_LOAD,
++      BOARD_READY
++};
++
++/*
++ * All the possible states that a requested concentrator image can be in.
++ */
++enum {
++      NO_PENDING_CONCENTRATOR_REQUESTS = 0,
++      NEED_CONCENTRATOR,
++      REQUESTED_CONCENTRATOR
++};
++
++extern char *dgap_state_text[];
++extern char *dgap_driver_state_text[];
++
++
++/*************************************************************************
++ *
++ * Some API's changed at linux version 2.1.x.  I'm not sure exactly
++ * when they changed during the 2.1.x development, but it doesn't
++ * matter to us.  Create some macros to preserve compatibility.
++ *
++ * Here you can see what has changed between 2.0 and 2.1+. If you
++ * are reading/writing this file, you should be well aware of these
++ * macros or you won't be able to follow whats going on.  The
++ * alternative was #ifdef spaghetti.
++ */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++# include <asm/irq.h>
++# include <asm/bitops.h>
++# include <asm/io.h>
++# include <asm/uaccess.h>
++# include <linux/gfp.h>
++
++# define DGAP_get_free_page(x)                (get_zeroed_page(GFP_ATOMIC))
++# define DGAP_VMALLOC(x)              (kmalloc((x), GFP_ATOMIC))
++# define DGAP_VFREE(x)                        (kfree(x))
++
++# define DGAP_MAJOR(x)                        (imajor(x))
++# define DGAP_MINOR(x)                        (iminor(x))
++# define DGAP_TTY_MAJOR(x)            (MAJOR(x))
++# define DGAP_TTY_MINOR(x)            (MINOR(x))
++
++# define DGAP_NUM_CPUS                        (num_online_cpus())
++
++# define DGAP_MOD_INC_USE_COUNT(rtn)  (rtn = 1)
++# define DGAP_MOD_DEC_USE_COUNT
++
++# define DGAP_IRQ_RETURN(x)           return x;
++
++
++# define DGAP_SPINLOCK_INIT(x)                spin_lock_init(&(x))
++
++# define DGAP_IOREMAP(ADDR, LEN)      ioremap(ADDR, LEN)
++# define DGAP_IOUNMAP(ADDR)           iounmap(ADDR)
++# define COPY_FROM_USER(DST,SRC,LEN)  copy_from_user(DST,SRC,LEN)
++# define COPY_TO_USER(DST,SRC,LEN)    copy_to_user(DST,SRC,LEN)
++# define GET_USER(A1,A2)              get_user(A1,(unsigned int *)A2)
++# define PUT_USER(A1,A2)              put_user(A1,(unsigned long *)A2)
++
++# define READ_PROTO   struct file *file, char *buf, size_t count,loff_t *ppos
++# define READ_ARGS    file, buf, count, ppos
++# define READ_RETURN_T        ssize_t
++
++# define WRITE_PROTO  struct file *file, const char *buf, size_t count, \
++                      loff_t *ppos
++# define WRITE_ARGS   file, buf, count, ppos
++# define WRITE_RETURN_T       ssize_t
++
++# define CLOSE_RETURN_T               int
++# define CLOSE_RETURN(X)      return(X)
++
++# define PARM_I_RDEV          file->f_dentry->d_inode->i_rdev
++# define GET_POS()            *ppos
++# define ADD_POS(AMT)         *ppos += (AMT)
++# define SET_POS(AMT)         *ppos = (AMT)
++
++# define DGAP_PCI_IRQ_TYPE    uint
++# define PCI_PRESENT()                pci_present()
++
++# define PARM_STR(VAR, INIT, DESC) \
++              static char *VAR = INIT; \
++              char *dgap_##VAR; \
++              MODULE_PARM(VAR, "s"); \
++              MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_INT(VAR, INIT, DESC) \
++              static int VAR = INIT; \
++              int dgap_##VAR; \
++              MODULE_PARM(VAR, "i"); \
++              MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_ULONG(VAR, INIT, DESC) \
++              static ulong VAR = INIT; \
++              ulong dgap_##VAR; \
++              MODULE_PARM(VAR, "l"); \
++              MODULE_PARM_DESC(VAR, DESC);
++
++# define DGAP_LOCK(x,y)               spin_lock_irqsave(&(x), y)
++# define DGAP_UNLOCK(x,y)     spin_unlock_irqrestore(&(x), y)
++//# define DGAP_LOCK(x,y)             spin_lock(&(x))
++//# define DGAP_UNLOCK(x,y)   spin_unlock(&(x))
++# define DGAP_TRYLOCK(x,y)    spin_trylock(&(x))
++
++# define DGAP_PROCID()                smp_processor_id()
++
++/*
++ *  In some revisions within the 2.4 kernel series, there is a patch
++ *  which changes the behavior of a failed open.  In 2.0 and 2.2 and
++ *  most 2.4 revisions, a failed open will be followed _always_ by
++ *  a call to the driver's close routine.  In some 2.4 revisions,
++ *  the close will not be called (and therefore driver use counts
++ *  will be too high, and ports may become unusable).
++ *
++ *  In the case that the ALT_FAIL_OPEN code is allowed to exist,
++ *  some new parameters are required, like ALT_FAIL_OPEN_DEFAULT.
++ */
++# define ALLOW_ALT_FAIL_OPEN 0
++# define ALT_FAIL_OPEN_DEFAULT 0
++
++
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++
++# include <asm/uaccess.h>
++
++# define DGAP_get_free_page(x)                (get_free_page(GFP_KERNEL))
++# define DGAP_VMALLOC(x)              (vmalloc(x))
++# define DGAP_VFREE(x)                        (vfree(x))
++
++# define DGAP_MAJOR(x)                        (MAJOR((x)->i_rdev))
++# define DGAP_MINOR(x)                        (MINOR((x)->i_rdev))
++# define DGAP_TTY_MAJOR(x)            (MAJOR(x))
++# define DGAP_TTY_MINOR(x)            (MINOR(x))
++
++# define DGAP_NUM_CPUS                        (smp_num_cpus)
++
++# define DGAP_MOD_INC_USE_COUNT(rtn) \
++      { \
++              MOD_INC_USE_COUNT; \
++              rtn = 1; \
++      }
++
++# define DGAP_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
++
++# define DGAP_IRQ_RETURN(x)   return;
++
++# define DGAP_SPINLOCK_INIT(x)                spin_lock_init(&(x))
++
++# define DGAP_IOREMAP(ADDR, LEN)      ioremap(ADDR, LEN)
++# define DGAP_IOUNMAP(ADDR)           iounmap(ADDR)
++# define COPY_FROM_USER(DST,SRC,LEN)  copy_from_user(DST,SRC,LEN)
++# define COPY_TO_USER(DST,SRC,LEN)    copy_to_user(DST,SRC,LEN)
++# define GET_USER(A1,A2)              get_user(A1,(unsigned int *)A2)
++# define PUT_USER(A1,A2)              put_user(A1,(unsigned long *)A2)
++
++# define READ_PROTO   struct file *file, char *buf, size_t count,loff_t *ppos
++# define READ_ARGS    file, buf, count, ppos
++# define READ_RETURN_T        ssize_t
++
++# define WRITE_PROTO  struct file *file, const char *buf, size_t count, \
++                      loff_t *ppos
++# define WRITE_ARGS   file, buf, count, ppos
++# define WRITE_RETURN_T       ssize_t
++
++# define CLOSE_RETURN_T               int
++# define CLOSE_RETURN(X)      return(X)
++
++# define PARM_I_RDEV          file->f_dentry->d_inode->i_rdev
++# define GET_POS()            *ppos
++# define ADD_POS(AMT)         *ppos += (AMT)
++# define SET_POS(AMT)         *ppos = (AMT)
++
++# define DGAP_PCI_IRQ_TYPE    uint
++# define PCI_PRESENT()                pci_present()
++
++# define PARM_STR(VAR, INIT, DESC) \
++              static char *VAR = INIT; \
++              char *dgap_##VAR; \
++              MODULE_PARM(VAR, "s"); \
++              MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_INT(VAR, INIT, DESC) \
++              static int VAR = INIT; \
++              int dgap_##VAR; \
++              MODULE_PARM(VAR, "i"); \
++              MODULE_PARM_DESC(VAR, DESC);
++
++# define PARM_ULONG(VAR, INIT, DESC) \
++              static ulong VAR = INIT; \
++              ulong dgap_##VAR; \
++              MODULE_PARM(VAR, "l"); \
++              MODULE_PARM_DESC(VAR, DESC);
++
++# define DGAP_LOCK(x,y)               spin_lock_irqsave(&(x), y);
++# define DGAP_UNLOCK(x,y)     spin_unlock_irqrestore(&(x), y);
++
++# define DGAP_PROCID()                smp_processor_id()
++
++/*
++ *  In some revisions within the 2.4 kernel series, there is a patch
++ *  which changes the behavior of a failed open.  In 2.0 and 2.2 and
++ *  most 2.4 revisions, a failed open will be followed _always_ by
++ *  a call to the driver's close routine.  In some 2.4 revisions,
++ *  the close will not be called (and therefore driver use counts
++ *  will be too high, and ports may become unusable).
++ *
++ *  In the case that the ALT_FAIL_OPEN code is allowed to exist,
++ *  some new parameters are required, like ALT_FAIL_OPEN_DEFAULT.
++ */
++# define ALLOW_ALT_FAIL_OPEN 1
++# define ALT_FAIL_OPEN_DEFAULT 0
++
++#else
++
++# error "this driver does not support anything below the 2.4 kernel series."
++
++#endif
++
++
++/*
++ * Modem line constants are defined as macros because DSR and
++ * DCD are swapable using the ditty altpin option.
++ */
++#define D_CD(ch)        ch->ch_cd       /* Carrier detect       */
++#define D_DSR(ch)       ch->ch_dsr      /* Data set ready       */
++#define D_RTS(ch)       DM_RTS          /* Request to send      */
++#define D_CTS(ch)       DM_CTS          /* Clear to send        */
++#define D_RI(ch)        DM_RI           /* Ring indicator       */
++#define D_DTR(ch)       DM_DTR          /* Data terminal ready  */
++
++
++/*************************************************************************
++ *
++ * Structures and closely related defines.
++ *
++ *************************************************************************/
++
++
++/*
++ * A structure to hold a statistics counter.  We also
++ * compute moving averages for this counter.
++ */
++struct macounter
++{
++      u32             cnt;    /* Total count */
++      ulong           accum;  /* Acuumulator per period */
++      ulong           sma;    /* Simple moving average */
++      ulong           ema;    /* Exponential moving average */
++};
++
++
++/*
++ *    Per-board information
++ */
++struct board_t
++{
++      int             magic;          /* Board Magic number.  */
++      int             boardnum;       /* Board number: 0-3 */
++      int             firstminor;     /* First minor, e.g. 0, 30, 60 */
++
++      int             type;           /* Type of board */
++      char            *name;          /* Product Name */
++      u16             vendor;         /* PCI vendor ID */
++      u16             device;         /* PCI device ID */
++      u16             subvendor;      /* PCI subsystem vendor ID */
++      u16             subdevice;      /* PCI subsystem device ID */
++      uchar           rev;            /* PCI revision ID */
++      u16             maxports;       /* MAX ports this board can handle */
++
++      spinlock_t      bd_lock;        /* Used to protect board */
++
++      u32             state;          /* State of card. */
++
++      struct          tasklet_struct helper_tasklet; /* Poll helper tasklet */
++
++      u32             wait_for_bios;
++      u32             wait_for_fep;
++
++      struct cnode *  bd_config;      /* Config of board */
++
++      u16             nasync;         /* Number of ports on card */
++
++      u32             use_interrupts; /* Should we be interrupt driven? */
++      u32             irq;            /* Interrupt request number */
++      u32             intr_count;     /* Count of interrupts */
++      u32             intr_used;      /* Non-zero if using interrupts */
++      u32             intr_running;   /* Non-zero if FEP knows its doing interrupts */
++
++      ulong           port;           /* Start of base io port of the card */
++      ulong           port_end;       /* End of base io port of the card */
++      ulong           membase;        /* Start of base memory of the card */
++      ulong           membase_end;    /* End of base memory of the card */
++
++      uchar           *re_map_port;   /* Remapped io port of the card */
++      uchar           *re_map_membase;/* Remapped memory of the card */
++
++      uchar           runwait;        /* # Processes waiting for FEP  */
++      uchar           inhibit_poller; /* Tells  the poller to leave us alone */
++
++      struct channel_t *channels[MAXPORTS]; /* array of pointers to our channels. */
++
++      struct tty_driver       SerialDriver;
++      char            SerialName[200];
++      struct tty_driver       PrintDriver;
++      char            PrintName[200];
++
++      u32             dgap_Major_Serial_Registered;
++      u32             dgap_Major_TransparentPrint_Registered;
++
++      u32             dgap_Serial_Major;
++      u32             dgap_TransparentPrint_Major;
++
++      u32             TtyRefCnt;
++
++      struct bs_t     *bd_bs;                 /* Base structure pointer       */
++
++      char    *flipbuf;               /* Our flip buffer, alloced if board is found */
++
++      u16             dpatype;        /* The board "type", as defined by DPA */
++      u16             dpastatus;      /* The board "status", as defined by DPA */
++      wait_queue_head_t kme_wait;     /* Needed for DPA support */
++
++      u32             conc_dl_status; /* Status of any pending conc download */
++      /*
++       *      Mgmt data.
++       */
++        char          *msgbuf_head;
++        char          *msgbuf;
++
++};
++
++
++
++/************************************************************************
++ * Unit flag definitions for un_flags.
++ ************************************************************************/
++#define UN_ISOPEN     0x0001          /* Device is open               */
++#define UN_CLOSING    0x0002          /* Line is being closed         */
++#define UN_IMM                0x0004          /* Service immediately          */
++#define UN_BUSY               0x0008          /* Some work this channel       */
++#define UN_BREAKI     0x0010          /* Input break received         */
++#define UN_PWAIT      0x0020          /* Printer waiting for terminal */
++#define UN_TIME               0x0040          /* Waiting on time              */
++#define UN_EMPTY      0x0080          /* Waiting output queue empty   */
++#define UN_LOW                0x0100          /* Waiting output low water mark*/
++#define UN_EXCL_OPEN  0x0200          /* Open for exclusive use       */
++#define UN_WOPEN      0x0400          /* Device waiting for open      */
++#define UN_WIOCTL     0x0800          /* Device waiting for open      */
++#define UN_HANGUP     0x8000          /* Carrier lost                 */
++
++
++/************************************************************************
++ * Structure for terminal or printer unit.
++ ************************************************************************/
++struct un_t {
++      int     magic;          /* Unit Magic Number.                   */
++      struct  channel_t *un_ch;
++      u32     un_time;
++      u32     un_type;
++      u32     un_open_count;  /* Counter of opens to port             */
++      struct tty_struct *un_tty;/* Pointer to unit tty structure      */
++      u32     un_flags;       /* Unit flags                           */
++      wait_queue_head_t un_flags_wait; /* Place to sleep to wait on unit */
++      u32     un_dev;         /* Minor device number                  */
++      tcflag_t un_oflag;      /* oflags being done on board           */
++      tcflag_t un_lflag;      /* lflags being done on board           */
++};
++
++
++/************************************************************************
++ * Device flag definitions for ch_flags.
++ ************************************************************************/
++#define CH_PRON         0x0001          /* Printer on string                */
++#define CH_OUT          0x0002          /* Dial-out device open             */
++#define CH_STOP         0x0004          /* Output is stopped                */
++#define CH_STOPI        0x0008          /* Input is stopped                 */
++#define CH_CD           0x0010          /* Carrier is present               */
++#define CH_FCAR         0x0020          /* Carrier forced on                */
++
++#define CH_RXBLOCK      0x0080          /* Enable rx blocked flag           */
++#define CH_WLOW         0x0100          /* Term waiting low event           */
++#define CH_WEMPTY       0x0200          /* Term waiting empty event         */
++#define CH_RENABLE      0x0400          /* Buffer just emptied          */
++#define CH_RACTIVE      0x0800          /* Process active in xxread()   */
++#define CH_RWAIT        0x1000          /* Process waiting in xxread()  */
++#define CH_HANGUP       0x8000                /* Hangup received                  */
++
++
++/************************************************************************
++ * Channel information structure.
++ ************************************************************************/
++struct channel_t {
++      int magic;                      /* Channel Magic Number         */
++      struct bs_t     *ch_bs;         /* Base structure pointer       */
++      struct cm_t     *ch_cm;         /* Command queue pointer        */
++      struct board_t *ch_bd;          /* Board structure pointer      */
++      unsigned char *ch_vaddr;        /* FEP memory origin            */
++      unsigned char *ch_taddr;        /* Write buffer origin          */
++      unsigned char *ch_raddr;        /* Read buffer origin           */
++      struct digi_t  ch_digi;         /* Transparent Print structure  */
++      struct un_t ch_tun;             /* Terminal unit info           */
++      struct un_t ch_pun;             /* Printer unit info            */
++
++      spinlock_t      ch_lock;        /* provide for serialization */
++      wait_queue_head_t ch_flags_wait;
++
++      u32     pscan_state;
++      uchar   pscan_savechar;
++
++      u32 ch_portnum;                 /* Port number, 0 offset.       */
++      u32 ch_open_count;              /* open count                   */
++      u32     ch_flags;               /* Channel flags                */
++
++
++      u32     ch_close_delay;         /* How long we should drop RTS/DTR for */
++
++      u32     ch_cpstime;             /* Time for CPS calculations    */
++
++      tcflag_t ch_c_iflag;            /* channel iflags               */
++      tcflag_t ch_c_cflag;            /* channel cflags               */
++      tcflag_t ch_c_oflag;            /* channel oflags               */
++      tcflag_t ch_c_lflag;            /* channel lflags               */
++
++      u16  ch_fepiflag;            /* FEP tty iflags               */
++      u16  ch_fepcflag;               /* FEP tty cflags               */
++      u16  ch_fepoflag;               /* FEP tty oflags               */
++      u16  ch_wopen;                  /* Waiting for open process cnt */
++      u16  ch_tstart;                 /* Transmit buffer start        */
++      u16  ch_tsize;                  /* Transmit buffer size         */
++      u16  ch_rstart;                 /* Receive buffer start         */
++      u16  ch_rsize;                  /* Receive buffer size          */
++      u16  ch_rdelay;                 /* Receive delay time           */
++
++      u16     ch_tlw;                 /* Our currently set low water mark */
++
++      u16  ch_cook;                   /* Output character mask        */
++
++      uchar   ch_card;                /* Card channel is on           */
++      uchar   ch_stopc;               /* Stop character               */
++      uchar   ch_startc;              /* Start character              */
++
++      uchar   ch_mostat;              /* FEP output modem status      */
++      uchar   ch_mistat;              /* FEP input modem status       */
++      uchar   ch_mforce;              /* Modem values to be forced    */
++      uchar   ch_mval;                /* Force values                 */
++      uchar   ch_fepstopc;            /* FEP stop character           */
++      uchar   ch_fepstartc;           /* FEP start character          */
++
++      uchar   ch_astopc;              /* Auxiliary Stop character     */
++      uchar   ch_astartc;             /* Auxiliary Start character    */
++      uchar   ch_fepastopc;           /* Auxiliary FEP stop char      */
++      uchar   ch_fepastartc;          /* Auxiliary FEP start char     */
++
++      uchar   ch_hflow;               /* FEP hardware handshake       */
++      uchar   ch_dsr;                 /* stores real dsr value        */
++      uchar   ch_cd;                  /* stores real cd value         */
++      uchar   ch_tx_win;              /* channel tx buffer window     */
++      uchar   ch_rx_win;              /* channel rx buffer window     */
++      u32  ch_info;                   /* Additional channel specific information */
++};
++
++
++/*************************************************************************
++ *
++ * Prototypes for non-static functions used in more than one module
++ *
++ *************************************************************************/
++
++int                   dgap_lock_poller(struct board_t *brd);
++void                  dgap_unlock_poller(struct board_t *brd);
++void                  dgap_mbuf(struct board_t *brd, const char *fmt, ...);
++int                   dgap_sleep(int ticks);
++int                   dgap_ms_sleep(u32 ms);
++
++int                   dgap_tty_brdinit(struct board_t *brd);
++void                  dgap_tty_brduninit(struct board_t *brd);
++
++void                  *dgap_driver_kzmalloc(size_t size, int priority);
++
++char                  *get_event_text(u32);
++char                  *get_msignal_text(u32);
++
++char                  *dgap_ioctl_name(int cmd);
++
++#if defined(DGAP_TRACER)
++void                  dgap_tracef(const char *fmt, ...);
++void                  dgap_tracer_free(void);
++#endif
++
++void                  dgap_proc_unregister_all(void);
++void                  dgap_proc_register_basic(void);
++int                     dgap_finalize_board_init(struct board_t *brd);
++
++void                  dgap_do_bios_load(struct board_t *brd, uchar *ubios, int len);
++void                  dgap_do_fep_load(struct board_t *brd, uchar *ufep, int len);
++void                  dgap_do_conc_load(struct board_t *brd, uchar *uaddr, int len);
++void                  dgap_do_config_load(uchar *uaddr, int len);
++
++int                   dgap_after_config_loaded(void);
++
++extern spinlock_t             dgap_dl_lock;
++extern wait_queue_head_t      dgap_dl_wait;
++extern int                    dgap_dl_action;
++
++extern int                    dgap_driver_state;
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_fep5.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_fep5.h  2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_fep5.h       2003-09-27 11:38:20.954342840 +0800
+@@ -0,0 +1,247 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ ************************************************************************
++ ***  FEP Version 5 dependent definitions
++ ************************************************************************/
++
++#ifndef __DGAP_FEP5_H
++#define __DGAP_FEP5_H
++
++#include "dgap_types.h"
++
++/************************************************************************
++ *      FEP memory offsets
++ ************************************************************************/
++#define START           0x0004L         /* Execution start address      */
++
++#define CMDBUF          0x0d10L         /* Command (cm_t) structure offset */
++#define CMDSTART        0x0400L         /* Start of command buffer      */
++#define CMDMAX          0x0800L         /* End of command buffer        */
++
++#define EVBUF           0x0d18L         /* Event (ev_t) structure       */
++#define EVSTART         0x0800L         /* Start of event buffer        */
++#define EVMAX           0x0c00L         /* End of event buffer          */
++#define FEP5_PLUS       0x0E40          /* ASCII '5' and ASCII 'A' is here  */
++#define ECS_SEG         0x0E44          /* Segment of the extended channel structure */
++#define LINE_SPEED      0x10            /* Offset into ECS_SEG for line speed   */
++                                        /* if the fep has extended capabilities */
++
++/* BIOS MAGIC SPOTS */
++#define ERROR           0x0C14L               /* BIOS error code              */
++#define SEQUENCE      0x0C12L         /* BIOS sequence indicator      */
++#define POSTAREA      0x0C00L         /* POST complete message area   */
++
++/* FEP MAGIC SPOTS */
++#define FEPSTAT         POSTAREA        /* OS here when FEP comes up    */
++#define NCHAN           0x0C02L         /* number of ports FEP sees     */
++#define PANIC           0x0C10L         /* PANIC area for FEP           */
++#define KMEMEM          0x0C30L         /* Memory for KME use           */
++#define CONFIG          0x0CD0L         /* Concentrator configuration info */
++#define CONFIGSIZE      0x0030          /* configuration info size      */
++#define DOWNREQ         0x0D00          /* Download request buffer pointer */
++
++#define CHANBUF         0x1000L         /* Async channel (bs_t) structs */
++#define FEPOSSIZE       0x1FFF          /* 8K FEPOS                     */
++
++#define XEMPORTS    0xC02     /*
++                               * Offset in board memory where FEP5 stores
++                               * how many ports it has detected.
++                               * NOTE: FEP5 reports 64 ports when the user
++                               * has the cable in EBI OUT instead of EBI IN.
++                               */
++
++#define FEPCLR      0x00
++#define FEPMEM      0x02
++#define FEPRST      0x04
++#define FEPINT      0x08
++#define FEPMASK     0x0e
++#define FEPWIN      0x80
++
++#define LOWMEM      0x0100
++#define HIGHMEM     0x7f00
++
++#define FEPTIMEOUT 200000
++
++#define ENABLE_INTR           0x0e04          /* Enable interrupts flag */
++#define FEPPOLL_MIN           1               /* minimum of 1 millisecond */
++#define FEPPOLL_MAX           20              /* maximum of 20 milliseconds */
++#define FEPPOLL                       0x0c26          /* Fep event poll interval */
++
++#define       IALTPIN                 0x0080          /* Input flag to swap DSR <-> DCD */
++
++/************************************************************************
++ * Command structure definition.
++ ************************************************************************/
++struct cm_t {
++      volatile unsigned short cm_head;        /* Command buffer head offset   */
++      volatile unsigned short cm_tail;        /* Command buffer tail offset   */
++      volatile unsigned short cm_start;       /* start offset of buffer       */
++      volatile unsigned short cm_max;         /* last offset of buffer        */
++};
++
++/************************************************************************
++ * Event structure definition.
++ ************************************************************************/
++struct ev_t {
++      volatile unsigned short ev_head;        /* Command buffer head offset   */
++      volatile unsigned short ev_tail;        /* Command buffer tail offset   */
++      volatile unsigned short ev_start;       /* start offset of buffer       */
++      volatile unsigned short ev_max;         /* last offset of buffer        */
++};
++
++/************************************************************************
++ * Download buffer structure.
++ ************************************************************************/
++struct downld_t {
++      uchar   dl_type;                /* Header                       */
++      uchar   dl_seq;                 /* Download sequence            */
++      ushort  dl_srev;                /* Software revision number     */
++      ushort  dl_lrev;                /* Low revision number          */
++      ushort  dl_hrev;                /* High revision number         */
++      ushort  dl_seg;                 /* Start segment address        */
++      ushort  dl_size;                /* Number of bytes to download  */
++      uchar   dl_data[1024];          /* Download data                */
++};
++
++/************************************************************************
++ * Per channel buffer structure
++ ************************************************************************
++ *              Base Structure Entries Usage Meanings to Host           *
++ *                                                                      *
++ *        W = read write        R = read only                           *
++ *        C = changed by commands only                                  *
++ *        U = unknown (may be changed w/o notice)                       *
++ ************************************************************************/
++struct bs_t {
++      volatile unsigned short  tp_jmp;        /* Transmit poll jump            */
++      volatile unsigned short  tc_jmp;        /* Cooked procedure jump         */
++      volatile unsigned short  ri_jmp;        /* Not currently used            */
++      volatile unsigned short  rp_jmp;        /* Receive poll jump             */
++
++      volatile unsigned short  tx_seg;        /* W  Tx segment         */
++      volatile unsigned short  tx_head;       /* W  Tx buffer head offset     */
++      volatile unsigned short  tx_tail;       /* R  Tx buffer tail offset     */
++      volatile unsigned short  tx_max;        /* W  Tx buffer size - 1         */
++
++      volatile unsigned short  rx_seg;        /* W  Rx segment                */
++      volatile unsigned short  rx_head;       /* W  Rx buffer head offset     */
++      volatile unsigned short  rx_tail;       /* R  Rx buffer tail offset     */
++      volatile unsigned short  rx_max;        /* W  Rx buffer size - 1         */
++
++      volatile unsigned short  tx_lw;         /* W  Tx buffer low water mark  */
++      volatile unsigned short  rx_lw;         /* W  Rx buffer low water mark  */
++      volatile unsigned short  rx_hw;         /* W  Rx buffer high water mark */
++      volatile unsigned short  incr;          /* W  Increment to next channel */
++
++      volatile unsigned short  fepdev;        /* U  SCC device base address    */
++      volatile unsigned short  edelay;        /* W  Exception delay            */
++      volatile unsigned short  blen;          /* W  Break length              */
++      volatile unsigned short  btime;         /* U  Break complete time       */
++
++      volatile unsigned short  iflag;         /* C  UNIX input flags          */
++      volatile unsigned short  oflag;         /* C  UNIX output flags         */
++      volatile unsigned short  cflag;         /* C  UNIX control flags        */
++      volatile unsigned short  wfill[13];     /* U  Reserved for expansion    */
++
++      volatile unsigned char   num;           /* U  Channel number            */
++      volatile unsigned char   ract;          /* U  Receiver active counter   */
++      volatile unsigned char   bstat;         /* U  Break status bits         */
++      volatile unsigned char   tbusy;         /* W  Transmit busy             */
++      volatile unsigned char   iempty;        /* W  Transmit empty event enable */
++      volatile unsigned char   ilow;          /* W  Transmit low-water event enable */
++      volatile unsigned char   idata;         /* W  Receive data interrupt enable */
++      volatile unsigned char   eflag;         /* U  Host event flags          */
++
++      volatile unsigned char   tflag;         /* U  Transmit flags            */
++      volatile unsigned char   rflag;         /* U  Receive flags             */
++      volatile unsigned char   xmask;         /* U  Transmit ready flags      */
++      volatile unsigned char   xval;          /* U  Transmit ready value      */
++      volatile unsigned char   m_stat;        /* RC Modem status bits          */
++      volatile unsigned char   m_change;      /* U  Modem bits which changed  */
++      volatile unsigned char   m_int;         /* W  Modem interrupt enable bits */
++      volatile unsigned char   m_last;        /* U  Last modem status         */
++
++      volatile unsigned char   mtran;         /* C   Unreported modem trans   */
++      volatile unsigned char   orun;          /* C   Buffer overrun occurred  */
++      volatile unsigned char   astartc;       /* W   Auxiliary Xon char       */
++      volatile unsigned char   astopc;        /* W   Auxiliary Xoff char      */
++      volatile unsigned char   startc;        /* W   Xon character             */
++      volatile unsigned char   stopc;         /* W   Xoff character           */
++      volatile unsigned char   vnextc;        /* W   Vnext character           */
++      volatile unsigned char   hflow;         /* C   Software flow control    */
++
++      volatile unsigned char   fillc;         /* U   Delay Fill character     */
++      volatile unsigned char   ochar;         /* U   Saved output character   */
++      volatile unsigned char   omask;         /* U   Output character mask    */
++
++      volatile unsigned char   bfill[13];     /* U   Reserved for expansion   */
++
++      volatile unsigned char   scc[16];       /* U   SCC registers            */
++};
++
++
++/************************************************************************
++ * FEP supported functions
++ ************************************************************************/
++#define SRLOW           0xe0            /* Set receive low water        */
++#define SRHIGH          0xe1            /* Set receive high water       */
++#define FLUSHTX         0xe2            /* Flush transmit buffer        */
++#define PAUSETX         0xe3            /* Pause data transmission      */
++#define RESUMETX        0xe4            /* Resume data transmission     */
++#define SMINT           0xe5            /* Set Modem Interrupt          */
++#define SAFLOWC         0xe6            /* Set Aux. flow control chars  */
++#define SBREAK          0xe8            /* Send break                   */
++#define SMODEM          0xe9            /* Set 8530 modem control lines */
++#define SIFLAG          0xea            /* Set UNIX iflags              */
++#define SFLOWC          0xeb            /* Set flow control characters  */
++#define STLOW           0xec            /* Set transmit low water mark  */
++#define RPAUSE          0xee            /* Pause recieve                */
++#define RRESUME         0xef            /* Resume receive               */
++#define BUFSETALL       0xf2            /* Set Tx & Rx buffer size avail*/
++#define SOFLAG          0xf3            /* Set UNIX oflags              */
++#define SHFLOW          0xf4            /* Set hardware handshake       */
++#define SCFLAG          0xf5            /* Set UNIX cflags              */
++#define SVNEXT          0xf6            /* Set VNEXT character          */
++#define SPINTFC         0xfc            /* Set VNEXT character          */
++
++
++/************************************************************************
++ *      Event flags.
++ ************************************************************************/
++#define IFBREAK         0x01            /* Break received               */
++#define IFTLW           0x02            /* Transmit low water           */
++#define IFTEM           0x04            /* Transmitter empty            */
++#define IFDATA          0x08            /* Receive data present         */
++#define IFMODEM         0x20            /* Modem status change          */
++
++/************************************************************************
++ *      Modem flags
++ ************************************************************************/
++#       define  DM_RTS          0x02    /* Request to send              */
++#       define  DM_CD           0x80    /* Carrier detect               */
++#       define  DM_DSR          0x20    /* Data set ready               */
++#       define  DM_CTS          0x10    /* Clear to send                */
++#       define  DM_RI           0x40    /* Ring indicator               */
++#       define  DM_DTR          0x01    /* Data terminal ready          */
++
++
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_mgmt.c  2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.c       2003-09-27 11:38:20.955342688 +0800
+@@ -0,0 +1,719 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *
++ *    NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
++ *
++ *    This is shared code between Digi's CVS archive and the
++ *    Linux Kernel sources.
++ *    Changing the source just for reformatting needlessly breaks
++ *    our CVS diff history.
++ *
++ *    Send any bug fixes/changes to:  Eng.Linux at digi dot com.
++ *    Thank you.
++ *
++ */
++
++/************************************************************************
++ *
++ * This file implements the mgmt functionality for the
++ * FEP5 based product lines.
++ *
++ ************************************************************************
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ */
++
++#define __NO_VERSION__
++#include "dgap_driver.h"
++#include <linux/ctype.h>
++#include "dgap_types.h"
++#include "dgap_fep5.h"
++#include "dgap_parse.h"
++#include "dgap_mgmt.h"
++#include "dgap_downld.h"
++#include "dgap_tty.h"
++
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++
++/*
++ * external variables
++ */
++extern int              dgap_debug;
++extern spinlock_t     dgap_global_lock;
++extern int            dgap_NumBoards;
++extern struct board_t *dgap_Board[];
++
++/* This holds the status of the KME buffer */
++static int            dgap_kmebusy = 0;
++
++/* Our "in use" variables, to enforce 1 open only */
++static int            dgap_mgmt_in_use = 0;
++static int            dgap_downld_in_use = 0;
++
++
++/*
++ * dgap_mgmt_open()
++ *
++ * Open the mgmt/downld/dpa device
++ */
++int dgap_mgmt_open(struct inode *inode, struct file *file)
++{
++      unsigned long lock_flags;
++      unsigned int minor = DGAP_MINOR(inode);
++
++      DPR_MGMT(("dgap_mgmt_open start.\n"));
++
++      DGAP_LOCK(dgap_global_lock, lock_flags);
++
++      /* mgmt device */
++      if (minor == MGMT_MGMT) {
++              /* Only allow 1 open at a time on mgmt device */
++              if (dgap_mgmt_in_use) {
++                      DGAP_UNLOCK(dgap_global_lock, lock_flags);
++                      return (-EBUSY);
++              }
++              dgap_mgmt_in_use++;
++      }
++      /* downld device */
++      else if (minor == MGMT_DOWNLD) {
++              /* Only allow 1 open at a time on downld device */
++              if (dgap_downld_in_use) {
++                      DGAP_UNLOCK(dgap_global_lock, lock_flags);
++                      return (-EBUSY);
++              }
++              dgap_downld_in_use++;
++      }
++      else {
++              DGAP_UNLOCK(dgap_global_lock, lock_flags);
++              return (-ENXIO);
++      }
++
++      DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++      DPR_MGMT(("dgap_mgmt_open finish.\n"));
++
++      return 0;
++}
++
++/*
++ * dgap_mgmt_close()
++ *
++ * Open the mgmt/dpa device
++ */
++int dgap_mgmt_close(struct inode *inode, struct file *file)
++{
++      unsigned long lock_flags;
++      unsigned int minor = DGAP_MINOR(inode);
++
++      DPR_MGMT(("dgap_mgmt_close start.\n"));
++
++      DGAP_LOCK(dgap_global_lock, lock_flags);
++
++      /* mgmt device */
++      if (minor == MGMT_MGMT) {
++              if (dgap_mgmt_in_use) {
++                      dgap_mgmt_in_use = 0;
++              }
++      }
++      /* downld device */
++      else if (minor == MGMT_DOWNLD) {
++              if (dgap_downld_in_use) {
++                      dgap_downld_in_use = 0;
++              }
++      }
++
++      DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++      DPR_MGMT(("dgap_mgmt_close finish.\n"));
++
++      return 0;
++}
++
++
++/*
++ * dgap_mgmt_ioctl()
++ *
++ * ioctl the mgmt/dpa device
++ */
++
++int dgap_mgmt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++{
++      unsigned long lock_flags;
++      int error = 0;
++      int i = 0;
++      struct board_t *brd;
++      static struct downldio dlio;
++
++      DPR_MGMT(("dgap_mgmt_ioctl start.\n"));
++
++      switch (cmd) {
++
++      case DIGI_DLREQ_GET:
++      {
++
++get_service:
++
++              DGAP_LOCK(dgap_global_lock, lock_flags);
++
++              if (dgap_driver_state == DRIVER_NEED_CONFIG_LOAD) {
++
++                      dgap_driver_state = DRIVER_REQUESTED_CONFIG;
++
++                      dlio.req_type = DLREQ_CONFIG;
++                      dlio.bdid = 0;
++                      dlio.image.fi.type = 0;
++
++                      DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++                      if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++                              DGAP_LOCK(dgap_global_lock, lock_flags);
++                              dgap_driver_state = DRIVER_NEED_CONFIG_LOAD;
++                              DGAP_UNLOCK(dgap_global_lock, lock_flags);
++                              return(-EFAULT);
++                      }
++
++                      return(0);
++              }
++
++              DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++              /*
++               * Loop thru each board.
++               * Check state, force state machine to start running.
++               */
++              for (i = 0; i < dgap_NumBoards; i++ ) {
++
++                      brd = dgap_Board[i];
++
++                      DGAP_LOCK(brd->bd_lock, lock_flags);
++
++                      switch (brd->state) {
++
++                      case NEED_DEVICE_CREATION:
++
++                              /*
++                               * Let go of lock, tty_register() (and us also)
++                               * does a non-atomic malloc, so it would be
++                               * possible to deadlock the system if the
++                               * malloc went to sleep.
++                               */
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                              dgap_tty_register(brd);
++                              DGAP_LOCK(brd->bd_lock, lock_flags);
++                              dgap_finalize_board_init(brd);
++
++                              brd->state = REQUESTED_DEVICE_CREATION;
++
++                              dlio.req_type = DLREQ_DEVCREATE;
++                              dlio.bdid = i;
++                              dlio.image.fi.type = brd->dpatype;
++
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++                              if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++                                      DGAP_LOCK(brd->bd_lock, lock_flags);
++                                      brd->state = NEED_DEVICE_CREATION;
++                                      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                                      return(-EFAULT);
++                              }
++
++                              return(0);
++
++                      case NEED_BIOS_LOAD:
++
++                              brd->state = REQUESTED_BIOS;
++
++                              dlio.req_type = DLREQ_BIOS;
++                              dlio.bdid = i;
++                              dlio.image.fi.type = brd->dpatype;
++
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                              if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++                                      DGAP_LOCK(brd->bd_lock, lock_flags);
++                                      brd->state = NEED_BIOS_LOAD;
++                                      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                                      return(-EFAULT);
++                              }
++
++                              return(0);
++
++                      case NEED_FEP_LOAD:
++                              brd->state = REQUESTED_FEP;
++
++                              dlio.req_type = DLREQ_FEP;
++                              dlio.bdid = i;
++                              dlio.image.fi.type = brd->dpatype;
++
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++                              if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++                                      DGAP_LOCK(brd->bd_lock, lock_flags);
++                                      brd->state = NEED_FEP_LOAD;
++                                      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                                      return(-EFAULT);
++                              }
++                              return(0);
++
++                      default:
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                              break;
++
++                      }
++
++                      DGAP_LOCK(brd->bd_lock, lock_flags);
++
++                      switch (brd->conc_dl_status) {
++
++                      case NEED_CONCENTRATOR:
++                      {
++                              u16 offset = 0;
++                              char *vaddr;
++                              struct downld_t *to_dp;
++
++                              vaddr = brd->re_map_membase;
++                              if (!vaddr) {
++                                      brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
++                                      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                                      break;
++                              }
++
++                              dlio.req_type = DLREQ_CONC;
++                              dlio.bdid = i;
++
++                              offset = readw((u16 *) (vaddr + DOWNREQ));
++                              to_dp = (struct downld_t *) (vaddr + (int) offset);
++
++                              if (!to_dp) {
++                                      brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
++                                      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                                      break;
++                              }
++
++                              memcpy(&dlio.image.dl, to_dp, sizeof(struct downld_t));
++
++                              brd->conc_dl_status = REQUESTED_CONCENTRATOR;
++
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++                              if (copy_to_user((void *) arg, &dlio, sizeof(struct downldio))) {
++                                      DGAP_LOCK(brd->bd_lock, lock_flags);
++                                      brd->conc_dl_status = NEED_CONCENTRATOR;
++                                      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                                      return(-EFAULT);
++                              }
++
++                              return(0);
++                      }
++
++                      default:
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                              break;
++                      }
++              }
++
++              /*
++               * Go to sleep waiting for the driver to signal an event to us.
++               */
++              error = wait_event_interruptible(dgap_dl_wait, (dgap_dl_action));
++
++              DGAP_LOCK(dgap_dl_lock, lock_flags);
++              dgap_dl_action = 0;
++              DGAP_UNLOCK(dgap_dl_lock, lock_flags);
++
++              /* Break out of ioctl if user cancelled us */
++              if (error)
++                      break;
++
++              goto get_service;
++
++      }
++
++      case DIGI_DLREQ_SET:
++      {
++              uchar *uaddr = NULL;
++
++              if (copy_from_user((char *) &dlio, (char *) arg, sizeof(struct downldio))) {
++                      return (-EFAULT);
++              }
++
++              if (dlio.req_type == DLREQ_CONFIG) {
++
++                      uaddr = (uchar *) arg +
++                              (int) ( ((struct downldio *)0)->image.fi.fepimage);
++
++                      dgap_do_config_load(uaddr, dlio.image.fi.len);
++                      dgap_after_config_loaded();
++
++                      DGAP_LOCK(dgap_global_lock, lock_flags);
++                      dgap_driver_state = DRIVER_READY;
++                      DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++                      break;
++
++              }
++
++              if (dlio.bdid < 0 || dlio.bdid > dgap_NumBoards) {
++                      return(-ENXIO);
++                }
++
++              brd = dgap_Board[dlio.bdid];
++
++              switch(dlio.req_type) {
++
++              case DLREQ_BIOS:
++                      if (brd->state == BOARD_FAILED || brd->state == BOARD_READY) {
++                              break;
++                      }
++
++                      if (dlio.image.fi.type == -1) {
++                              DGAP_LOCK(brd->bd_lock, lock_flags);
++                              brd->state = BOARD_FAILED;
++                              brd->dpastatus = BD_NOBIOS;
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                              break;
++                      }
++
++
++                      uaddr = (uchar *) arg +
++                              (int) ( ((struct downldio *)0)->image.fi.fepimage);
++
++                      dgap_do_bios_load(brd, uaddr, dlio.image.fi.len);
++
++                      break;
++              case DLREQ_FEP:
++                      if (brd->state == BOARD_FAILED || brd->state == BOARD_READY) {
++                               break;
++                      }
++
++                      if (dlio.image.fi.type == -1) {
++                              DGAP_LOCK(brd->bd_lock, lock_flags);
++                              brd->state = BOARD_FAILED;
++                              brd->dpastatus = BD_NOBIOS;
++                              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++                              break;
++                      }
++
++                      uaddr = (uchar *) arg +
++                              (int) ( ((struct downldio *)0)->image.fi.fepimage);
++
++                      dgap_do_fep_load(brd, uaddr, dlio.image.fi.len);
++
++                      break;
++
++              case DLREQ_CONC:
++
++                      if (brd->state == BOARD_FAILED) {
++                               break;
++                      }
++
++                      if (dlio.image.fi.type == -1) {
++                              break;
++                      }
++
++                      uaddr = (char *) &dlio.image.dl;
++                      dgap_do_conc_load(brd, uaddr, sizeof(struct downld_t));
++
++                      break;
++
++              case DLREQ_DEVCREATE:
++                      if (brd->state == BOARD_FAILED || brd->state == BOARD_READY) {
++                               break;
++                      }
++
++                      DGAP_LOCK(brd->bd_lock, lock_flags);
++                      brd->state = FINISHED_DEVICE_CREATION;
++                      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++                      break;
++
++              }
++
++              break;
++      }
++
++
++      case DIGI_GETDD:
++      {
++              /*
++               * This returns the total number of boards
++               * in the system, as well as driver version
++               * and has space for a reserved entry
++               */
++              struct digi_dinfo ddi;
++
++              DGAP_LOCK(dgap_global_lock, lock_flags);
++
++              ddi.dinfo_nboards = dgap_NumBoards;
++              sprintf(ddi.dinfo_version, "%s", DG_PART);
++
++              DGAP_UNLOCK(dgap_global_lock, lock_flags);
++
++              DPR_MGMT(("DIGI_GETDD returning numboards: %lu version: %s\n",
++                      ddi.dinfo_nboards, ddi.dinfo_version));
++
++              copy_to_user((char *) arg, &ddi, sizeof (ddi));
++              break;
++      }
++
++      case DIGI_GETBD:
++      {
++              int brd;
++              int error = 0;
++
++              struct digi_info di;
++
++              if (copy_from_user(&brd, (unsigned int *) arg, sizeof(int))) {
++                      return(-EFAULT);
++              }
++
++              if ((error = verify_area(VERIFY_WRITE, (char*) arg, sizeof(di)))) {
++                      return (error);
++              }
++
++              DPR_MGMT(("DIGI_GETBD asking about board: %d\n", brd));
++
++              if ((brd < 0) || (brd > dgap_NumBoards) || (dgap_NumBoards == 0))
++                      return (-ENODEV);
++
++              memset(&di, 0, sizeof(di));
++
++              di.info_bdnum = brd;
++
++              DGAP_LOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++              di.info_bdtype = dgap_Board[brd]->dpatype;
++              di.info_bdstate = dgap_Board[brd]->dpastatus;
++              di.info_ioport = (ulong) dgap_Board[brd]->port;
++              di.info_physaddr = (ulong) dgap_Board[brd]->membase;
++              di.info_physsize = (ulong) dgap_Board[brd]->membase - dgap_Board[brd]->membase_end;
++              if (dgap_Board[brd]->state != BOARD_FAILED)
++                      di.info_nports = dgap_Board[brd]->nasync;
++              else
++                      di.info_nports = 0;
++
++              DGAP_UNLOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++              DPR_MGMT(("DIGI_GETBD returning type: %x state: %x ports: %x size: %lx\n",
++                      di.info_bdtype, di.info_bdstate, di.info_nports, di.info_physsize));
++
++              copy_to_user((char *) arg, &di, sizeof (di));
++              break;
++      }
++
++      case DIGI_KME:
++      {
++              int itmp, jtmp;
++              unchar *memaddr = NULL;
++              struct rw_t kme;
++              struct rw_t *mp = NULL;
++              int brd = 0;
++              struct board_t *bd;
++
++              /* This ioctl takes an argument of type 'rw_t'
++               * and uses it to interact with the KME struct
++               * located on the digiboard itself.
++               */
++              if ((error = verify_area(VERIFY_READ, (char*)arg, sizeof(kme))))
++                      return(error);
++
++              copy_from_user(&kme, (char*)arg, sizeof(kme));
++
++              if (kme.rw_size > 128)
++                      kme.rw_size = 128;
++
++              brd = kme.rw_board;
++
++              DPR_MGMT(("dgap_mgmt: DIGI_KME: %s asked for board %d\n", current->comm, brd));
++
++              /* Sanity Checking... */
++              if ((brd < 0) || (brd > dgap_NumBoards) || (dgap_NumBoards == 0))
++                      return (-ENODEV);
++
++              bd = dgap_Board[brd];
++
++              DGAP_LOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++              if (bd->state != BOARD_READY) {
++                      DGAP_UNLOCK(dgap_Board[brd]->bd_lock, lock_flags);
++                      return(-ENODEV);
++              }
++
++              memaddr = bd->re_map_membase;
++
++              DGAP_UNLOCK(dgap_Board[brd]->bd_lock, lock_flags);
++
++              /* If the concentrator number is 0... */
++              if (kme.rw_conc == 0 && kme.rw_addr < 0x100000) {
++                      int page = 0;
++                      int addr = kme.rw_addr;
++                      int size = kme.rw_size;
++                      caddr_t data = (caddr_t) kme.rw_data;
++
++                      while ((itmp = size)) {
++
++                              switch (kme.rw_req) {
++                              case RW_READ:
++                              {
++                                      register caddr_t cp1 = (char *)memaddr + addr;
++                                      register caddr_t cp2 = kme.rw_data;
++
++                                      DPR_MGMT(("RW_READ CARDMEM - page=%d rw_addr=0x%lx  rw_size=%x\n",
++                                              page, kme.rw_addr, kme.rw_size));
++
++                                      for (jtmp = 0; jtmp < itmp; jtmp++) {
++                                              *cp2++ = readb(cp1++);
++                                      }
++                              }
++
++                              break;
++
++                              case RW_WRITE:
++                              {
++                                      register caddr_t cp1 = memaddr + addr;
++                                      register caddr_t cp2 = data;
++
++                                      DPR_MGMT(("RW_WRITE CARDMEM - page=%d rw_addr=0x%lx rw_size=%d\n",
++                                              page, kme.rw_addr, kme.rw_size));
++
++                                      for (jtmp = 0; jtmp < itmp; jtmp++) {
++                                              writeb(*cp2++, cp1++);
++                                      }
++                              }
++                              break;
++                              }
++
++                              addr += itmp;
++                              data += itmp;
++                              size -= itmp;
++
++                      }
++
++              }
++              else {
++
++                      /*
++                       * Read/Write memory in a REMOTE CONCENTRATOR..
++                       * There is only 1 buffer, so do mutual
++                       * exclusion to make sure only one KME
++                       * request is pending...
++                       */
++
++                      mp = (struct rw_t *) (memaddr + KMEMEM);
++
++                      while (dgap_kmebusy != 0) {
++                              dgap_kmebusy = 2;
++                              error = wait_event_interruptible(bd->kme_wait, (!dgap_kmebusy));
++                              if (error)
++                                      goto endkme;
++                      }
++
++                      dgap_kmebusy = 1;
++
++                      /* Copy KME request to the board.. */
++
++                      mp->rw_board = kme.rw_board;
++                      mp->rw_conc  = kme.rw_conc;
++                      mp->rw_reserved = kme.rw_reserved;
++                      memcpy(&mp->rw_addr, &kme.rw_addr, sizeof(int));
++                      memcpy(&mp->rw_size, &kme.rw_size, sizeof(short));
++
++                      if(kme.rw_req == RW_WRITE) {
++                              register caddr_t cp1 = (caddr_t) mp->rw_data;
++                              register caddr_t cp2 = (caddr_t) kme.rw_data;
++
++                              DPR_MGMT(("RW_WRITE CONCMEM - rw_addr=0x%lx  rw_size=%d\n",
++                                      kme.rw_addr, kme.rw_size));
++
++                              for (jtmp = 0; jtmp < (int) kme.rw_size; jtmp++) {
++                                      writeb(*cp2++, cp1++);
++                              }
++                      }
++
++                      /* EXECUTE REQUEST */
++
++                      mp->rw_req = kme.rw_req;
++
++                      /*
++                       * Wait for the board to process the
++                       * request, but limit the wait to 2 secs
++                       */
++
++                      for (itmp = jiffies + (2 * HZ); mp->rw_req;) {
++                              if(jiffies >= itmp) {
++                                      error = ENXIO;
++                                      /* Set request back to 0.. */
++                                      mp->rw_req = 0;
++                                      goto endkme;
++                              }
++
++                              schedule_timeout(HZ / 10);
++                      }
++
++                      /*
++                       * Since this portion of code is looksee
++                       * ported from the HPUX EMUX code, i'm
++                       * leaving OUT a portion of that code where
++                       * the HP/UX code actually puts the process
++                       * to sleep for some reason
++                       */
++                      if (mp->rw_size < kme.rw_size)
++                              memcpy(&kme.rw_size, &mp->rw_size, sizeof(short));
++
++                      /* Copy the READ data back to the source buffer... */
++                      if (kme.rw_req == RW_READ) {
++                              register caddr_t cp1 = (caddr_t) mp->rw_data;
++                              register caddr_t cp2 = (caddr_t) kme.rw_data;
++
++                              DPR_MGMT(("RW_READ CONCMEM - rw_addr=0x%lx  rw_size=%d\n",
++                                      kme.rw_addr, kme.rw_size));
++
++                              for (jtmp = 0; jtmp < (int) kme.rw_size; jtmp++) {
++                                      *cp2++ = readb(cp1++);
++                              }
++                      }
++
++                      /*
++                       * Common exit point for code sharing the
++                       * kme buffer. Before exiting, always wake
++                       * another process waiting for the buffer
++                       */
++
++              endkme:
++
++                      if (dgap_kmebusy != 1)
++                              wake_up_interruptible(&bd->kme_wait);
++                      dgap_kmebusy = 0;
++                      if(error == ENXIO)
++                              return(-EINVAL);
++              }
++
++              /* Copy the whole (Possibly Modified) mess */
++              /* back out to user space...               */
++
++              if (!error) {
++                      copy_to_user((char *) arg, &kme, sizeof(kme));
++                      return(0);
++              }
++      }
++      }
++
++      DPR_MGMT(("dgap_mgmt_ioctl finish.\n"));
++
++      return 0;
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_mgmt.h  2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_mgmt.h       2003-09-27 11:38:20.956342536 +0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_MGMT_H
++#define __DGAP_MGMT_H
++
++#define MGMT_MGMT 0
++#define MGMT_DOWNLD 1
++
++int dgap_mgmt_open(struct inode *inode, struct file *file);
++int dgap_mgmt_close(struct inode *inode, struct file *file);
++int dgap_mgmt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++#endif
++
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_parse.c 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.c      2003-09-27 11:38:20.958342232 +0800
+@@ -0,0 +1,1299 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *
++ *    NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
++ *
++ *    This is shared code between Digi's CVS archive and the
++ *    Linux Kernel sources.
++ *    Changing the source just for reformatting needlessly breaks
++ *    our CVS diff history.
++ *
++ *    Send any bug fixes/changes to:  Eng.Linux at digi dot com.
++ *    Thank you.
++ *
++ *
++ *****************************************************************************
++ *
++ * dgap_parse.c - Parses the configuration information from the input file.
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ */
++
++#define __NO_VERSION__
++#include <linux/ctype.h>
++#include "dgap_types.h"
++#include "dgap_fep5.h"
++#include "dgap_driver.h"
++#include "dgap_conf.h"
++
++/*
++ * Function prototypes.
++ */
++static int dgap_gettok(char **in, struct cnode *p);
++static char *dgap_getword(char **in);
++static char *dgap_savestring(char *s);
++static struct cnode *dgap_newnode(int t);
++static int dgap_checknode(struct cnode *p);
++static void dgap_err(char *s);
++
++/*
++ * Any needed external variables...
++ */
++extern int dgap_debug;
++
++/*
++ * Our needed internal static variables...
++ */
++static struct cnode dgap_head;
++#define MAXCWORD 200
++static char dgap_cword[MAXCWORD];
++
++struct toklist {
++      int     token;
++      char    *string;
++};
++
++static struct toklist tlist[] = {
++      {       BEGIN,          "config_begin"                  },
++      {       END,            "config_end"                    },
++      {       BOARD,          "board"                         },
++      {       PCX,            "Digi_AccelePort_C/X_PCI"       },      /* C/X_PCI */
++      {       PEPC,           "Digi_AccelePort_EPC/X_PCI"     },      /* EPC/X_PCI */
++      {       PPCM,           "Digi_AccelePort_Xem_PCI"       },      /* PCI/Xem */
++      {       APORT2_920P,    "Digi_AccelePort_2r_920_PCI"    },
++      {       APORT4_920P,    "Digi_AccelePort_4r_920_PCI"    },
++      {       APORT8_920P,    "Digi_AccelePort_8r_920_PCI"    },
++      {       PAPORT4,        "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
++      {       PAPORT8,        "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
++      {       IO,             "io"                            },
++      {       LINE,           "line"                          },
++      {       CONC,           "conc"                          },
++      {       CONC,           "concentrator"                  },
++      {       CX,             "cx"                            },
++      {       EPC,            "epc"                           },
++      {       MOD,            "module"                        },
++      {       ID,             "id"                            },
++      {       STARTO,         "start"                         },
++      {       SPEED,          "speed"                         },
++      {       CABLE,          "cable"                         },
++      {       CONNECT,        "connect"                       },
++      {       METHOD,         "method"                        },
++      {       STATUS,         "status"                        },
++      {       CUSTOM,         "Custom"                        },
++      {       BASIC,          "Basic"                         },
++      {       MEM,            "mem"                           },
++      {       MEM,            "memory"                        },
++      {       PORTS,          "ports"                         },
++      {       MODEM,          "modem"                         },
++      {       NPORTS,         "nports"                        },
++      {       TTYN,           "ttyname"                       },
++      {       CU,             "cuname"                        },
++      {       PRINT,          "prname"                        },
++      {       CMAJOR,         "major"                         },
++      {       ALTPIN,         "altpin"                        },
++      {       USEINTR,        "useintr"                       },
++      {       TTSIZ,          "ttysize"                       },
++      {       CHSIZ,          "chsize"                        },
++      {       BSSIZ,          "boardsize"                     },
++      {       UNTSIZ,         "schedsize"                     },
++      {       F2SIZ,          "f2200size"                     },
++      {       VPSIZ,          "vpixsize"                      },
++      {       0,              NULL                            }
++};
++
++
++/*
++ * Parse a configuration file read into memory as a string.
++ */
++int   dgap_parsefile(char **in, int Remove)
++{
++      struct cnode *p, *brd, *line, *conc;
++      int     rc;
++      char    *s = NULL, *s2 = NULL;
++      int     linecnt = 0;
++
++      p = &dgap_head;
++      brd = line = conc = NULL;
++
++      /* perhaps we are adding to an existing list? */
++      while (p->next != NULL) {
++              p = p->next;
++      }
++
++      /* file must start with a BEGIN */
++      while ( (rc = dgap_gettok(in,p)) != BEGIN ) {
++              if (rc == 0) {
++                      dgap_err("unexpected EOF");
++                      return(-1);
++              }
++      }
++
++      for (; ; ) {
++              rc = dgap_gettok(in,p);
++              if (rc == 0) {
++                      dgap_err("unexpected EOF");
++                      return(-1);
++              }
++
++              switch (rc) {
++              case 0:
++                      dgap_err("unexpected end of file");
++                      return(-1);
++
++              case BEGIN:     /* should only be 1 begin */
++                      dgap_err("unexpected config_begin\n");
++                      return(-1);
++
++              case END:
++                      return(0);
++
++              case BOARD:     /* board info */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(BNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++
++                      p->u.board.status = dgap_savestring("No");
++                      line = conc = NULL;
++                      brd = p;
++                      linecnt = -1;
++                      break;
++
++              case APORT2_920P:       /* AccelePort_4 */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected Digi_2r_920 string");
++                              return(-1);
++                      }
++                      p->u.board.type = APORT2_920P;
++                      p->u.board.v_type = 1;
++                      DPR_INIT(("Adding Digi_2r_920 PCI to config...\n"));
++                      break;
++
++              case APORT4_920P:       /* AccelePort_4 */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected Digi_4r_920 string");
++                              return(-1);
++                      }
++                      p->u.board.type = APORT4_920P;
++                      p->u.board.v_type = 1;
++                      DPR_INIT(("Adding Digi_4r_920 PCI to config...\n"));
++                      break;
++
++              case APORT8_920P:       /* AccelePort_8 */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected Digi_8r_920 string");
++                              return(-1);
++                      }
++                      p->u.board.type = APORT8_920P;
++                      p->u.board.v_type = 1;
++                      DPR_INIT(("Adding Digi_8r_920 PCI to config...\n"));
++                      break;
++
++              case PAPORT4:   /* AccelePort_4 PCI */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected Digi_4r(PCI) string");
++                              return(-1);
++                      }
++                      p->u.board.type = PAPORT4;
++                      p->u.board.v_type = 1;
++                      DPR_INIT(("Adding Digi_4r PCI to config...\n"));
++                      break;
++
++              case PAPORT8:   /* AccelePort_8 PCI */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected Digi_8r string");
++                              return(-1);
++                      }
++                      p->u.board.type = PAPORT8;
++                      p->u.board.v_type = 1;
++                      DPR_INIT(("Adding Digi_8r PCI to config...\n"));
++                      break;
++
++              case PCX:       /* PCI C/X */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected Digi_C/X_(PCI) string");
++                              return(-1);
++                      }
++                      p->u.board.type = PCX;
++                      p->u.board.v_type = 1;
++                      p->u.board.conc1 = 0;
++                      p->u.board.conc2 = 0;
++                      p->u.board.module1 = 0;
++                      p->u.board.module2 = 0;
++                      DPR_INIT(("Adding PCI C/X to config...\n"));
++                      break;
++
++              case PEPC:      /* PCI EPC/X */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected \"Digi_EPC/X_(PCI)\" string");
++                              return(-1);
++                      }
++                      p->u.board.type = PEPC;
++                      p->u.board.v_type = 1;
++                      p->u.board.conc1 = 0;
++                      p->u.board.conc2 = 0;
++                      p->u.board.module1 = 0;
++                      p->u.board.module2 = 0;
++                      DPR_INIT(("Adding PCI EPC/X to config...\n"));
++                      break;
++
++              case PPCM:      /* PCI/Xem */
++                      if (p->type != BNODE) {
++                              dgap_err("unexpected PCI/Xem string");
++                              return(-1);
++                      }
++                      p->u.board.type = PPCM;
++                      p->u.board.v_type = 1;
++                      p->u.board.conc1 = 0;
++                      p->u.board.conc2 = 0;
++                      DPR_INIT(("Adding PCI XEM to config...\n"));
++                      break;
++
++              case IO:        /* i/o port */
++                      if (p->type != BNODE) {
++                              dgap_err("IO port only vaild for boards");
++                              return(-1);
++                      }
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.board.portstr = dgap_savestring(s);
++                      p->u.board.port = (short)simple_strtol(s, &s2, 0);
++                      if ((short)strlen(s) > (short)(s2 - s)) {
++                              dgap_err("bad number for IO port");
++                              return(-1);
++                      }
++                      p->u.board.v_port = 1;
++                      DPR_INIT(("Adding IO (%s) to config...\n", s));
++                      break;
++
++              case MEM:       /* memory address */
++                      if (p->type != BNODE) {
++                              dgap_err("memory address only vaild for boards");
++                              return(-1);
++                      }
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.board.addrstr = dgap_savestring(s);
++                      p->u.board.addr = simple_strtoul(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for memory address");
++                              return(-1);
++                      }
++                      p->u.board.v_addr = 1;
++                      DPR_INIT(("Adding MEM (%s) to config...\n", s));
++                      break;
++
++              case METHOD:
++                      if (p->type != BNODE) {
++                              dgap_err("install method only vaild for boards");
++                              return(-1);
++                      }
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.board.method = dgap_savestring(s);
++                      p->u.board.v_method = 1;
++                      DPR_INIT(("Adding METHOD (%s) to config...\n", s));
++                      break;
++
++              case STATUS:
++                      if (p->type != BNODE) {
++                              dgap_err("config status only vaild for boards");
++                              return(-1);
++                      }
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.board.status = dgap_savestring(s);
++                      DPR_INIT(("Adding STATUS (%s) to config...\n", s));
++                      break;
++
++              case NPORTS:    /* number of ports */
++                      if (p->type == BNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.board.nport = (char)simple_strtol(s, &s2, 0);
++                              if ((int)strlen(s) > (int)(s2 - s)) {
++                                      dgap_err("bad number for number of ports");
++                                      return(-1);
++                              }
++                              p->u.board.v_nport = 1;
++                      } else if (p->type == CNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.conc.nport = (char)simple_strtol(s, &s2, 0);
++                              if ((int)strlen(s) > (int)(s2 - s)) {
++                                      dgap_err("bad number for number of ports");
++                                      return(-1);
++                              }
++                              p->u.conc.v_nport = 1;
++                      } else if (p->type == MNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.module.nport = (char)simple_strtol(s, &s2, 0);
++                              if ((int)strlen(s) > (int)(s2 - s)) {
++                                      dgap_err("bad number for number of ports");
++                                      return(-1);
++                              }
++                              p->u.module.v_nport = 1;
++                      } else {
++                              dgap_err("nports only valid for concentrators or modules");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding NPORTS (%s) to config...\n", s));
++                      break;
++
++              case ID:        /* letter ID used in tty name */
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++
++                      p->u.board.status = dgap_savestring(s);
++
++                      if (p->type == CNODE) {
++                              p->u.conc.id = dgap_savestring(s);
++                              p->u.conc.v_id = 1;
++                      } else if (p->type == MNODE) {
++                              p->u.module.id = dgap_savestring(s);
++                              p->u.module.v_id = 1;
++                      } else {
++                              dgap_err("id only valid for concentrators or modules");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding ID (%s) to config...\n", s));
++                      break;
++
++              case STARTO:    /* start offset of ID */
++                      if (p->type == BNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.board.start = simple_strtol(s, &s2, 0);
++                              if ((int)strlen(s) > (int)(s2 - s)) {
++                                      dgap_err("bad number for start of tty count");
++                                      return(-1);
++                              }
++                              p->u.board.v_start = 1;
++                      } else if (p->type == CNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.conc.start = simple_strtol(s, &s2, 0);
++                              if ((int)strlen(s) > (int)(s2 - s)) {
++                                      dgap_err("bad number for start of tty count");
++                                      return(-1);
++                              }
++                              p->u.conc.v_start = 1;
++                      } else if (p->type == MNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.module.start = simple_strtol(s, &s2, 0);
++                              if ((int)strlen(s) > (int)(s2 - s)) {
++                                      dgap_err("bad number for start of tty count");
++                                      return(-1);
++                              }
++                              p->u.module.v_start = 1;
++                      } else {
++                              dgap_err("start only valid for concentrators or modules");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding START (%s) to config...\n", s));
++                      break;
++
++              case TTYN:      /* tty name prefix */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(TNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      if ( (s = dgap_getword(in)) == NULL ) {
++                              dgap_err("unexpeced end of file");
++                              return(-1);
++                      }
++                      if ( (p->u.ttyname = dgap_savestring(s)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding TTY (%s) to config...\n", s));
++                      break;
++
++              case CU:        /* cu name prefix */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(CUNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      if ( (s = dgap_getword(in)) == NULL ) {
++                              dgap_err("unexpeced end of file");
++                              return(-1);
++                      }
++                      if ( (p->u.cuname = dgap_savestring(s)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding CU (%s) to config...\n", s));
++                      break;
++
++              case LINE:      /* line information */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if (brd == NULL) {
++                              dgap_err("must specify board before line info");
++                              return(-1);
++                      }
++                      switch (brd->u.board.type) {
++                      case PPCM:
++                              dgap_err("line not vaild for PC/em");
++                              return(-1);
++                      }
++                      if ( (p->next = dgap_newnode(LNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      conc = NULL;
++                      line = p;
++                      linecnt++;
++                      DPR_INIT(("Adding LINE to config...\n"));
++                      break;
++
++              case CONC:      /* concentrator information */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if (line == NULL) {
++                              dgap_err("must specify line info before concentrator");
++                              return(-1);
++                      }
++                      if ( (p->next = dgap_newnode(CNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      conc = p;
++                      if (linecnt)
++                              brd->u.board.conc2++;
++                      else
++                              brd->u.board.conc1++;
++
++                      DPR_INIT(("Adding CONC to config...\n"));
++                      break;
++
++              case CX:        /* c/x type concentrator */
++                      if (p->type != CNODE) {
++                              dgap_err("cx only valid for concentrators");
++                              return(-1);
++                      }
++                      p->u.conc.type = CX;
++                      p->u.conc.v_type = 1;
++                      DPR_INIT(("Adding CX to config...\n"));
++                      break;
++
++              case EPC:       /* epc type concentrator */
++                      if (p->type != CNODE) {
++                              dgap_err("cx only valid for concentrators");
++                              return(-1);
++                      }
++                      p->u.conc.type = EPC;
++                      p->u.conc.v_type = 1;
++                      DPR_INIT(("Adding EPC to config...\n"));
++                      break;
++
++              case MOD:       /* EBI module */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if (brd == NULL) {
++                              dgap_err("must specify board info before EBI modules");
++                              return(-1);
++                      }
++                      switch (brd->u.board.type) {
++                      case PPCM:
++                              linecnt = 0;
++                              break;
++                      default:
++                              if (conc == NULL) {
++                                      dgap_err("must specify concentrator info before EBI module");
++                                      return(-1);
++                              }
++                      }
++                      if ( (p->next = dgap_newnode(MNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      if (linecnt)
++                              brd->u.board.module2++;
++                      else
++                              brd->u.board.module1++;
++
++                      DPR_INIT(("Adding MOD to config...\n"));
++                      break;
++
++              case PORTS:     /* ports type EBI module */
++                      if (p->type != MNODE) {
++                              dgap_err("ports only valid for EBI modules");
++                              return(-1);
++                      }
++                      p->u.module.type = PORTS;
++                      p->u.module.v_type = 1;
++                      DPR_INIT(("Adding PORTS to config...\n"));
++                      break;
++
++              case MODEM:     /* ports type EBI module */
++                      if (p->type != MNODE) {
++                              dgap_err("modem only valid for modem modules");
++                              return(-1);
++                      }
++                      p->u.module.type = MODEM;
++                      p->u.module.v_type = 1;
++                      DPR_INIT(("Adding MODEM to config...\n"));
++                      break;
++
++              case CABLE:
++                      if (p->type == LNODE) {
++                              if ((s = dgap_getword(in)) == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.line.cable = dgap_savestring(s);
++                              p->u.line.v_cable = 1;
++                      }
++                      DPR_INIT(("Adding CABLE (%s) to config...\n", s));
++                      break;
++
++              case SPEED:     /* sync line speed indication */
++                      if (p->type == LNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.line.speed = (char)simple_strtol(s, &s2, 0);
++                              if ((short)strlen(s) > (short)(s2 - s)) {
++                                      dgap_err("bad number for line speed");
++                                      return(-1);
++                              }
++                              p->u.line.v_speed = 1;
++                      } else if (p->type == CNODE) {
++                              s = dgap_getword(in);
++                              if (s == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.conc.speed = (char)simple_strtol(s, &s2, 0);
++                              if ((short)strlen(s) > (short)(s2 - s)) {
++                                      dgap_err("bad number for line speed");
++                                      return(-1);
++                              }
++                              p->u.conc.v_speed = 1;
++                      } else {
++                              dgap_err("speed valid only for lines or concentrators.");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding SPEED (%s) to config...\n", s));
++                      break;
++
++              case CONNECT:
++                      if (p->type == CNODE) {
++                              if ((s = dgap_getword(in)) == NULL) {
++                                      dgap_err("unexpected end of file");
++                                      return(-1);
++                              }
++                              p->u.conc.connect = dgap_savestring(s);
++                              p->u.conc.v_connect = 1;
++                      }
++                      DPR_INIT(("Adding CONNECT (%s) to config...\n", s));
++                      break;
++              case PRINT:     /* transparent print name prefix */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(PNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      if ( (s = dgap_getword(in)) == NULL ) {
++                              dgap_err("unexpeced end of file");
++                              return(-1);
++                      }
++                      if ( (p->u.printname = dgap_savestring(s)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding PRINT (%s) to config...\n", s));
++                      break;
++
++              case CMAJOR:    /* major number */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(JNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.majornumber = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for major number");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding CMAJOR (%s) to config...\n", s));
++                      break;
++
++              case ALTPIN:    /* altpin setting */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(ANODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.altpin = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for altpin");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding ALTPIN (%s) to config...\n", s));
++                      break;
++
++              case USEINTR:           /* enable interrupt setting */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(INTRNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.useintr = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for useintr");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding USEINTR (%s) to config...\n", s));
++                      break;
++
++              case TTSIZ:     /* size of tty structure */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(TSNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.ttysize = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for ttysize");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding TTSIZ (%s) to config...\n", s));
++                      break;
++
++              case CHSIZ:     /* channel structure size */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(CSNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.chsize = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for chsize");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding CHSIZE (%s) to config...\n", s));
++                      break;
++
++              case BSSIZ:     /* board structure size */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(BSNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.bssize = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for bssize");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding BSSIZ (%s) to config...\n", s));
++                      break;
++
++              case UNTSIZ:    /* sched structure size */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(USNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.unsize = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for schedsize");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding UNTSIZ (%s) to config...\n", s));
++                      break;
++
++              case F2SIZ:     /* f2200 structure size */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(FSNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.f2size = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for f2200size");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding F2SIZ (%s) to config...\n", s));
++                      break;
++
++              case VPSIZ:     /* vpix structure size */
++                      if (dgap_checknode(p))
++                              return(-1);
++                      if ( (p->next = dgap_newnode(VSNODE)) == NULL ) {
++                              dgap_err("out of memory");
++                              return(-1);
++                      }
++                      p = p->next;
++                      s = dgap_getword(in);
++                      if (s == NULL) {
++                              dgap_err("unexpected end of file");
++                              return(-1);
++                      }
++                      p->u.vpixsize = simple_strtol(s, &s2, 0);
++                      if ((int)strlen(s) > (int)(s2 - s)) {
++                              dgap_err("bad number for vpixsize");
++                              return(-1);
++                      }
++                      DPR_INIT(("Adding VPSIZ (%s) to config...\n", s));
++                      break;
++              }
++      }
++}
++
++
++/*
++ * sindex: much like index(), but it looks for a match of any character in
++ * the group, and returns that position.  If the first character is a ^, then
++ * this will match the first occurence not in that group.
++ */
++static char *sindex (char *string, char *group)
++{
++      char    *ptr;
++
++      if (!string || !group)
++              return (char *) NULL;
++
++      if (*group == '^') {
++              group++;
++              for (; *string; string++) {
++                      for (ptr = group; *ptr; ptr++) {
++                              if (*ptr == *string)
++                                      break;
++                      }
++                      if (*ptr == '\0')
++                              return string;
++              }
++      }
++      else {
++              for (; *string; string++) {
++                      for (ptr = group; *ptr; ptr++) {
++                              if (*ptr == *string)
++                                      return string;
++                      }
++              }
++      }
++
++      return (char *) NULL;
++}
++
++
++/*
++ * Get a token from the input file; return 0 if end of file is reached
++ */
++static int dgap_gettok(char **in, struct cnode *p)
++{
++      char    *w;
++      struct toklist *t;
++
++      if (strstr(dgap_cword, "boar")) {
++              w = dgap_getword(in);
++              snprintf(dgap_cword, MAXCWORD, "%s", w);
++              for (t = tlist; t->token != 0; t++) {
++                      if ( !strcmp(w, t->string)) {
++                              return(t->token);
++                      }
++              }
++              dgap_err("board !!type not specified");
++              return(1);
++      }
++      else {
++              while ( (w = dgap_getword(in)) != NULL ) {
++                      snprintf(dgap_cword, MAXCWORD, "%s", w);
++                      for (t = tlist; t->token != 0; t++) {
++                              if ( !strcmp(w, t->string) )
++                                      return(t->token);
++                      }
++              }
++              return(0);
++      }
++}
++
++
++/*
++ * get a word from the input stream, also keep track of current line number.
++ * words are separated by whitespace.
++ */
++static char *dgap_getword(char **in)
++{
++      char *ret_ptr = *in;
++
++        char *ptr = sindex(*in, " \t\n");
++
++      /* If no word found, return null */
++      if (!ptr)
++              return NULL;
++
++      /* Mark new location for our buffer */
++      *ptr = '\0';
++      *in = ptr + 1;
++
++      /* Eat any extra spaces/tabs/newlines that might be present */
++      while (*in && **in && ((**in == ' ') || (**in == '\t') || (**in == '\n'))) {
++              **in = '\0';
++              *in = *in + 1;
++      }
++
++      return ret_ptr;
++}
++
++
++/*
++ * print an error message, giving the line number in the file where
++ * the error occurred.
++ */
++static void dgap_err(char *s)
++{
++      printk("DGAP: parse: %s\n", s);
++}
++
++
++/*
++ * allocate a new configuration node of type t
++ */
++static struct cnode *dgap_newnode(int t)
++{
++      struct cnode *n;
++      if ( (n = (struct cnode *) kmalloc(sizeof(struct cnode ), GFP_ATOMIC) ) != NULL) {
++              memset( (char *)n, 0, sizeof(struct cnode ) );
++              n->type = t;
++      }
++      return(n);
++}
++
++
++/*
++ * dgap_checknode: see if all the necessary info has been supplied for a node
++ * before creating the next node.
++ */
++static int dgap_checknode(struct cnode *p)
++{
++      switch (p->type) {
++      case BNODE:
++              if (p->u.board.v_type == 0) {
++                      dgap_err("board type !not specified");
++                      return(1);
++              }
++
++              return(0);
++
++      case LNODE:
++              if (p->u.line.v_speed == 0) {
++                      dgap_err("line speed not specified");
++                      return(1);
++              }
++              return(0);
++
++      case CNODE:
++              if (p->u.conc.v_type == 0) {
++                      dgap_err("concentrator type not specified");
++                      return(1);
++              }
++              if (p->u.conc.v_speed == 0) {
++                      dgap_err("concentrator line speed not specified");
++                      return(1);
++              }
++              if (p->u.conc.v_nport == 0) {
++                      dgap_err("number of ports on concentrator not specified");
++                      return(1);
++              }
++              if (p->u.conc.v_id == 0) {
++                      dgap_err("concentrator id letter not specified");
++                      return(1);
++              }
++              return(0);
++
++      case MNODE:
++              if (p->u.module.v_type == 0) {
++                      dgap_err("EBI module type not specified");
++                      return(1);
++              }
++              if (p->u.module.v_nport == 0) {
++                      dgap_err("number of ports on EBI module not specified");
++                      return(1);
++              }
++              if (p->u.module.v_id == 0) {
++                      dgap_err("EBI module id letter not specified");
++                      return(1);
++              }
++              return(0);
++      }
++      return(0);
++}
++
++/*
++ * save a string somewhere
++ */
++static char   *dgap_savestring(char *s)
++{
++      char    *p;
++      if ( (p = kmalloc(strlen(s) + 1, GFP_ATOMIC) ) != NULL) {
++              strcpy(p, s);
++      }
++      return(p);
++}
++
++
++/*
++ * Given a board pointer, returns whether we should use interrupts or not.
++ */
++u32 dgap_config_get_useintr(struct board_t *bd)
++{
++      struct cnode *p = NULL;
++
++      if (!bd)
++              return(0);
++
++      for (p = bd->bd_config; p; p = p->next) {
++              switch (p->type) {
++              case INTRNODE:
++                      /*
++                       * check for pcxr types.
++                       */
++                      return p->u.useintr;
++              default:
++                      break;
++              }
++      }
++
++      /* If not found, then don't turn on interrupts. */
++      return 0;
++}
++
++
++/*
++ * Given a board pointer, returns whether we turn on altpin or not.
++ */
++u32 dgap_config_get_altpin(struct board_t *bd)
++{
++      struct cnode *p = NULL;
++
++      if (!bd)
++              return(0);
++
++      for (p = bd->bd_config; p; p = p->next) {
++              switch (p->type) {
++              case ANODE:
++                      /*
++                       * check for pcxr types.
++                       */
++                      return p->u.altpin;
++              default:
++                      break;
++              }
++      }
++
++      /* If not found, then don't turn on interrupts. */
++      return 0;
++}
++
++
++
++/*
++ * Given a specific type of board, if found, detached link and
++ * returns the first occurance in the list.
++ */
++struct cnode *dgap_find_config(int type)
++{
++      struct cnode *p, *prev = NULL, *prev2 = NULL, *found = NULL;
++
++      p = &dgap_head;
++
++      while (p->next != NULL) {
++              prev = p;
++              p = p->next;
++
++              if (p->type == BNODE) {
++                      if (p->u.board.type == type) {
++                              DPR_INIT(("Matched type in config file\n"));
++
++                              found = p;
++                              /*
++                               * Keep walking thru the list till we find the next board.
++                               */
++                              while (p->next != NULL) {
++                                      prev2 = p;
++                                      p = p->next;
++                                      if (p->type == BNODE) {
++
++                                              /*
++                                               * Mark the end of our 1 board chain of configs.
++                                               */
++                                              prev2->next = NULL;
++
++                                              /*
++                                               * Link the "next" board to the previous board,
++                                               * effectively "unlinking" our board from the main config.
++                                               */
++                                              prev->next = p;
++
++                                              return found;
++                                      }
++                              }
++                              /*
++                               * It must be the last board in the list.
++                               */
++                              prev->next = NULL;
++                              return found;
++                      }
++              }
++      }
++      return NULL;
++}
++
++/*
++ * Given a board pointer, walks the config link, counting up
++ * all ports user specified should be on the board.
++ * (This does NOT mean they are all actually present right now tho)
++ */
++u32 dgap_config_get_number_of_ports(struct board_t *bd)
++{
++      int count = 0;
++      struct cnode *p = NULL;
++
++      if (!bd)
++              return(0);
++
++      for (p = bd->bd_config; p; p = p->next) {
++
++              switch (p->type) {
++              case BNODE:
++                      /*
++                       * check for pcxr types.
++                       */
++                      if (p->u.board.type > EPCFE)
++                              count += p->u.board.nport;
++                      break;
++              case CNODE:
++                      count += p->u.conc.nport;
++                      break;
++              case MNODE:
++                      count += p->u.module.nport;
++                      break;
++              }
++      }
++      return (count);
++}
++
++char *dgap_create_config_string(struct board_t *bd, char *string)
++{
++      char *ptr = string;
++      struct cnode *p = NULL;
++
++      if (!bd) {
++              *ptr = 0xff;
++              return string;
++      }
++
++      for (p = bd->bd_config; p; p = p->next) {
++
++              switch (p->type) {
++              case LNODE:
++                      *ptr = '\0';
++                      ptr++;
++                      *ptr = p->u.line.speed;
++                      ptr++;
++                      break;
++              case CNODE:
++                      *ptr = p->u.conc.nport;
++                      ptr++;
++                      *ptr = p->u.conc.speed;
++                      ptr++;
++                      break;
++              }
++      }
++
++      *ptr = 0xff;
++      return string;
++}
++
++
++
++char *dgap_get_config_letters(struct board_t *bd, char *string)
++{
++      int found = FALSE;
++      char *ptr = string;
++      struct cnode *cptr = NULL;
++      int len = 0;
++      int left = MAXTTYNAMELEN;
++
++      if (!bd) {
++              return "<NULL>";
++      }
++
++      for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
++
++              if ((cptr->type == BNODE) &&
++                   ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
++                   (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
++                   (cptr->u.board.type == PAPORT8))) {
++
++                      found = TRUE;
++              }
++
++              if (cptr->type == TNODE && found == TRUE) {
++                      char *ptr1;
++                      if (strstr(cptr->u.ttyname, "tty")) {
++                              ptr1 = cptr->u.ttyname;
++                              ptr1 += 3;
++                      }
++                      else {
++                              ptr1 = cptr->u.ttyname;
++                      }
++                      if (ptr1) {
++                              len = snprintf(ptr, left, "%s", ptr1);
++                              left -= len;
++                              ptr  += len;
++                              if (left <= 0)
++                                      break;
++                      }
++              }
++
++              if (cptr->type == CNODE) {
++                      if (cptr->u.conc.id) {
++                              len = snprintf(ptr, left, "%s", cptr->u.conc.id);
++                              left -= len;
++                              ptr  += len;
++                              if (left <= 0)
++                                      break;
++                      }
++                }
++
++              if (cptr->type == MNODE) {
++                      if (cptr->u.module.id) {
++                              len = snprintf(ptr, left, "%s", cptr->u.module.id);
++                              left -= len;
++                              ptr  += len;
++                              if (left <= 0)
++                                      break;
++                      }
++              }
++      }
++
++      return string;
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_parse.h 2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_parse.h      2003-09-27 11:38:20.959342080 +0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef _DGAP_PARSE_H
++#define _DGAP_PARSE_H
++
++#include "dgap_driver.h"
++
++int dgap_parsefile(char **in, int Remove);
++struct cnode *dgap_find_config(int type);
++u32 dgap_config_get_number_of_ports(struct board_t *bd);
++char *dgap_create_config_string(struct board_t *bd, char *string);
++char *dgap_get_config_letters(struct board_t *bd, char *string);
++u32 dgap_config_get_useintr(struct board_t *bd);
++u32 dgap_config_get_altpin(struct board_t *bd);
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_pci.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_pci.h   2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_pci.h        2003-09-27 11:38:20.960341928 +0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++
++#ifndef __DGAP_PCI_H
++#define __DGAP_PCI_H
++
++#define PCIMAX 32                     /* maximum number of PCI boards */
++
++#define DIGI_VID              0x114F
++
++#define PCI_DEVICE_EPC_DID    0x0002
++#define PCI_DEVICE_XEM_DID    0x0004
++#define PCI_DEVICE_XR_DID     0x0005
++#define PCI_DEVICE_CX_DID     0x0006
++#define PCI_DEVICE_XRJ_DID    0x0009  /* PLX-based Xr adapter */
++#define PCI_DEVICE_XR_IBM_DID 0x0011  /* IBM 8-port Async Adapter */
++#define PCI_DEVICE_XR_422_DID 0x0012  /* Xr-422 */
++#define PCI_DEVICE_920_2_DID  0x0034  /* XR-Plus 920 K, 2 port */
++#define PCI_DEVICE_920_4_DID  0x0026  /* XR-Plus 920 K, 4 port */
++#define PCI_DEVICE_920_8_DID  0x0027  /* XR-Plus 920 K, 8 port */
++#define PCI_DEVICE_EPCJ_DID   0x000a  /* PLX 9060 chip for PCI  */
++#define PCI_DEVICE_CX_IBM_DID 0x001b  /* IBM 128-port Async Adapter */
++
++#define PCI_DEVICE_XEM_NAME   "AccelePort XEM"
++#define PCI_DEVICE_CX_NAME    "AccelePort CX"
++#define PCI_DEVICE_XR_NAME    "AccelePort Xr"
++#define PCI_DEVICE_XRJ_NAME   "AccelePort Xr (PLX)"
++#define PCI_DEVICE_920_2_NAME "AccelePort Xr920 2 port"
++#define PCI_DEVICE_920_4_NAME "AccelePort Xr920 4 port"
++#define PCI_DEVICE_920_8_NAME "AccelePort Xr920 8 port"
++#define PCI_DEVICE_XR_422_NAME        "AccelePort Xr 422"
++#define PCI_DEVICE_EPCJ_NAME  "AccelePort EPC (PLX)"
++#define PCI_DEVICE_XR_IBM_NAME        "AccelePort Xr (IBM)"
++#define PCI_DEVICE_CX_IBM_NAME        "AccelePort CX (IBM)"
++
++/*
++ * On the PCI boards, there is no IO space allocated
++ * The I/O registers will be in the first 3 bytes of the
++ * upper 2MB of the 4MB memory space.  The board memory
++ * will be mapped into the low 2MB of the 4MB memory space
++ */
++
++/* Potential location of PCI Bios from E0000 to FFFFF*/
++#define PCI_BIOS_SIZE         0x00020000
++
++/* Size of Memory and I/O for PCI (4MB) */
++#define PCI_RAM_SIZE          0x00400000
++
++/* Size of Memory (2MB) */
++#define PCI_MEM_SIZE          0x00200000
++
++/* Max PCI Window Size (2MB) */
++#define PCI_WIN_SIZE          0x00200000
++
++#define PCI_WIN_SHIFT         21 /* 21 bits max */
++
++/* Offset of I/0 in Memory (2MB) */
++#define PCI_IO_OFFSET         0x00200000
++
++/* Size of IO (2MB) */
++#define PCI_IO_SIZE           0x00200000
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_proc.c  2003-09-27 11:38:18.448723752 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.c       2003-09-27 11:38:20.961341776 +0800
+@@ -0,0 +1,700 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *
++ *    NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
++ *
++ *    This is shared code between Digi's CVS archive and the
++ *    Linux Kernel sources.
++ *    Changing the source just for reformatting needlessly breaks
++ *    our CVS diff history.
++ *
++ *    Send any bug fixes/changes to:  Eng.Linux at digi dot com.
++ *    Thank you.
++ *
++ */
++
++/************************************************************************
++ *
++ * /proc/dgap/{*} functions
++ *
++ ************************************************************************/
++#define __NO_VERSION__
++#include "dgap_driver.h"
++#include "dgap_parse.h"
++#include "dgap_mgmt.h"
++#include <linux/ctype.h>
++#include <linux/proc_fs.h>
++
++/* external variables */
++extern int              dgap_debug;
++extern struct board_t *dgap_Board[MAXBOARDS];
++extern uchar          dgap_NumBoards;
++extern u32            dgap_poll_counter;
++
++
++/*
++ * OK, here's the deal with /proc files.  We want to use the
++ * simple (yet inefficient) interface to /proc where we just get
++ * a buffer and fill it in.  Otherwise, we'd have to provide the
++ * full set of functions for a /proc driver.
++ *
++ * When we get called, "buf" points to a single free page which
++ * we can write into.  If you are careful, you can write up
++ * to PAGE_SIZE (4096) bytes into it.  But to be paranoid,
++ * Linux lies and says the "count" is only PROC_BLOK_SIZE (3072).
++ *
++ * In any case, its easiest to make several /proc/dgap/ entries
++ * if you want to print out more info than can fit in a page.
++ *
++ * Here's some further information.  We are trying to be compatible
++ * with 2.0.xx and 2.1.xx.  There have been improvements in 2.1.x
++ * in this area, but it still isn't perfect.  Anyway, our hands
++ * are tied by the 2.0.x limitations.  For example, you cannot
++ * pass private data to the get_info (2.0.x) routines.  Therefore,
++ * you cannot make a generic function to print the data for one
++ * board.  If you want to do this, you have to make a wrapper
++ * function, one function name per board number.  Yech!
++ */
++
++      #define PROC_READ_PROTO \
++              char *buf, char **start, off_t fpos, int count, \
++              int *eof, void *private
++
++      #define PROC_READ_ARGS \
++              buf, start, fpos, count, eof, private
++
++
++/*
++ *    Make wrappers for per-board entries. Gag me.  Sorry,
++ *    2.0.x forced us into this since it has no way to pass
++ *    private data to the read_proc (get_info, actually).
++ */
++/* FIXME - Fix this, we can convert away from this now */
++#define       PROCWRAP_FUNCTION(FUNC, NUM) \
++                      static int \
++                      FUNC ## NUM (PROC_READ_PROTO) \
++                      { \
++                              return FUNC(NUM, PROC_READ_ARGS); \
++                      }
++
++#define       PROCWRAP_FUNC(FUNC,NUM) \
++              FUNC ## tbl[NUM]
++
++#define       PROCWRAP_FUNCTIONS(FUNC) \
++              PROCWRAP_FUNCTION(FUNC, 0) \
++              PROCWRAP_FUNCTION(FUNC, 1) \
++              PROCWRAP_FUNCTION(FUNC, 2) \
++              PROCWRAP_FUNCTION(FUNC, 3) \
++              PROCWRAP_FUNCTION(FUNC, 4) \
++              PROCWRAP_FUNCTION(FUNC, 5) \
++              PROCWRAP_FUNCTION(FUNC, 6) \
++              PROCWRAP_FUNCTION(FUNC, 7) \
++              PROCWRAP_FUNCTION(FUNC, 8) \
++              PROCWRAP_FUNCTION(FUNC, 9) \
++              PROCWRAP_FUNCTION(FUNC, 10) \
++              PROCWRAP_FUNCTION(FUNC, 11) \
++              PROCWRAP_FUNCTION(FUNC, 12) \
++              PROCWRAP_FUNCTION(FUNC, 13) \
++              PROCWRAP_FUNCTION(FUNC, 14) \
++              PROCWRAP_FUNCTION(FUNC, 15) \
++              PROCWRAP_FUNCTION(FUNC, 16) \
++              PROCWRAP_FUNCTION(FUNC, 17) \
++              PROCWRAP_FUNCTION(FUNC, 18) \
++              PROCWRAP_FUNCTION(FUNC, 19) \
++              PROCWRAP_FUNCTION(FUNC, 20) \
++              PROCWRAP_FUNCTION(FUNC, 21) \
++              PROCWRAP_FUNCTION(FUNC, 22) \
++              PROCWRAP_FUNCTION(FUNC, 23) \
++              PROCWRAP_FUNCTION(FUNC, 24) \
++              PROCWRAP_FUNCTION(FUNC, 25) \
++              PROCWRAP_FUNCTION(FUNC, 26) \
++              PROCWRAP_FUNCTION(FUNC, 27) \
++              PROCWRAP_FUNCTION(FUNC, 28) \
++              PROCWRAP_FUNCTION(FUNC, 29) \
++              PROCWRAP_FUNCTION(FUNC, 30) \
++              PROCWRAP_FUNCTION(FUNC, 31) \
++
++#define       PROCWRAP_TBL(FUNC) \
++                      static read_proc_t * FUNC ## tbl[MAXBOARDS] = \
++              { \
++                      FUNC ## 0, \
++                      FUNC ## 1, \
++                      FUNC ## 2, \
++                      FUNC ## 3, \
++                      FUNC ## 4, \
++                      FUNC ## 5, \
++                      FUNC ## 6, \
++                      FUNC ## 7, \
++                      FUNC ## 8, \
++                      FUNC ## 9, \
++                      FUNC ## 10, \
++                      FUNC ## 11, \
++                      FUNC ## 12, \
++                      FUNC ## 13, \
++                      FUNC ## 14, \
++                      FUNC ## 15, \
++                      FUNC ## 16, \
++                      FUNC ## 17, \
++                      FUNC ## 18, \
++                      FUNC ## 19, \
++                      FUNC ## 20, \
++                      FUNC ## 21, \
++                      FUNC ## 22, \
++                      FUNC ## 23, \
++                      FUNC ## 24, \
++                      FUNC ## 25, \
++                      FUNC ## 26, \
++                      FUNC ## 27, \
++                      FUNC ## 28, \
++                      FUNC ## 29, \
++                      FUNC ## 30, \
++                      FUNC ## 31, \
++              };
++
++#define       PROCWRAPPERS(FUNC) \
++              PROCWRAP_FUNCTIONS(FUNC) \
++              PROCWRAP_TBL(FUNC)
++
++
++/*
++ * /proc/dgap/<boardno>/tty
++ */
++static struct proc_dir_entry *ProcDgAPTTY[MAXBOARDS];
++
++static int dgap_proc_tty(int brdno, PROC_READ_PROTO)
++{
++      struct board_t *brd;
++      char    *p = buf;
++
++      DPR_PROC(("dgap_proc_tty count=%d fpos=%ld\n", count, fpos));
++
++        brd = dgap_Board[brdno];
++
++        if(!brd)
++                return(-EINVAL);
++
++      /* Prepare the Header Labels */
++      p += sprintf(p, "         Receive Statistics        "
++                               "Transmit Statistics\n");
++      p += sprintf(p, "%2s %19s %7s %19s %7s %s\n",
++                     "Ch", "Chars Rx", "RxCPS",
++                     "Chars Tx", "TxCPS", " Line Status Flags");
++
++      DPR_PROC(("dgap_proc_tty returns %d\n", p-buf));
++
++      return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_tty)
++
++
++/*
++ * /proc/dgap/<boardno>/ttys
++ */
++static struct proc_dir_entry *ProcDgAPTTYs[MAXBOARDS];
++
++static int dgap_proc_ttys(int brdno, PROC_READ_PROTO)
++{
++      struct board_t *brd;
++      char    *p = buf;
++
++      DPR_PROC(("dgap_proc_ttys count=%d fpos=%ld\n", count, fpos));
++
++        brd = dgap_Board[brdno];
++
++        if(!brd)
++                return(-EINVAL);
++
++      p += sprintf(p, "Chan\t&tty\tflags\n");
++
++      DPR_PROC(("dgap_proc_ttys returns %d\n", p-buf));
++
++      return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_ttys)
++
++
++/*
++ * /proc/dgap/<boardno>/info
++ *
++ * Variables compatible with the shell
++ */
++static struct proc_dir_entry *ProcDgAPBrdInfo[MAXBOARDS];
++
++static int dgap_proc_brd_info(int brdno, PROC_READ_PROTO)
++{
++      struct board_t  *brd;
++      char            *p = buf;
++      char            *name;
++
++      DPR_PROC(("dgap_proc_brd_info\n"));
++
++        brd = dgap_Board[brdno];
++
++        if(!brd)
++                return(-EINVAL);
++
++      name = brd->name;
++
++      p += sprintf(p, "Board Name = %s\n", name);
++      p += sprintf(p, "Board Type = %d\n", brd->type);
++
++      /*
++       * report some things about the PCI bus that are important
++       * to some applications
++       */
++        p += sprintf(p, "Vendor ID = 0x%x\n", brd->vendor);
++        p += sprintf(p, "Device ID = 0x%x\n", brd->device);
++        p += sprintf(p, "Subvendor ID = 0x%x\n", brd->subvendor);
++        p += sprintf(p, "Subdevice ID = 0x%x\n", brd->subdevice);
++
++      /*
++       * report the physical addresses assigned to us when we got
++       * registered
++       */
++        p += sprintf(p, "IO Port = 0x%lx\n", brd->port);
++        p += sprintf(p, "Memory Base Address = 0x%lx\n", brd->membase);
++        p += sprintf(p, "Remapped IO Port Address = 0x%p\n", brd->re_map_port);
++        p += sprintf(p, "Remapped Memory Base Address = 0x%p\n", brd->re_map_membase);
++
++        p += sprintf(p, "Current state of board = %s\n", dgap_state_text[brd->state]);
++        p += sprintf(p, "Interrupt #: %d. Times interrupted: %d\n",
++              brd->irq, brd->intr_count);
++        p += sprintf(p, "Majors allocated to board = TTY: %d PR: %d\n",
++              brd->SerialDriver.major, brd->PrintDriver.major);
++
++      /*
++       * report available resources on the card
++       */
++
++      return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_brd_info)
++
++
++/*
++ * /proc/dgap/info
++ *
++ *    Variables compatible with the shell
++ */
++static struct proc_dir_entry *ProcDgAPInfo;
++
++static int dgap_proc_info(PROC_READ_PROTO)
++{
++      char    *p = buf;
++
++      DPR_PROC(("dgap_proc_info\n"));
++      p += sprintf(p, "Max Boards = %d\n", MAXBOARDS);
++      p += sprintf(p, "Current number of boards = %d\n", dgap_NumBoards);
++      p += sprintf(p, "Poll counter = %d\n", dgap_poll_counter);
++      p += sprintf(p, "State of driver: %s\n", dgap_driver_state_text[dgap_driver_state]);
++      return(p-buf);
++}
++
++/*
++ * /proc/dgap/<boardno>/mknod
++ */
++static struct proc_dir_entry *ProcDgAPBrdMknod[MAXBOARDS];
++
++static int mknod_tty_cmd(char *buf, char *nodename,
++                     int major, int firstminor, int count, int start)
++{
++      return sprintf(buf, "dgap_mknod\t%s\t\t%d\t%d\t%d\t%d\n",
++                     nodename, major, firstminor, count, start);
++}
++
++
++static int dgap_proc_brd_mknod(int brdno, PROC_READ_PROTO)
++{
++      struct board_t *brd = dgap_Board[brdno];
++      int     bn;
++      char    *p = buf;
++      struct cnode *cptr = NULL;
++      char str[100];
++      int found = FALSE;
++      int ncount = 0;
++      int starto = 0;
++
++      DPR_PROC(("dgap_proc_brd_mknod(%d) %d\n", brdno, count));
++
++        if(!brd)
++                return(-ENODEV);
++
++        bn = brd->boardnum;
++
++
++      /*
++       * Output the boilerplate at the top of the shell script
++       */
++      p += sprintf(p, "#!/bin/sh\n\n");
++
++      p += sprintf(p, "# /proc/dgap/mknod [-d]\n");
++      p += sprintf(p, "#\tMake DGAP device nodes.\n");
++      p += sprintf(p, "#\t-d deletes all existing nodes first\n\n");
++
++      p += sprintf(p, "PATH=" SBINDIR ":$PATH\n");
++
++      p += sprintf(p, "[ -d %s ] || mkdir -p -m 755 %s\n",
++                     DEVSTR, DEVSTR);
++
++      p += sprintf(p, "[ \"$1\" != -d ] || rm -rf %s/* || exit 1\n",
++                     DEVSTR);
++
++      p += sprintf(p, "cd %s || exit 2\n\n", DEVSTR);
++
++      /*
++       * For each board, output the device information in
++       * a handy table format...
++       */
++      p += sprintf(p, "#\t\tNAME\t\tMAJOR\tMINOR\tCOUNT\tSTART\n");
++
++
++      for (cptr = brd->bd_config; cptr; cptr = cptr->next) {
++
++              if ((cptr->type == BNODE) &&
++                  ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
++                   (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
++                   (cptr->u.board.type == PAPORT8))) {
++
++                              found = TRUE;
++                              if (cptr->u.board.start)
++                                      starto = cptr->u.board.start;
++                              else
++                                      starto = 1;
++              }
++
++              if (cptr->type == TNODE && found == TRUE) {
++                      char *ptr1;
++                      if (strstr(cptr->u.ttyname, "tty")) {
++                              ptr1 = cptr->u.ttyname;
++                              ptr1 += 3;
++                      }
++                      else {
++                              ptr1 = cptr->u.ttyname;
++                      }
++
++                      /* TTY devices */
++                      sprintf(str, "tty%s%%p", ptr1);
++
++                      p += mknod_tty_cmd(p, str,
++                              brd->SerialDriver.major,
++                              0, dgap_config_get_number_of_ports(brd), starto);
++
++                      /* PR devices */
++                      sprintf(str, "pr%s%%p", ptr1);
++
++                      p += mknod_tty_cmd(p, str,
++                              brd->PrintDriver.major,
++                              0, dgap_config_get_number_of_ports(brd), starto);
++              }
++
++              if (cptr->type == CNODE) {
++
++                      sprintf(str, "tty%s%%p", cptr->u.conc.id);
++
++                      /* TTY devices */
++                      p += mknod_tty_cmd(p, str,
++                              brd->SerialDriver.major,
++                              ncount, cptr->u.conc.nport,
++                              cptr->u.conc.start ? cptr->u.conc.start : 1);
++
++                      sprintf(str, "pr%s%%p", cptr->u.conc.id);
++
++                      p += mknod_tty_cmd(p, str,
++                              brd->PrintDriver.major,
++                              ncount, cptr->u.conc.nport,
++                              cptr->u.conc.start ? cptr->u.conc.start : 1);
++
++                      ncount += cptr->u.conc.nport;
++              }
++
++              if (cptr->type == MNODE) {
++
++                      sprintf(str, "tty%s%%p", cptr->u.module.id);
++
++                      /* TTY devices */
++                      p += mknod_tty_cmd(p, str,
++                              brd->SerialDriver.major,
++                              ncount, cptr->u.module.nport,
++                              cptr->u.module.start ? cptr->u.module.start : 1);
++
++                      sprintf(str, "pr%s%%p", cptr->u.module.id);
++
++                      p += mknod_tty_cmd(p, str,
++                              brd->PrintDriver.major,
++                              ncount, cptr->u.module.nport,
++                              cptr->u.module.start ? cptr->u.module.start : 1);
++
++                      ncount += cptr->u.module.nport;
++
++              }
++      }
++
++      return(p-buf);
++}
++
++PROCWRAPPERS(dgap_proc_brd_mknod)
++
++
++/*
++ *      /proc/dgap/mknod
++ */
++static struct proc_dir_entry *ProcDgAPMknod;
++
++static int dgap_proc_mknod(PROC_READ_PROTO)
++{
++        char    *p = buf;
++
++        DPR_PROC(("dgap_proc_mknod\n"));
++
++        p += sprintf(p, "#!/bin/sh\n\n");
++
++        p += sprintf(p, "#\t/proc/dgap/mknod [-d]\n");
++        p += sprintf(p, "#\t\tMake DGAP device nodes.\n");
++        p += sprintf(p, "#\t\t-d deletes all existing nodes first\n\n");
++
++      p += sprintf(p, "if [ \"$1\" != -d ]\nthen\n\texit 1\nfi\n");
++
++      p += sprintf(p, "if [ -d %s ]\nthen\n", DEVSTR);
++
++        p += sprintf(p, "\tcd %s\n", DEVSTR);
++
++      /* Delete all our ttys */
++        p += sprintf(p, "\tfor i in tty*\n");
++        p += sprintf(p, "\tdo\n");
++
++        p += sprintf(p, "\t\tif [ \"$i\" != \"tty*\" ]\n");
++        p += sprintf(p, "\t\tthen\n");
++
++        p += sprintf(p, "\t\t\trm -rf $i\n");
++        p += sprintf(p, "\t\t\trm -rf /dev/$i\n");
++
++        p += sprintf(p, "\t\tfi\n");
++
++        p += sprintf(p, "\tdone\n");
++
++      /* Delete all our prs */
++        p += sprintf(p, "\tfor i in pr*\n");
++        p += sprintf(p, "\tdo\n");
++
++        p += sprintf(p, "\t\tif [ \"$i\" != \"pr*\" ]\n");
++        p += sprintf(p, "\t\tthen\n");
++
++        p += sprintf(p, "\t\t\trm -rf $i\n");
++        p += sprintf(p, "\t\t\trm -rf /dev/$i\n");
++
++        p += sprintf(p, "\t\tfi\n");
++
++        p += sprintf(p, "\tdone\n");
++
++        p += sprintf(p, "fi\n");
++
++      /* Delete anything that was left. */
++      p += sprintf(p, "rm -rf %s/*\n", DEVSTR);
++
++        p += sprintf(p, "for i in /proc/dgap/*/mknod\n");
++        p += sprintf(p, "do\n");
++
++        p += sprintf(p, "\tif [ \"$i\" != \"/proc/dgap/*/mknod\" ]\n");
++        p += sprintf(p, "\tthen\n");
++
++        p += sprintf(p, "\t\t$i\n");
++
++        p += sprintf(p, "\tfi\n");
++
++        p += sprintf(p, "done\n");
++
++      p += sprintf(p, "#\tCreate the management device.\n\n");
++      p += mknod_tty_cmd(p, "/dev/dg/dgap/mgmt", DIGI_DGAP_MAJOR, MGMT_MGMT, 1, 0);
++      p += mknod_tty_cmd(p, "/dev/dg/dgap/downld", DIGI_DGAP_MAJOR, MGMT_DOWNLD, 1, 0);
++
++        return (p-buf);
++}
++
++
++/*
++ * The directory entries /proc/dgap/<boardnum>
++ */
++static struct proc_dir_entry *ProcDgAPBrd[MAXBOARDS];
++
++/*
++ * The directory entry /proc/dgap
++ */
++static struct proc_dir_entry *ProcDgAP;
++
++/*
++ * Gee, the proc I/F for drivers is *still* not well done in 2.1.x.
++ *
++ * In any event, we'll *make* a better interface here and then
++ * use it to abstract the differences between 2.0.x and 2.1.x
++ *
++ * Unfortunately, the *best* interface would also allow you
++ * to pass in "private" data.  But that can't be supported
++ * on 2.0.x, so that is why this interface is just "better".
++ */
++
++static struct proc_dir_entry *better_create_proc_entry(
++        const char *name, mode_t mode, unsigned long size,
++        read_proc_t *read_proc,       struct proc_dir_entry *parent)
++{
++        struct proc_dir_entry *pde;
++
++        pde = create_proc_entry(name, mode, parent);
++        if (!pde) return NULL;
++
++        if (size)
++                pde->size = size;
++        if (read_proc)
++                pde->read_proc = read_proc;
++
++        return pde;
++}
++
++static void better_remove_proc_entry(struct proc_dir_entry *pde)
++{
++        if (!pde) return;
++
++        remove_proc_entry(pde->name, pde->parent);
++}
++
++
++/*
++ * Register the basic /proc/dgap files that appear whenever
++ * the driver is loaded.
++ */
++void dgap_proc_register_basic_prescan(void)
++{
++      char    *buf;
++      int     size;
++
++      /* Register /proc/dgap */
++      ProcDgAP = better_create_proc_entry(PROCSTR, S_IFDIR, 0, NULL, 0);
++
++      /* Register /proc/dgap/info */
++      ProcDgAPInfo = better_create_proc_entry( "info", 0, 0,
++                      dgap_proc_info, ProcDgAP);
++
++      /*
++       * Compute size of /proc/dgap/mknod output, fixup
++       * proc_dir_entry for it, then register it.
++       */
++      buf = kmalloc(4096, GFP_KERNEL);
++      if (buf) {
++                size = dgap_proc_mknod(buf, NULL, 0, 4096, 0, 0);
++      } else
++              size = 0;
++      kfree(buf);
++
++      ProcDgAPMknod =
++                better_create_proc_entry("mknod", S_IFREG | S_IRUGO | S_IXUGO,
++                                         size, dgap_proc_mknod, ProcDgAP);
++}
++
++
++
++/*
++ * Register the basic /proc/dgap files that appear whenever
++ * the driver is loaded.
++ */
++void dgap_proc_register_basic_postscan(void)
++{
++      char    *buf;
++      int     size;
++      int     i;
++
++      /*
++       * Register /proc/dgap/<boardnum> directories
++       * and the /proc/dgap/<boardnum>/info files
++       */
++      for (i = 0; i < dgap_NumBoards; ++i) {
++              char    name[2];
++
++              name[0] = i + '0';
++              name[1] = 0;
++              ProcDgAPBrd[i] = better_create_proc_entry(name, S_IFDIR, 0,
++                                                          NULL, ProcDgAP);
++
++              ProcDgAPBrdInfo[i] = better_create_proc_entry("info", 0, 0,
++                        PROCWRAP_FUNC(dgap_proc_brd_info, i),
++                        ProcDgAPBrd[i]);
++
++              /*
++                 * Compute size of /proc/dgap/<boardno>/mknod output, fixup
++                 * proc_dir_entry for it, then register it.
++                 */
++                buf = kmalloc(4096, GFP_ATOMIC);
++                if (buf) {
++                        size = dgap_proc_brd_mknod(i, buf, NULL, 0, 4096, 0, 0);
++                } else
++                        size = 0;
++                kfree(buf);
++
++                ProcDgAPBrdMknod[i] = better_create_proc_entry("mknod",
++                                        S_IFREG | S_IRUGO | S_IXUGO, size,
++                                        PROCWRAP_FUNC(dgap_proc_brd_mknod, i),
++                                        ProcDgAPBrd[i]);
++      }
++}
++
++
++/*
++ * Register the proc devices that appear only if we are
++ * loading up a fep.
++ */
++void dgap_proc_register_fep(void)
++{
++      int     i;
++
++      for (i = 0; i < dgap_NumBoards; ++i) {
++
++              ProcDgAPTTYs[i] = better_create_proc_entry( "ttys", 0, 0,
++                      PROCWRAP_FUNC(dgap_proc_ttys, i),
++                      ProcDgAPBrd[i]);
++
++              ProcDgAPTTY[i] = better_create_proc_entry( "tty", 0, 0,
++                      PROCWRAP_FUNC(dgap_proc_tty, i),
++                      ProcDgAPBrd[i]);
++      }
++}
++
++/*
++ * Unregister all of our /proc/dgap/{*} devices
++ */
++void dgap_proc_unregister_all(void)
++{
++      int     i;
++
++#define NUKE_ONE(PDE) \
++      if (PDE) { better_remove_proc_entry(PDE); PDE = NULL; } else
++
++      for (i = 0; i < dgap_NumBoards; ++i) {
++              NUKE_ONE(ProcDgAPTTY[i]);
++              NUKE_ONE(ProcDgAPTTYs[i]);
++              NUKE_ONE(ProcDgAPBrdMknod[i]);
++              NUKE_ONE(ProcDgAPBrdInfo[i]);
++              NUKE_ONE(ProcDgAPBrd[i]);
++      }
++
++      NUKE_ONE(ProcDgAPMknod);
++      NUKE_ONE(ProcDgAPInfo);
++
++      NUKE_ONE(ProcDgAP);
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_proc.h  2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_proc.h       2003-09-27 11:38:20.962341624 +0800
+@@ -0,0 +1,32 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_PROC_H
++#define __DGAP_PROC_H
++
++#include "dgap_driver.h"
++
++void  dgap_proc_unregister_all(void);
++void  dgap_proc_register_basic_prescan(void);
++void  dgap_proc_register_basic_postscan(void);
++void  dgap_proc_register_fep(void);
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_trace.c 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.c      2003-09-27 11:38:20.962341624 +0800
+@@ -0,0 +1,182 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *
++ *    NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
++ *
++ *    This is shared code between Digi's CVS archive and the
++ *    Linux Kernel sources.
++ *    Changing the source just for reformatting needlessly breaks
++ *    our CVS diff history.
++ *
++ *    Send any bug fixes/changes to:  Eng.Linux at digi dot com.
++ *    Thank you.
++ *
++ */
++
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++
++#define __NO_VERSION__
++#include "dgap_driver.h"
++#define TRC_TO_CONSOLE 1
++
++
++
++#include <linux/vmalloc.h>
++
++/* file level globals */
++static char *dgap_trcbuf;             /* the ringbuffer */
++
++#if defined(TRC_TO_KMEM)
++static int dgap_trcbufi = 0;          /* index of the tilde at the end of */
++#endif
++
++extern int dgap_trcbuf_size;          /* size of the ringbuffer */
++
++#if defined(TRC_TO_KMEM)
++static spinlock_t dgap_tracef_lock = SPIN_LOCK_UNLOCKED;
++#endif
++
++
++#if !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE)
++void dgap_tracef(const char *fmt, ...)
++{
++      return;
++}
++
++#else /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
++
++void dgap_tracef(const char *fmt, ...)
++{
++      va_list          ap;
++      char             buf[TRC_MAXMSG+1];
++      size_t           lenbuf;
++      int              i;
++      static int       failed = FALSE;
++# if defined(TRC_TO_KMEM)
++      unsigned long    flags;
++#endif
++
++      if(failed)
++              return;
++# if defined(TRC_TO_KMEM)
++      DGAP_LOCK(dgap_tracef_lock, flags);
++#endif
++
++      /* Format buf using fmt and arguments contained in ap. */
++      va_start(ap, fmt);
++      i = vsprintf(buf, fmt,  ap);
++      va_end(ap);
++      lenbuf = strlen(buf);
++
++# if defined(TRC_TO_KMEM)
++      {
++              static int       initd=0;
++
++              /*
++               * Now, in addition to (or instead of) printing this stuff out
++               * (which is a buffered operation), also tuck it away into a
++               * corner of memory which can be examined post-crash in kdb.
++               */
++              if (!initd) {
++                      dgap_trcbuf = (char *) vmalloc(dgap_trcbuf_size);
++                      if(!dgap_trcbuf) {
++                              failed = TRUE;
++                              printk("dgap: tracing init failed!\n");
++                              return;
++                      }
++
++                      memset(dgap_trcbuf, '\0',  dgap_trcbuf_size);
++                      dgap_trcbufi = 0;
++                      initd++;
++
++                      printk("dgap: tracing enabled - " TRC_DTRC
++                              " 0x%lx 0x%x\n",
++                              (unsigned long)dgap_trcbuf,
++                              dgap_trcbuf_size);
++              }
++
++#  if defined(TRC_ON_OVERFLOW_WRAP_AROUND)
++              /*
++               * This is the less CPU-intensive way to do things.  We simply
++               * wrap around before we fall off the end of the buffer.  A
++               * tilde (~) demarcates the current end of the trace.
++               *
++               * This method should be used if you are concerned about race
++               * conditions as it is less likely to affect the timing of
++               * things.
++               */
++
++              if (dgap_trcbufi + lenbuf >= dgap_trcbuf_size) {
++                      /* We are wrapping, so wipe out the last tilde. */
++                      dgap_trcbuf[dgap_trcbufi] = '\0';
++                      /* put the new string at the beginning of the buffer */
++                      dgap_trcbufi = 0;
++              }
++
++              strcpy(&dgap_trcbuf[dgap_trcbufi], buf);
++              dgap_trcbufi += lenbuf;
++              dgap_trcbuf[dgap_trcbufi] = '~';
++
++#  elif defined(TRC_ON_OVERFLOW_SHIFT_BUFFER)
++              /*
++               * This is the more CPU-intensive way to do things.  If we
++               * venture into the last 1/8 of the buffer, we shift the
++               * last 7/8 of the buffer forward, wiping out the first 1/8.
++               * Advantage: No wrap-around, only truncation from the
++               * beginning.
++               *
++               * This method should not be used if you are concerned about
++               * timing changes affecting the behaviour of the driver (ie,
++               * race conditions).
++               */
++              strcpy(&dgap_trcbuf[dgap_trcbufi], buf);
++              dgap_trcbufi += lenbuf;
++              dgap_trcbuf[dgap_trcbufi] = '~';
++              dgap_trcbuf[dgap_trcbufi+1] = '\0';
++
++              /* If we're near the end of the trace buffer... */
++              if (dgap_trcbufi > (dgap_trcbuf_size/8)*7) {
++                      /* Wipe out the first eighth to make some more room. */
++                      strcpy(dgap_trcbuf, &dgap_trcbuf[dgap_trcbuf_size/8]);
++                      dgap_trcbufi = strlen(dgap_trcbuf)-1;
++                      /* Plop overflow message at the top of the buffer. */
++                      bcopy(TRC_OVERFLOW, dgap_trcbuf, strlen(TRC_OVERFLOW));
++              }
++#  else
++#   error "TRC_ON_OVERFLOW_WRAP_AROUND or TRC_ON_OVERFLOW_SHIFT_BUFFER?"
++#  endif
++      }
++      DGAP_UNLOCK(dgap_tracef_lock, flags);
++
++# endif /* defined(TRC_TO_KMEM) */
++}
++
++#endif /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
++
++
++/*
++ * dgap_tracer_free()
++ *
++ *
++ */
++void dgap_tracer_free(void)
++{
++      if(dgap_trcbuf)
++              vfree(dgap_trcbuf);
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_trace.h 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_trace.h      2003-09-27 11:38:20.963341472 +0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ *
++ *****************************************************************************
++ * Header file for dgap_trace.c
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ */
++
++#ifndef __DGAP_TRACE_H
++#define __DGAP_TRACE_H
++
++#include "dgap_driver.h"
++
++void dgap_tracef(const char *fmt, ...);
++void dgap_tracer_free(void);
++
++#endif
++
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_tty.c   2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.c        2003-09-27 11:38:20.970340408 +0800
+@@ -0,0 +1,3935 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *
++ *    NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
++ *
++ *    This is shared code between Digi's CVS archive and the
++ *    Linux Kernel sources.
++ *    Changing the source just for reformatting needlessly breaks
++ *    our CVS diff history.
++ *
++ *    Send any bug fixes/changes to:  Eng.Linux at digi dot com.
++ *    Thank you.
++ */
++
++/************************************************************************
++ *
++ * This file implements the tty driver functionality for the
++ * FEP5 based product lines.
++ *
++ ************************************************************************
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ */
++
++#include "dgap_driver.h"
++#include <linux/ctype.h>
++#include "dgap_types.h"
++#include "dgap_fep5.h"
++#include "dgap_parse.h"
++
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++
++#ifndef _POSIX_VDISABLE
++#define   _POSIX_VDISABLE '\0'
++#endif
++
++/*
++ * external variables
++ */
++extern int              dgap_debug;
++extern int              dgap_rawreadok;
++extern spinlock_t     dgap_global_lock;
++
++/*
++ * internal variables
++ */
++static struct board_t *dgap_BoardsByMajor[256];
++static u32            dgap_count = 500;
++static uchar          *dgap_TmpWriteBuf = NULL;
++static DECLARE_MUTEX(dgap_TmpWriteSem);
++
++/*
++ * Default transparent print information.
++ */
++static struct digi_t digi_init = {
++      DIGI_COOK,              /* Flags                        */
++      100,                    /* Max CPS                      */
++      50,                     /* Max chars in print queue     */
++      100,                    /* Printer buffer size          */
++      4,                      /* size of printer on string    */
++      4,                      /* size of printer off string   */
++      "\033[5i",              /* ANSI printer on string ]     */
++      "\033[4i",              /* ANSI printer off string ]    */
++      "ansi"                  /* default terminal type        */
++};
++
++
++/*
++ * Define a local default termios struct. All ports will be created
++ * with this termios initially.
++ *
++ * This defines a raw port at 9600 baud, 8 data bits, no parity,
++ * 1 stop bit.
++ */
++static struct termios DefaultTermios =
++{
++      c_iflag: (DEFAULT_IFLAGS),      /* iflags */
++      c_oflag: (DEFAULT_OFLAGS),      /* oflags */
++      c_cflag: (DEFAULT_CFLAGS),      /* cflags */
++      c_lflag: (DEFAULT_LFLAGS),      /* lflags */
++      c_cc:    INIT_C_CC,
++      c_line:  0,
++};
++
++/* Our function prototypes */
++static void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, u32 ncmds);
++static void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, u32 ncmds);
++static int dgap_tty_open(struct tty_struct *tty, struct file *file);
++static void dgap_tty_close(struct tty_struct *tty, struct file *file);
++static int block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch);
++static void dgap_carrier(struct channel_t *ch);
++static int dgap_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
++static int dgap_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
++static int dgap_tty_digigeta(struct tty_struct *tty, struct digi_t *retinfo);
++static int dgap_tty_digiseta(struct tty_struct *tty, struct digi_t *new_info);
++static int dgap_tty_write_room(struct tty_struct* tty);
++static void dgap_tty_put_char(struct tty_struct *tty, unsigned char c);
++static void dgap_tty_set_termios(struct tty_struct *tty, struct termios *old_termios);
++static int dgap_tty_chars_in_buffer(struct tty_struct* tty);
++static void dgap_tty_start(struct tty_struct *tty);
++static void dgap_tty_stop(struct tty_struct *tty);
++static void dgap_tty_throttle(struct tty_struct *tty);
++static void dgap_tty_unthrottle(struct tty_struct *tty);
++static void dgap_tty_flush_chars(struct tty_struct *tty);
++static void dgap_tty_flush_buffer(struct tty_struct *tty);
++static void dgap_tty_hangup(struct tty_struct *tty);
++static int dgap_wait_for_drain(struct tty_struct *tty);
++static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int *value);
++static int dgap_get_modem_info(struct channel_t *ch, unsigned int *value);
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++ static int dgap_tty_tiocmget(struct tty_struct *tty, struct file *file);
++ static int dgap_tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
++#endif
++
++
++/************************************************************************
++ *
++ * TTY Initialization/Cleanup Functions
++ *
++ ************************************************************************/
++
++/*
++ * dgap_tty_preinit()
++ *
++ * Initialize any global tty related data before we download any boards.
++ */
++int dgap_tty_preinit(void)
++{
++      unsigned long flags;
++
++      DGAP_LOCK(dgap_global_lock, flags);
++
++      /*
++       * Allocate a buffer for doing the copy from user space to
++       * kernel space in dgap_input().  We only use one buffer and
++       * control access to it with a semaphore.  If we are paging, we
++       * are already in trouble so one buffer won't hurt much anyway.
++       */
++      dgap_TmpWriteBuf = kmalloc(WRITEBUFLEN, GFP_ATOMIC);
++
++      if (!dgap_TmpWriteBuf) {
++              DGAP_UNLOCK(dgap_global_lock, flags);
++              DPR_INIT(("unable to allocate tmp write buf"));
++              return (-ENOMEM);
++      }
++
++        DGAP_UNLOCK(dgap_global_lock, flags);
++        return(0);
++}
++
++
++/*
++ * dgap_tty_register()
++ *
++ * Init the tty subsystem for this board.
++ */
++int dgap_tty_register(struct board_t *brd)
++{
++      int rc = 0;
++      char buf[MAXTTYNAMELEN];
++      char *ptr;
++
++      DPR_INIT(("tty_register start"));
++
++      buf[0] = '\0';
++
++      ptr = dgap_get_config_letters(brd, buf);
++
++        memset(&brd->SerialDriver, 0, sizeof(struct tty_driver));
++      memset(&brd->PrintDriver, 0, sizeof(struct tty_driver));
++
++      brd->SerialDriver.magic = TTY_DRIVER_MAGIC;
++
++      snprintf(brd->SerialName, MAXTTYNAMELEN, "tty[%s]", buf[0] != '\0' ? buf : "");
++      brd->SerialDriver.name = brd->SerialName;
++      brd->SerialDriver.name_base = 0;
++      brd->SerialDriver.major = 0;
++      brd->SerialDriver.minor_start = 0;
++      brd->SerialDriver.num = MAXPORTS;
++      brd->SerialDriver.type = TTY_DRIVER_TYPE_SERIAL;
++      brd->SerialDriver.subtype = SERIAL_TYPE_NORMAL;
++      brd->SerialDriver.init_termios = DefaultTermios;
++      brd->SerialDriver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS);
++      brd->SerialDriver.driver_name = DRVSTR;
++
++      /*
++       * The kernel wants space to store pointers to
++       * tty_struct's and termios's.
++       */
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++      brd->SerialDriver.ttys = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++      if (!brd->SerialDriver.ttys)
++              return(-ENOMEM);
++
++      brd->SerialDriver.refcount = brd->TtyRefCnt;
++#else
++      brd->SerialDriver.table = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++      if (!brd->SerialDriver.table)
++              return(-ENOMEM);
++
++      brd->SerialDriver.refcount = &brd->TtyRefCnt;
++
++#endif
++
++      brd->SerialDriver.termios = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++      if (!brd->SerialDriver.termios)
++              return(-ENOMEM);
++
++      brd->SerialDriver.termios_locked = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++      if (!brd->SerialDriver.termios_locked)
++              return(-ENOMEM);
++
++      /*
++       * Entry points for driver.  Called by the kernel from
++       * tty_io.c and n_tty.c.
++       */
++      brd->SerialDriver.open = dgap_tty_open;
++      brd->SerialDriver.close = dgap_tty_close;
++      brd->SerialDriver.ioctl = dgap_tty_ioctl;
++      brd->SerialDriver.write = dgap_tty_write;
++      brd->SerialDriver.write_room = dgap_tty_write_room;
++      brd->SerialDriver.put_char = dgap_tty_put_char;
++      brd->SerialDriver.set_termios = dgap_tty_set_termios;
++      brd->SerialDriver.chars_in_buffer = dgap_tty_chars_in_buffer;
++      brd->SerialDriver.stop = dgap_tty_stop;
++      brd->SerialDriver.start = dgap_tty_start;
++      brd->SerialDriver.throttle = dgap_tty_throttle;
++      brd->SerialDriver.unthrottle = dgap_tty_unthrottle;
++      brd->SerialDriver.flush_chars = dgap_tty_flush_chars;
++      brd->SerialDriver.flush_buffer = dgap_tty_flush_buffer;
++      brd->SerialDriver.hangup = dgap_tty_hangup;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++      brd->SerialDriver.owner = THIS_MODULE;
++      brd->SerialDriver.tiocmget = dgap_tty_tiocmget;
++      brd->SerialDriver.tiocmset = dgap_tty_tiocmset;
++#endif
++
++      /*
++       * If we're doing transparent print, we have to do all of the above
++       * again, seperately so we don't get the LD confused about what major
++       * we are when we get into the dgap_tty_open() routine.
++       */
++      brd->PrintDriver.magic = TTY_DRIVER_MAGIC;
++      snprintf(brd->PrintName, MAXTTYNAMELEN, "pr[%s]", buf[0] != '\0' ? buf : "");
++      brd->PrintDriver.name = brd->PrintName;
++      brd->PrintDriver.name_base = 0;
++      brd->PrintDriver.major = 0;
++      brd->PrintDriver.minor_start = 0;
++      brd->PrintDriver.num = MAXPORTS;
++      brd->PrintDriver.type = TTY_DRIVER_TYPE_SERIAL;
++      brd->PrintDriver.subtype = SERIAL_TYPE_NORMAL;
++      brd->PrintDriver.init_termios = DefaultTermios;
++      brd->PrintDriver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS);
++      brd->PrintDriver.driver_name = DRVSTR;
++
++      /*
++       * The kernel wants space to store pointers to
++       * tty_struct's and termios's.  Must be seperate from
++       * the Serial Driver so we don't get confused
++       */
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++      brd->PrintDriver.ttys = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++      if (!brd->PrintDriver.ttys)
++              return(-ENOMEM);
++
++      brd->PrintDriver.refcount = brd->TtyRefCnt;
++#else
++      brd->PrintDriver.table = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL);
++      if (!brd->PrintDriver.table)
++              return(-ENOMEM);
++
++      brd->PrintDriver.refcount = &brd->TtyRefCnt;
++
++#endif
++
++      brd->PrintDriver.termios = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++      if (!brd->PrintDriver.termios)
++              return(-ENOMEM);
++
++      brd->PrintDriver.termios_locked = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct termios *), GFP_KERNEL);
++
++      if (!brd->PrintDriver.termios_locked)
++              return(-ENOMEM);
++
++      /*
++       * Entry points for driver.  Called by the kernel from
++       * tty_io.c and n_tty.c.
++       */
++      brd->PrintDriver.open = dgap_tty_open;
++      brd->PrintDriver.close = dgap_tty_close;
++      brd->PrintDriver.ioctl = dgap_tty_ioctl;
++      brd->PrintDriver.write = dgap_tty_write;
++      brd->PrintDriver.write_room = dgap_tty_write_room;
++      brd->PrintDriver.put_char = dgap_tty_put_char;
++      brd->PrintDriver.set_termios = dgap_tty_set_termios;
++      brd->PrintDriver.chars_in_buffer = dgap_tty_chars_in_buffer;
++      brd->PrintDriver.stop = dgap_tty_stop;
++      brd->PrintDriver.start = dgap_tty_start;
++      brd->PrintDriver.throttle = dgap_tty_throttle;
++      brd->PrintDriver.unthrottle = dgap_tty_unthrottle;
++      brd->PrintDriver.flush_chars = dgap_tty_flush_chars;
++      brd->PrintDriver.flush_buffer = dgap_tty_flush_buffer;
++      brd->PrintDriver.hangup = dgap_tty_hangup;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++      brd->SerialDriver.owner = THIS_MODULE;
++      brd->PrintDriver.tiocmget = dgap_tty_tiocmget;
++      brd->PrintDriver.tiocmset = dgap_tty_tiocmset;
++#endif
++
++      if (!brd->dgap_Major_Serial_Registered) {
++              /* Register tty devices */
++              rc = tty_register_driver(&brd->SerialDriver);
++              if (rc < 0) {
++                      APR(("Can't register tty device (%d)\n", rc));
++                      return(rc);
++              }
++              brd->dgap_Major_Serial_Registered = TRUE;
++              dgap_BoardsByMajor[brd->SerialDriver.major] = brd;
++              brd->dgap_Serial_Major = brd->SerialDriver.major;
++      }
++
++      if (!brd->dgap_Major_TransparentPrint_Registered) {
++              /* Register Transparent Print devices */
++              rc = tty_register_driver(&brd->PrintDriver);
++              if (rc < 0) {
++                      APR(("Can't register Transparent Print device (%d)\n", rc));
++                      return(rc);
++              }
++              brd->dgap_Major_TransparentPrint_Registered = TRUE;
++              dgap_BoardsByMajor[brd->PrintDriver.major] = brd;
++              brd->dgap_TransparentPrint_Major = brd->PrintDriver.major;
++      }
++
++      DPR_INIT(("DGAP REGISTER TTY: MAJORS: %d %d\n", brd->SerialDriver.major,
++              brd->PrintDriver.major));
++
++      return (rc);
++}
++
++
++/*
++ * dgap_tty_init()
++ *
++ * Init the tty subsystem.  Called once per board after board has been
++ * downloaded and init'ed.
++ */
++int dgap_tty_init(struct board_t *brd)
++{
++      int i;
++      int tlw;
++      uint true_count = 0;
++      uchar *vaddr;
++      uchar modem = 0;
++      struct channel_t *ch;
++      struct bs_t *bs;
++      struct cm_t *cm;
++
++      if (!brd)
++              return (-ENXIO);
++
++      DPR_INIT(("dgap_tty_init start\n"));
++
++      /*
++       * Initialize board structure elements.
++       */
++
++      vaddr = brd->re_map_membase;
++      true_count = readw((vaddr + NCHAN));
++
++      brd->nasync = dgap_config_get_number_of_ports(brd);
++
++      if (!brd->nasync) {
++              brd->nasync = brd->maxports;
++      }
++
++      if (brd->nasync > brd->maxports) {
++              brd->nasync = brd->maxports;
++      }
++
++      if (true_count != brd->nasync) {
++              if ((brd->type == PPCM) && (true_count == 64)) {
++                      APR(("***WARNING**** %s configured for %d ports, has %d ports.\nPlease make SURE the EBI cable running from the card\nto each EM module is plugged into EBI IN!\n",
++                              brd->name, brd->nasync, true_count));
++              }
++              else if ((brd->type == PPCM) && (true_count == 0)) {
++                      APR(("***WARNING**** %s configured for %d ports, has %d ports.\nPlease make SURE the EBI cable running from the card\nto each EM module is plugged into EBI IN!\n",
++                              brd->name, brd->nasync, true_count));
++              }
++              else {
++                      APR(("***WARNING**** %s configured for %d ports, has %d ports.\n",
++                              brd->name, brd->nasync, true_count));
++              }
++
++              brd->nasync = true_count;
++
++              /* If no ports, don't bother going any further */
++              if (!brd->nasync) {
++                      brd->state = BOARD_FAILED;
++                      brd->dpastatus = BD_NOFEP;
++                      return(-ENXIO);
++              }
++      }
++
++      /*
++       * Allocate channel memory that might not have been allocated
++       * when the driver was first loaded.
++       */
++      for (i = 0; i < brd->nasync; i++) {
++              if (!brd->channels[i]) {
++                      brd->channels[i] = dgap_driver_kzmalloc(sizeof(struct channel_t), GFP_ATOMIC);
++                      if (!brd->channels[i]) {
++                              DPR_CORE(("%s:%d Unable to allocate memory for channel struct\n",
++                                  __FILE__, __LINE__));
++                      }
++              }
++      }
++
++      ch = brd->channels[0];
++      vaddr = brd->re_map_membase;
++
++      bs = (struct bs_t *) ((ulong) vaddr + CHANBUF);
++      cm = (struct cm_t *) ((ulong) vaddr + CMDBUF);
++
++      brd->bd_bs = bs;
++
++      /* Set up channel variables */
++      for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) {
++
++              if (!brd->channels[i])
++                      continue;
++
++              DGAP_SPINLOCK_INIT(ch->ch_lock);
++
++              /* Store all our magic numbers */
++              ch->magic = DGAP_CHANNEL_MAGIC;
++              ch->ch_tun.magic = DGAP_UNIT_MAGIC;
++              ch->ch_pun.magic = DGAP_UNIT_MAGIC;
++
++              ch->ch_vaddr = vaddr;
++              ch->ch_bs = bs;
++              ch->ch_cm = cm;
++              ch->ch_bd = brd;
++              ch->ch_portnum = i;
++              ch->ch_digi = digi_init;
++
++              /*
++               * Set up digi dsr and dcd bits based on altpin flag.
++               */
++              if (dgap_config_get_altpin(brd)) {
++                      ch->ch_dsr      = DM_CD;
++                      ch->ch_cd       = DM_DSR;
++                      ch->ch_digi.digi_flags |= DIGI_ALTPIN;
++              }
++              else {
++                      ch->ch_cd       = DM_CD;
++                      ch->ch_dsr      = DM_DSR;
++              }
++
++              ch->ch_taddr = vaddr + ((ch->ch_bs->tx_seg) << 4);
++              ch->ch_raddr = vaddr + ((ch->ch_bs->rx_seg) << 4);
++              ch->ch_tx_win = 0;
++              ch->ch_rx_win = 0;
++              ch->ch_tsize = readw(&(ch->ch_bs->tx_max)) + 1;
++              ch->ch_rsize = readw(&(ch->ch_bs->rx_max)) + 1;
++              ch->ch_tstart = 0;
++              ch->ch_rstart = 0;
++
++              /* .25 second delay */
++              ch->ch_close_delay = 250;
++
++              /*
++               * Set queue water marks, interrupt mask,
++               * and general tty parameters.
++               */
++              ch->ch_tlw = tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) : ch->ch_tsize / 2;
++
++              dgap_cmdw(ch, STLOW, tlw, 0);
++
++              dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0);
++
++              dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0);
++
++              ch->ch_mistat = readb(&(ch->ch_bs->m_stat));
++
++              init_waitqueue_head(&ch->ch_flags_wait);
++              init_waitqueue_head(&ch->ch_tun.un_flags_wait);
++              init_waitqueue_head(&ch->ch_pun.un_flags_wait);
++
++              /* Turn on all modem interrupts for now */
++              modem = (DM_CD | DM_DSR | DM_CTS | DM_RI);
++              writeb(modem, &(ch->ch_bs->m_int));
++      }
++
++      /*
++       * Set edelay to 0 if interrupts are turned on,
++       * otherwise set edelay to the usual 100.
++       */
++      if (brd->intr_used)
++              writew(0, &(brd->bd_bs->edelay));
++      else
++              writew(100, &(brd->bd_bs->edelay));
++
++      writeb(1, &(brd->bd_bs->idata));
++
++      DPR_INIT(("dgap_tty_init finish\n"));
++
++      return (0);
++}
++
++
++/*
++ * dgap_tty_post_uninit()
++ *
++ * UnInitialize any global tty related data.
++ */
++void dgap_tty_post_uninit(void)
++{
++      if (dgap_TmpWriteBuf) {
++              kfree(dgap_TmpWriteBuf);
++              dgap_TmpWriteBuf = NULL;
++      }
++}
++
++
++/*
++ * dgap_tty_uninit()
++ *
++ * Uninitialize the TTY portion of this driver.  Free all memory and
++ * resources.
++ */
++void dgap_tty_uninit(struct board_t *brd)
++{
++      if (brd->dgap_Major_Serial_Registered) {
++              dgap_BoardsByMajor[brd->SerialDriver.major] = NULL;
++              brd->dgap_Serial_Major = 0;
++              tty_unregister_driver(&brd->SerialDriver);
++              brd->dgap_Major_Serial_Registered = FALSE;
++      }
++
++      if (brd->dgap_Major_TransparentPrint_Registered) {
++              dgap_BoardsByMajor[brd->PrintDriver.major] = 0;
++              brd->dgap_TransparentPrint_Major = 0;
++              tty_unregister_driver(&brd->PrintDriver);
++              brd->dgap_Major_TransparentPrint_Registered = FALSE;
++      }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++      if (brd->SerialDriver.ttys) {
++              kfree(brd->SerialDriver.ttys);
++              brd->SerialDriver.ttys = NULL;
++      }
++      if (brd->PrintDriver.ttys) {
++              kfree(brd->PrintDriver.ttys);
++              brd->PrintDriver.ttys = NULL;
++        }
++#else
++      if (brd->SerialDriver.table) {
++              kfree(brd->SerialDriver.table);
++              brd->SerialDriver.table = NULL;
++      }
++      if (brd->PrintDriver.table) {
++              kfree(brd->PrintDriver.table);
++              brd->PrintDriver.table = NULL;
++        }
++#endif
++}
++
++
++/*=======================================================================
++ *
++ *      dgap_cmdb - Sends a 2 byte command to the FEP.
++ *
++ *              ch      - Pointer to channel structure.
++ *              cmd     - Command to be sent.
++ *              byte1   - Integer containing first byte to be sent.
++ *              byte2   - Integer containing second byte to be sent.
++ *              ncmds   - Wait until ncmds or fewer cmds are left
++ *                        in the cmd buffer before returning.
++ *
++ *=======================================================================*/
++void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, u32 ncmds)
++{
++      char            *vaddr = NULL;
++      struct cm_t     *cm_addr = NULL;
++      u16             head;
++        u16           tail;
++      u32             count;
++      u32             n;
++
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      /*
++       * Check if board is still alive.
++       */
++      if (ch->ch_bd->state == BOARD_FAILED) {
++              DPR_CORE(("%s:%d board is in failed state.\n", __FILE__, __LINE__));
++              return;
++        }
++
++      /*
++       * Make sure the pointers are in range before
++       * writing to the FEP memory.
++       */
++      vaddr = ch->ch_bd->re_map_membase;
++
++      if (!vaddr)
++              return;
++
++      cm_addr = (struct cm_t *) (vaddr + CMDBUF);
++      head = readw(&(cm_addr->cm_head));
++
++      /*
++       * Forget it if pointers out of range.
++       */
++      if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
++              DPR_CORE(("%s:%d pointers out of range, failing board!\n", __FILE__, __LINE__));
++              ch->ch_bd->state = BOARD_FAILED;
++              return;
++      }
++
++      /*
++       * Put the data in the circular command buffer.
++       */
++      writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
++      writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
++      writeb(byte1, (char *) (vaddr + head + CMDSTART + 2));
++      writeb(byte2, (char *) (vaddr + head + CMDSTART + 3));
++
++      head = (head + 4) & (CMDMAX - CMDSTART - 4);
++
++      writew(head, &(cm_addr->cm_head));
++
++      /*
++       * Wait if necessary before updating the head
++       * pointer to limit the number of outstanding
++       * commands to the FEP.   If the time spent waiting
++       * is outlandish, declare the FEP dead.
++       */
++      for (count = dgap_count ;;) {
++
++              head = readw(&(cm_addr->cm_head));
++              tail = readw(&(cm_addr->cm_tail));
++
++              n = (head - tail) & (CMDMAX - CMDSTART - 4);
++
++              if (n <= ncmds * sizeof(struct cm_t))
++                      break;
++
++              if (--count == 0) {
++                      DPR_CORE(("%s:%d failing board.\n",__FILE__, __LINE__));
++                      ch->ch_bd->state = BOARD_FAILED;
++                      return;
++              }
++              udelay(10);
++      }
++}
++
++
++/*=======================================================================
++ *
++ *      dgap_cmdw - Sends a 1 word command to the FEP.
++ *
++ *              ch      - Pointer to channel structure.
++ *              cmd     - Command to be sent.
++ *              word    - Integer containing word to be sent.
++ *              ncmds   - Wait until ncmds or fewer cmds are left
++ *                        in the cmd buffer before returning.
++ *
++ *=======================================================================*/
++void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, u32 ncmds)
++{
++      char            *vaddr = NULL;
++      struct cm_t     *cm_addr = NULL;
++      u16             head;
++      u16             tail;
++      u32             count;
++      u32             n;
++
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      /*
++       * Check if board is still alive.
++       */
++      if (ch->ch_bd->state == BOARD_FAILED) {
++              DPR_CORE(("%s:%d board is failed!\n", __FILE__, __LINE__));
++              return;
++      }
++
++      /*
++       * Make sure the pointers are in range before
++       * writing to the FEP memory.
++       */
++      vaddr = ch->ch_bd->re_map_membase;
++      if (!vaddr)
++              return;
++
++      cm_addr = (struct cm_t *) (vaddr + CMDBUF);
++      head = readw(&(cm_addr->cm_head));
++
++      /*
++       * Forget it if pointers out of range.
++       */
++      if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
++              DPR_CORE(("%s:%d Pointers out of range.  Failing board.\n",__FILE__, __LINE__));
++              ch->ch_bd->state = BOARD_FAILED;
++              return;
++      }
++
++      /*
++       * Put the data in the circular command buffer.
++       */
++      writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
++      writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
++      writew((u16) word, (char *) (vaddr + head + CMDSTART + 2));
++
++      head = (head + 4) & (CMDMAX - CMDSTART - 4);
++
++      writew(head, &(cm_addr->cm_head));
++
++      /*
++       * Wait if necessary before updating the head
++       * pointer to limit the number of outstanding
++       * commands to the FEP.   If the time spent waiting
++       * is outlandish, declare the FEP dead.
++       */
++      for (count = dgap_count ;;) {
++
++              head = readw(&(cm_addr->cm_head));
++              tail = readw(&(cm_addr->cm_tail));
++
++              n = (head - tail) & (CMDMAX - CMDSTART - 4);
++
++              if (n <= ncmds * sizeof(struct cm_t))
++                      break;
++
++              if (--count == 0) {
++                      DPR_CORE(("%s:%d Failing board.\n",__FILE__, __LINE__));
++                      ch->ch_bd->state = BOARD_FAILED;
++                      return;
++              }
++              udelay(10);
++      }
++}
++
++
++/*=======================================================================
++ *
++ *      dgap_wmove - Write data to FEP buffer.
++ *
++ *              ch      - Pointer to channel structure.
++ *              buf     - Poiter to characters to be moved.
++ *              cnt     - Number of characters to move.
++ *
++ *=======================================================================*/
++void dgap_wmove(struct channel_t *ch, char *buf, u32 cnt)
++{
++      int    n;
++      char   *taddr;
++      struct bs_t    *bs;
++      u32    head;
++
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      /*
++       * Check parameters.
++       */
++      bs   = ch->ch_bs;
++      head = readw(&(bs->tx_head));
++
++      /*
++       * If pointers are out of range, just return.
++       */
++      if ((cnt > ch->ch_tsize) || (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize) {
++              DPR_CORE(("%s:%d pointer out of range", __FILE__, __LINE__));
++              return;
++      }
++
++      /*
++       * If the write wraps over the top of the circular buffer,
++       * move the portion up to the wrap point, and reset the
++       * pointers to the bottom.
++       */
++      n = ch->ch_tstart + ch->ch_tsize - head;
++
++      if (cnt >= n) {
++              cnt -= n;
++              taddr = ch->ch_taddr + head;
++              memcpy_toio(taddr, buf, n);
++              head = ch->ch_tstart;
++              buf += n;
++      }
++
++      /*
++       * Move rest of data.
++       */
++      taddr = ch->ch_taddr + head;
++      n = cnt;
++      memcpy_toio(taddr, buf, n);
++      head += cnt;
++
++      writew(head, &(bs->tx_head));
++}
++
++
++
++/*=======================================================================
++ *
++ *      dgap_param - Set Digi parameters.
++ *
++ *              struct tty_struct *     - TTY for port.
++ *
++ *=======================================================================*/
++int dgap_param(struct tty_struct *tty)
++{
++      struct termios *ts;
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct bs_t   *bs;
++      struct un_t   *un;
++      u32     head;
++      u32     cflag;
++      u32     iflag;
++      uchar   mval;
++      uchar   hflow;
++
++      if (!tty || tty->magic != TTY_MAGIC) {
++              return (-ENXIO);
++      }
++
++      un = (struct un_t *) tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC) {
++              return (-ENXIO);
++      }
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
++              return (-ENXIO);
++      }
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC) {
++              return (-ENXIO);
++      }
++
++        bs = ch->ch_bs;
++      if (bs == 0) {
++              return (-ENXIO);
++      }
++
++      DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n",
++              ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag));
++
++      ts = tty->termios;
++
++      /*
++       * If baud rate is zero, flush queues, and set mval to drop DTR.
++       */
++      if ((ch->ch_c_cflag & (CBAUD)) == 0) {
++
++              /* flush rx */
++              head = readw(&(ch->ch_bs->rx_head));
++              writew(head, &(ch->ch_bs->rx_tail));
++
++              /* flush tx */
++              head = readw(&(ch->ch_bs->tx_head));
++              /* Okay to have channel and board locks held calling this */
++              dgap_cmdw( ch, FLUSHTX, (u16) head, 0 );
++
++              /* Drop RTS and DTR */
++              ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch));
++              dgap_cmdb( ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0 );
++
++              mval = 0;
++      }
++      else {
++              /*
++               * Set baud rate, character size, and parity.
++               */
++
++              /*
++               * CBAUD has bit position 0x1000 set these days to indicate Linux
++               * baud rate remap.
++               * We use a different bit assignment for high speed.  Clear this
++               * bit out while grabbing the parts of "cflag" we want.
++               */
++              cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE);
++
++              /*
++               * HUPCL bit is used by FEP to indicate fast baud
++               * table is to be used.
++               */
++              if ((ch->ch_digi.digi_flags & DIGI_FAST) || (ch->ch_c_cflag & CBAUDEX))
++                      cflag |= HUPCL;
++
++
++              if ((ch->ch_c_cflag & CBAUDEX) && !(ch->ch_digi.digi_flags & DIGI_FAST)) {
++              /*
++               * The below code is trying to guarantee that only baud rates
++               * 115200, 230400, 460800, 921600 are remapped.  We use exclusive or
++               * because the various baud rates share common bit positions
++               * and therefore can't be tested for easily.
++               */
++                      tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX;
++                      int baudpart = 0;
++
++                      /* Map high speed requests to index into FEP's baud table */
++                      switch (tcflag) {
++                      case B57600 :
++                              baudpart = 1;
++                              break;
++#ifdef B76800
++                      case B76800 :
++                              baudpart = 2;
++                              break;
++#endif
++                      case B115200 :
++                              baudpart = 3;
++                              break;
++                      case B230400 :
++                              baudpart = 9;
++                              break;
++                      case B460800 :
++                              baudpart = 11;
++                              break;
++#ifdef B921600
++                      case B921600 :
++                              baudpart = 12;
++                              break;
++#endif
++                      default:
++                              baudpart = 0;
++                      }
++
++                      if (baudpart)
++                              cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart;
++              }
++
++              cflag &= 0xffff;
++
++              if (cflag != ch->ch_fepcflag) {
++                      ch->ch_fepcflag = (u16) (cflag & 0xffff);
++
++                      /* Okay to have channel and board locks held calling this */
++                      dgap_cmdw(ch, SCFLAG, (u16) cflag, 0);
++              }
++
++              mval = D_DTR(ch) | D_RTS(ch);
++      }
++
++      /*
++       * Get input flags.
++       */
++      iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | IXON | IXANY | IXOFF);
++
++      if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) {
++              iflag &= ~(IXON | IXOFF);
++              ch->ch_c_iflag &= ~(IXON | IXOFF);
++      }
++
++      if (ch->ch_digi.digi_flags & DIGI_ALTPIN)
++              iflag |= IALTPIN ;
++
++      if (iflag != ch->ch_fepiflag) {
++              ch->ch_fepiflag = iflag;
++
++              /* Okay to have channel and board locks held calling this */
++              dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0);
++      }
++
++      /*
++       * Select hardware handshaking.
++       */
++      hflow = 0;
++
++      if (ch->ch_c_cflag & CRTSCTS) {
++              hflow |= (D_RTS(ch) | D_CTS(ch));
++      }
++      if (ch->ch_digi.digi_flags & RTSPACE)
++              hflow |= D_RTS(ch);
++      if (ch->ch_digi.digi_flags & DTRPACE)
++              hflow |= D_DTR(ch);
++      if (ch->ch_digi.digi_flags & CTSPACE)
++              hflow |= D_CTS(ch);
++      if (ch->ch_digi.digi_flags & DSRPACE)
++              hflow |= D_DSR(ch);
++      if (ch->ch_digi.digi_flags & DCDPACE)
++              hflow |= D_CD(ch);
++
++      if (hflow != ch->ch_hflow) {
++              ch->ch_hflow = hflow;
++
++              /* Okay to have channel and board locks held calling this */
++              dgap_cmdb(ch, SHFLOW, (uchar) hflow, 0xff, 0);
++        }
++
++      /*
++       * Set modem control lines.
++       */
++      mval ^= ch->ch_mforce & (mval ^ ch->ch_mval);
++
++      if (ch->ch_mostat ^ mval) {
++              ch->ch_mostat = mval;
++
++              /* Okay to have channel and board locks held calling this */
++              dgap_cmdb(ch, SMODEM, (uchar) mval, D_RTS(ch)|D_DTR(ch), 0);
++      }
++
++      /*
++       * Read modem signals, and then call carrier function.
++       */
++      ch->ch_mistat = readb(&(bs->m_stat));
++      dgap_carrier(ch);
++
++      /*
++       * Set the start and stop characters.
++       */
++      if (ch->ch_startc != ch->ch_fepstartc || ch->ch_stopc != ch->ch_fepstopc) {
++              ch->ch_fepstartc = ch->ch_startc;
++              ch->ch_fepstopc =  ch->ch_stopc;
++
++              /* Okay to have channel and board locks held calling this */
++              dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0);
++      }
++
++      /*
++       * Set the Auxiliary start and stop characters.
++       */
++      if (ch->ch_astartc != ch->ch_fepastartc || ch->ch_astopc != ch->ch_fepastopc) {
++              ch->ch_fepastartc = ch->ch_astartc;
++              ch->ch_fepastopc = ch->ch_astopc;
++
++              /* Okay to have channel and board locks held calling this */
++              dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0);
++      }
++
++      DPR_PARAM(("param finish\n"));
++
++      return (0);
++}
++
++
++/*
++ * parity_scan()
++ *
++ * Convert the FEP5 way of reporting parity errors and breaks into
++ * the Linux line discipline way.
++ */
++static void parity_scan(struct channel_t *ch, unsigned char *cbuf, unsigned char *fbuf, int *len)
++{
++      int l = *len;
++      int count = 0;
++      unsigned char *in, *cout, *fout;
++      unsigned char c;
++
++      in = cbuf;
++      cout = cbuf;
++      fout = fbuf;
++
++      DPR_PSCAN(("parity_scan start\n"));
++
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      while (l--) {
++              c = *in++;
++              switch (ch->pscan_state) {
++              default:
++                      /* reset to sanity and fall through */
++                      ch->pscan_state = 0;
++
++              case 0:
++                      /* No FF seen yet */
++                      if (c == (unsigned char) '\377') {
++                              /* delete this character from stream */
++                              ch->pscan_state = 1;
++                      } else {
++                              *cout++ = c;
++                              *fout++ = TTY_NORMAL;
++                              count += 1;
++                      }
++                      break;
++
++              case 1:
++                      /* first FF seen */
++                      if (c == (unsigned char) '\377') {
++                              /* doubled ff, transform to single ff */
++                              *cout++ = c;
++                              *fout++ = TTY_NORMAL;
++                              count += 1;
++                              ch->pscan_state = 0;
++                      } else {
++                              /* save value examination in next state */
++                              ch->pscan_savechar = c;
++                              ch->pscan_state = 2;
++                      }
++                      break;
++
++              case 2:
++                      /* third character of ff sequence */
++
++                      *cout++ = c;
++
++                      if (ch->pscan_savechar == 0x0) {
++
++                              if (c == 0x0) {
++                                      DPR_PSCAN(("parity_scan in 3rd char of ff seq. c: %x setting break.\n", c));
++                                      *fout++ = TTY_BREAK;
++                              }
++                              else {
++                                      DPR_PSCAN(("parity_scan in 3rd char of ff seq. c: %x setting parity.\n", c));
++                                      *fout++ = TTY_PARITY;
++                              }
++                      }
++                      else {
++                              DPR_PSCAN(("%s:%d Logic Error.\n", __FILE__, __LINE__));
++                      }
++
++                      count += 1;
++                      ch->pscan_state = 0;
++              }
++      }
++      *len = count;
++      DPR_PSCAN(("parity_scan finish\n"));
++}
++
++
++/*=======================================================================
++ *
++ *      dgap_input - Process received data.
++ *
++ *              ch      - Pointer to channel structure.
++ *
++ *=======================================================================*/
++void dgap_input(struct channel_t *ch)
++{
++      struct board_t *bd;
++      struct bs_t     *bs;
++      struct tty_struct *tp;
++      uint    rmask;
++      uint    head;
++      uint    tail;
++      int     data_len;
++      ulong   lock_flags;
++      ulong   lock_flags2;
++      int flip_len;
++      int len = 0;
++      int n = 0;
++      char *buf;
++      uchar tmpchar;
++      int s = 0;
++
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      tp = ch->ch_tun.un_tty;
++
++      bs  = ch->ch_bs;
++      if (!bs) {
++              return;
++      }
++
++      bd = ch->ch_bd;
++      if(!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_READ(("dgap_input start\n"));
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      /*
++       *      Figure the number of characters in the buffer.
++       *      Exit immediately if none.
++       */
++
++      rmask = ch->ch_rsize - 1;
++
++      head = readw(&(bs->rx_head));
++      head &= rmask;
++      tail = readw(&(bs->rx_tail));
++      tail &= rmask;
++
++      data_len = (head - tail) & rmask;
++
++      if (data_len == 0) {
++              writeb(1, &(bs->idata));
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              DPR_READ(("No data on port %d\n", ch->ch_portnum));
++              return;
++      }
++
++      /*
++       *      If the device is not open, or CREAD is off, flush
++       *      input data and return immediately.
++       */
++      if (!tp || (tp->magic != TTY_MAGIC) || !(ch->ch_tun.un_flags & UN_ISOPEN) ||
++          !(tp->termios->c_cflag & CREAD) || (ch->ch_tun.un_flags & UN_CLOSING)) {
++
++              DPR_READ(("input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum));
++              DPR_READ(("input. tp: %p tp->magic: %x MAGIC:%x ch flags: %x\n",
++                      tp, tp ? tp->magic : 0, TTY_MAGIC, ch->ch_tun.un_flags));
++              writew(head, &(bs->rx_tail));
++              writeb(1, &(bs->idata));
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return;
++      }
++
++      /*
++       * If we are throttled, simply don't read any data.
++       */
++      if (ch->ch_flags & CH_RXBLOCK) {
++              writeb(1, &(bs->idata));
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              DPR_READ(("Port %d throttled, not reading any data. head: %x tail: %x\n",
++                      ch->ch_portnum, head, tail));
++              return;
++      }
++
++      /*
++       *      Ignore oruns.
++       */
++      tmpchar = readb(&(bs->orun));
++      if (tmpchar) {
++              writeb(0, &(bs->orun));
++      }
++
++      DPR_READ(("dgap_input start 2\n"));
++
++      /*
++       * If the rxbuf is empty and we are not throttled, put as much
++       * as we can directly into the linux TTY flip buffer.
++       * The dgap_rawreadok case takes advantage of carnal knowledge that
++       * the char_buf and the flag_buf are next to each other and
++       * are each of (2 * TTY_FLIPBUF_SIZE) size.
++       *
++       * NOTE: if(!tty->real_raw), the call to ldisc.receive_buf
++       *       actually still uses the flag buffer, so you can't
++       *       use it for input data
++       */
++      if (dgap_rawreadok) {
++              if (tp->real_raw) {
++                      flip_len = MYFLIPLEN;
++              }
++              else {
++                      flip_len = 2 * TTY_FLIPBUF_SIZE;
++              }
++      }
++      else {
++              flip_len = TTY_FLIPBUF_SIZE - tp->flip.count;
++      }
++
++      len = min(data_len, flip_len);
++      len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
++
++      if (len <= 0) {
++              writeb(1, &(bs->idata));
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              DPR_READ(("dgap_input 1 - finish\n"));
++              return;
++      }
++
++      /*
++       * If we're bypassing flip buffers on rx, we can blast it
++       * right into the beginning of the buffer.
++       */
++      if (dgap_rawreadok) {
++              if (tp->real_raw) {
++                      buf = ch->ch_bd->flipbuf;
++              }
++              else {
++                      buf = tp->flip.char_buf;
++              }
++      }
++      else {
++              buf = tp->flip.char_buf_ptr;
++      }
++
++      n = len;
++
++      /*
++       * n now contains the most amount of data we can copy,
++       * bounded either by the flip buffer size or the amount
++       * of data the card actually has pending...
++       */
++      while (n) {
++
++              s = ((head >= tail) ? head : ch->ch_rsize) - tail;
++              s = min(s, n);
++
++              if (s <= 0)
++                      break;
++
++
++              memcpy_fromio(buf, (char *) ch->ch_raddr + tail, s);
++
++              tail += s;
++              buf += s;
++              n -= s;
++              /* Flip queue if needed */
++              tail &= rmask;
++      }
++
++      /*
++       * In high performance mode, we don't have to update
++       * flag_buf or any of the counts or pointers into flip buf.
++       */
++      if (!dgap_rawreadok) {
++              if (I_PARMRK(tp)) {
++                      parity_scan(ch, tp->flip.char_buf_ptr,
++                              tp->flip.flag_buf_ptr, &len);
++              }
++              else {
++                      memset(tp->flip.flag_buf_ptr, 0, len);
++              }
++
++              tp->flip.char_buf_ptr += len;
++              tp->flip.flag_buf_ptr += len;
++              tp->flip.count += len;
++
++      }
++      else if (!tp->real_raw) {
++              if (I_PARMRK(tp)) {
++                      parity_scan(ch, tp->flip.char_buf,
++                              tp->flip.flag_buf, &len);
++              } else {
++                      memset(tp->flip.flag_buf, 0, len);
++              }
++      }
++
++      /*
++       * If we're doing raw reads, jam it right into the
++       * line disc bypassing the flip buffers.
++       */
++      if (dgap_rawreadok) {
++              if (tp->real_raw) {
++                      writew(tail, &(bs->rx_tail));
++                      writeb(1, &(bs->idata));
++
++                      /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++                      DPR_READ(("dgap_input. %d real_raw len:%d calling receive_buf for buffer for board %d\n",
++                               __LINE__, len, ch->ch_bd->boardnum));
++                      tp->ldisc.receive_buf(tp, ch->ch_bd->flipbuf, NULL, len);
++              }
++              else {
++                      writew(tail, &(bs->rx_tail));
++                      writeb(1, &(bs->idata));
++
++                      /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++                      DPR_READ(("dgap_input. %d not real_raw len:%d calling receive_buf for buffer for board %d\n",
++                               __LINE__, len, ch->ch_bd->boardnum));
++                      tp->ldisc.receive_buf(tp, tp->flip.char_buf, tp->flip.flag_buf, len);
++              }
++      }
++      else {
++              writew(tail, &(bs->rx_tail));
++              writeb(1, &(bs->idata));
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++              DPR_READ(("dgap_input. %d not dgap_read raw okay scheduling flip\n", __LINE__));
++              tty_schedule_flip(tp);
++      }
++
++      DPR_READ(("dgap_input - finish\n"));
++}
++
++
++
++/*=======================================================================
++ *
++ *      dgap_event - FEP to host event processing routine.
++ *
++ *              bd     - Board of current event.
++ *
++ *=======================================================================*/
++int dgap_event(struct board_t *bd)
++{
++      struct channel_t *ch;
++      ulong           lock_flags;
++      ulong           lock_flags2;
++      struct bs_t     *bs;
++      uchar           *event;
++      uchar           *vaddr = NULL;
++      struct ev_t     *eaddr = NULL;
++      uint            head;
++      uint            tail;
++      int             port;
++      int             reason;
++      int             modem;
++      int             b1;
++
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return (-ENXIO);
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++
++      vaddr = bd->re_map_membase;
++
++      if (!vaddr) {
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return (-ENXIO);
++      }
++
++      eaddr = (struct ev_t *) (vaddr + EVBUF);
++
++      /* Get our head and tail */
++      head = readw(&(eaddr->ev_head));
++      tail = readw(&(eaddr->ev_tail));
++
++      /*
++       * Forget it if pointers out of range.
++       */
++
++      if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART ||
++          (head | tail) & 03) {
++              DPR_EVENT(("should be calling xxfail %d\n", __LINE__));
++              /* Let go of board lock */
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return (-ENXIO);
++      }
++
++      /*
++       * Loop to process all the events in the buffer.
++       */
++      while (tail != head) {
++
++              /*
++               * Get interrupt information.
++               */
++
++              event = bd->re_map_membase + tail + EVSTART;
++
++              port   = event[0];
++              reason = event[1];
++              modem  = event[2];
++              b1     = event[3];
++
++              DPR_EVENT(("event: jiffies: %ld port: %d reason: %x modem: %x\n",
++                      jiffies, port, reason, modem));
++
++              /*
++               * Make sure the interrupt is valid.
++               */
++                if ( port >= bd->nasync) {
++                      goto next;
++              }
++
++              if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) {
++                      goto next;
++              }
++
++              ch = bd->channels[port];
++
++              if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
++                      goto next;
++              }
++
++              /*
++               * If we have made it here, the event was valid.
++               * Lock down the channel.
++               */
++              DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++              bs = ch->ch_bs;
++
++              if (!bs) {
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      goto next;
++              }
++
++              /*
++               * Process received data.
++               */
++              if (reason & IFDATA) {
++
++                      /*
++                       * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT!
++                       * input could send some data to ld, which in turn
++                       * could do a callback to one of our other functions.
++                       */
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++                      dgap_input(ch);
++
++                      DGAP_LOCK(bd->bd_lock, lock_flags);
++                      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++                      if (ch->ch_flags & CH_RACTIVE)
++                              ch->ch_flags |= CH_RENABLE;
++                      else
++                              writeb(1, &(bs->idata));
++
++                      if (ch->ch_flags & CH_RWAIT) {
++                              ch->ch_flags &= ~CH_RWAIT;
++
++                              wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++                      }
++              }
++
++              /*
++               * Process Modem change signals.
++               */
++              if (reason & IFMODEM) {
++                      ch->ch_mistat = modem;
++                      dgap_carrier(ch);
++              }
++
++              /*
++               * Process break.
++               */
++              if (reason & IFBREAK) {
++
++                      DPR_EVENT(("got IFBREAK\n"));
++
++                      if (ch->ch_tun.un_tty) {
++                              /* A break has been indicated */
++                              ch->ch_tun.un_tty->flip.count++;
++                              *ch->ch_tun.un_tty->flip.flag_buf_ptr++ = TTY_BREAK;
++                              *ch->ch_tun.un_tty->flip.char_buf_ptr++ = 0;
++                              tty_schedule_flip(ch->ch_tun.un_tty);
++                      }
++              }
++
++              /*
++               * Process Transmit low.
++               */
++              if (reason & IFTLW) {
++
++                      DPR_EVENT(("event: got low event\n"));
++
++                      if (ch->ch_tun.un_flags & UN_LOW) {
++                              ch->ch_tun.un_flags &= ~UN_LOW;
++
++                              if (ch->ch_tun.un_flags & UN_ISOPEN) {
++                                      if ((ch->ch_tun.un_tty->flags &
++                                         (1 << TTY_DO_WRITE_WAKEUP)) &&
++                                              ch->ch_tun.un_tty->ldisc.write_wakeup)
++                                      {
++                                              (ch->ch_tun.un_tty->ldisc.write_wakeup)(ch->ch_tun.un_tty);
++                                      }
++                                      wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
++                                      wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++
++                                      DPR_EVENT(("event: Got low event. jiffies: %lu\n", jiffies));
++                              }
++                      }
++
++                      if (ch->ch_pun.un_flags & UN_LOW) {
++                              ch->ch_pun.un_flags &= ~UN_LOW;
++                              if (ch->ch_pun.un_flags & UN_ISOPEN) {
++                                      if ((ch->ch_pun.un_tty->flags &
++                                         (1 << TTY_DO_WRITE_WAKEUP)) &&
++                                              ch->ch_pun.un_tty->ldisc.write_wakeup)
++                                      {
++                                              (ch->ch_pun.un_tty->ldisc.write_wakeup)(ch->ch_pun.un_tty);
++                                      }
++                                      wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
++                                      wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++                              }
++                      }
++
++                      if (ch->ch_flags & CH_WLOW) {
++                              ch->ch_flags &= ~CH_WLOW;
++                              wake_up_interruptible(&ch->ch_flags_wait);
++                      }
++              }
++
++              /*
++               * Process Transmit empty.
++               */
++              if (reason & IFTEM) {
++                      DPR_EVENT(("event: got empty event\n"));
++
++                      if (ch->ch_tun.un_flags & UN_EMPTY) {
++                              ch->ch_tun.un_flags &= ~UN_EMPTY;
++                              if (ch->ch_tun.un_flags & UN_ISOPEN) {
++                                      if ((ch->ch_tun.un_tty->flags &
++                                         (1 << TTY_DO_WRITE_WAKEUP)) &&
++                                              ch->ch_tun.un_tty->ldisc.write_wakeup)
++                                      {
++                                              (ch->ch_tun.un_tty->ldisc.write_wakeup)(ch->ch_tun.un_tty);
++                                      }
++                                      wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
++                                      wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++                              }
++                      }
++
++                      if (ch->ch_pun.un_flags & UN_EMPTY) {
++                              ch->ch_pun.un_flags &= ~UN_EMPTY;
++                              if (ch->ch_pun.un_flags & UN_ISOPEN) {
++                                      if ((ch->ch_pun.un_tty->flags &
++                                         (1 << TTY_DO_WRITE_WAKEUP)) &&
++                                              ch->ch_pun.un_tty->ldisc.write_wakeup)
++                                      {
++                                              (ch->ch_pun.un_tty->ldisc.write_wakeup)(ch->ch_pun.un_tty);
++                                      }
++                                      wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
++                                      wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++                              }
++                      }
++
++
++                      if (ch->ch_flags & CH_WEMPTY) {
++                              ch->ch_flags &= ~CH_WEMPTY;
++                              wake_up_interruptible(&ch->ch_flags_wait);
++                      }
++              }
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++
++next:
++              tail = (tail + 4) & (EVMAX - EVSTART - 4);
++      }
++
++      writew(tail, &(eaddr->ev_tail));
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      return (0);
++}
++
++
++/************************************************************************
++ * Determines when CARRIER changes state and takes appropriate
++ * action.
++ ************************************************************************/
++void dgap_carrier(struct channel_t *ch)
++{
++      struct board_t *bd;
++
++        int virt_carrier = 0;
++        int phys_carrier = 0;
++
++      DPR_CARR(("dgap_carrier called...\n"));
++
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      bd = ch->ch_bd;
++
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      /* Make sure altpin is always set correctly */
++      if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
++              ch->ch_dsr      = DM_CD;
++              ch->ch_cd       = DM_DSR;
++      }
++      else {
++              ch->ch_dsr      = DM_DSR;
++              ch->ch_cd       = DM_CD;
++      }
++
++      if (ch->ch_mistat & D_CD(ch)) {
++              DPR_CARR(("mistat: %x  D_CD: %x\n", ch->ch_mistat, D_CD(ch)));
++              phys_carrier = 1;
++      }
++
++      if (ch->ch_digi.digi_flags & DIGI_FORCEDCD) {
++              virt_carrier = 1;
++      }
++
++      if (ch->ch_c_cflag & CLOCAL) {
++              virt_carrier = 1;
++      }
++
++
++      DPR_CARR(("DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier));
++
++      /*
++       * Test for a VIRTUAL carrier transition to HIGH.
++       */
++      if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
++
++              /*
++               * When carrier rises, wake any threads waiting
++               * for carrier in the open routine.
++               */
++
++              DPR_CARR(("carrier: virt DCD rose\n"));
++
++              if (waitqueue_active(&(ch->ch_flags_wait)))
++                      wake_up_interruptible(&ch->ch_flags_wait);
++      }
++
++      /*
++       * Test for a PHYSICAL carrier transition to HIGH.
++       */
++      if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
++
++              /*
++               * When carrier rises, wake any threads waiting
++               * for carrier in the open routine.
++               */
++
++              DPR_CARR(("carrier: physical DCD rose\n"));
++
++              if (waitqueue_active(&(ch->ch_flags_wait)))
++                      wake_up_interruptible(&ch->ch_flags_wait);
++      }
++
++      /*
++       *  Test for a PHYSICAL transition to low, so long as we aren't
++       *  currently ignoring physical transitions (which is what "virtual
++       *  carrier" indicates).
++       *
++       *  The transition of the virtual carrier to low really doesn't
++       *  matter... it really only means "ignore carrier state", not
++       *  "make pretend that carrier is there".
++       */
++      if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0) &&
++          (phys_carrier == 0))
++      {
++
++              /*
++               *   When carrier drops:
++               *
++               *   Drop carrier on all open units.
++               *
++               *   Flush queues, waking up any task waiting in the
++               *   line discipline.
++               *
++               *   Send a hangup to the control terminal.
++               *
++               *   Enable all select calls.
++               */
++              if (waitqueue_active(&(ch->ch_flags_wait)))
++                      wake_up_interruptible(&ch->ch_flags_wait);
++
++              if (ch->ch_tun.un_open_count > 0) {
++                      DPR_CARR(("Sending tty hangup\n"));
++                      tty_hangup(ch->ch_tun.un_tty);
++              }
++
++              if (ch->ch_pun.un_open_count > 0) {
++                      DPR_CARR(("Sending pr hangup\n"));
++                      tty_hangup(ch->ch_pun.un_tty);
++              }
++      }
++
++      /*
++       *  Make sure that our cached values reflect the current reality.
++       */
++      if (virt_carrier == 1)
++              ch->ch_flags |= CH_FCAR;
++      else
++              ch->ch_flags &= ~CH_FCAR;
++
++      if (phys_carrier == 1)
++              ch->ch_flags |= CH_CD;
++      else
++              ch->ch_flags &= ~CH_CD;
++}
++
++
++/************************************************************************
++ *
++ * TTY Entry points and helper functions
++ *
++ ************************************************************************/
++
++/*
++ * dgap_tty_open()
++ *
++ */
++static int dgap_tty_open(struct tty_struct *tty, struct file *file)
++{
++      struct board_t  *brd;
++      struct channel_t *ch;
++      struct un_t     *un;
++      struct bs_t     *bs;
++      uint            major = 0;
++      uint            minor = 0;
++      int             rc = 0;
++      ulong           lock_flags;
++      ulong           lock_flags2;
++      u32             head;
++
++      DGAP_MOD_INC_USE_COUNT(rc);
++      if (!rc) {
++              return -ENXIO;
++      }
++
++      rc = 0;
++
++      major = DGAP_TTY_MAJOR(tty->device);
++      minor = DGAP_TTY_MINOR(tty->device);
++
++      if (major > 255) {
++              DGAP_MOD_DEC_USE_COUNT;
++              return -ENXIO;
++      }
++
++      /* Get board pointer from our array of majors we have allocated */
++      brd = dgap_BoardsByMajor[major];
++      if (!brd) {
++              DGAP_MOD_DEC_USE_COUNT;
++              return -ENXIO;
++      }
++
++      DGAP_LOCK(brd->bd_lock, lock_flags);
++
++      /* If board is not ready yet, bail. */
++      /* TODO: Maybe sleep here, instead of bailing right away? */
++      if (brd->state != BOARD_READY) {
++              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++              DGAP_MOD_DEC_USE_COUNT;
++              return -ENXIO;
++      }
++
++      /* If opened device is greater than our number of ports, bail. */
++      if (DGAP_TTY_MINOR(tty->device) > brd->nasync) {
++              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++              DGAP_MOD_DEC_USE_COUNT;
++              return -ENXIO;
++      }
++
++      ch = brd->channels[minor];
++      if (!ch) {
++              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++              DGAP_MOD_DEC_USE_COUNT;
++              return -ENXIO;
++      }
++
++      /* Grab channel lock */
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      /* Figure out our type */
++      if (major == brd->dgap_Serial_Major) {
++              un = &brd->channels[minor]->ch_tun;
++              un->un_type = DGAP_SERIAL;
++      }
++      else if (major == brd->dgap_TransparentPrint_Major) {
++              un = &brd->channels[minor]->ch_pun;
++              un->un_type = DGAP_PRINT;
++      }
++      else {
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++              DPR_OPEN(("%d Unknown TYPE!\n", __LINE__));
++              return -ENXIO;
++      }
++
++      /* Store our unit into driver_data, so we always have it available. */
++      tty->driver_data = un;
++
++      DPR_OPEN(("Open called. MAJOR: %d MINOR:%d unit: %p NAME: %s\n",
++              DGAP_TTY_MAJOR(tty->device), DGAP_TTY_MINOR(tty->device), un, brd->name));
++
++      /*
++       * Error if channel info pointer is 0.
++       */
++      if ((bs = ch->ch_bs) == 0) {
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(brd->bd_lock, lock_flags);
++              DPR_OPEN(("%d BS is 0!\n", __LINE__));
++              return -ENXIO;
++        }
++
++      DPR_OPEN(("%d: tflag=%x  pflag=%x\n", __LINE__, ch->ch_tun.un_flags, ch->ch_pun.un_flags));
++
++      /*
++       * Initialize tty's
++       */
++      if (!(un->un_flags & UN_ISOPEN)) {
++              /* Store important variables. */
++              un->un_ch      = brd->channels[minor];
++              un->un_dev     = minor;
++              un->un_tty     = tty;
++
++              /* Maybe do something here to the TTY struct as well? */
++      }
++
++      /*
++       * Initialize if neither terminal or printer is open.
++       */
++      if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
++
++              DPR_OPEN(("dgap_open: initializing channel in open...\n"));
++
++              ch->ch_mforce = 0;
++              ch->ch_mval = 0;
++
++              /*
++               * Flush input queue.
++               */
++              head = readw(&(bs->rx_head));
++              writew(head, &(bs->rx_tail));
++
++              ch->ch_flags = 0;
++              ch->pscan_state = 0;
++              ch->pscan_savechar = 0;
++
++              ch->ch_c_cflag   = tty->termios->c_cflag;
++              ch->ch_c_iflag   = tty->termios->c_iflag;
++              ch->ch_c_oflag   = tty->termios->c_oflag;
++              ch->ch_c_lflag   = tty->termios->c_lflag;
++              ch->ch_startc = tty->termios->c_cc[VSTART];
++              ch->ch_stopc  = tty->termios->c_cc[VSTOP];
++
++              /* TODO: flush our TTY struct here? */
++      }
++
++      dgap_carrier(ch);
++      /*
++       * Run param in case we changed anything
++       */
++      dgap_param(tty);
++
++      /*
++       * follow protocol for opening port
++       */
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(brd->bd_lock, lock_flags);
++
++      rc = block_til_ready(tty, file, ch);
++
++      if (rc) {
++              DPR_OPEN(("dgap_tty_open returning after block_til_ready "
++                      "with %d\n", rc));
++      }
++
++      /* No going back now, increment our unit and channel counters */
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++      ch->ch_open_count++;
++      un->un_open_count++;
++      un->un_flags |= (UN_ISOPEN);
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      DPR_OPEN(("dgap_tty_open finished\n"));
++      return (rc);
++}
++
++
++/*
++ * block_til_ready()
++ *
++ * Wait for DCD, if needed.
++ */
++static int block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch)
++{
++      int retval = 0;
++      struct un_t *un = NULL;
++      ulong   lock_flags;
++      uint    old_ch_flags = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC || !file || !ch || ch->magic != DGAP_CHANNEL_MAGIC) {
++              return (-ENXIO);
++      }
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC) {
++              return (-ENXIO);
++      }
++
++      DPR_OPEN(("block_til_ready - before block.\n"));
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++
++      ch->ch_wopen++;
++
++      /* Loop forever */
++      while (1) {
++
++              /*
++               * If board has failed somehow during our sleep, bail with error.
++               */
++              if (ch->ch_bd->state == BOARD_FAILED) {
++                      retval = -ENXIO;
++                      break;
++              }
++
++              /* If tty was hung up, break out of loop and set error. */
++              if (tty_hung_up_p(file)) {
++                      retval = -EAGAIN;
++                      break;
++              }
++
++              /*
++               * If either unit is in the middle of the fragile part of close,
++               * we just cannot touch the channel safely.
++               * Go back to sleep, knowing that when the channel can be
++               * touched safely, the close routine will signal the
++               * ch_wait_flags to wake us back up.
++               */
++              if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_CLOSING)) {
++
++                      /*
++                       * Our conditions to leave cleanly and happily:
++                       * 1) NONBLOCKING on the tty is set.
++                       * 2) CLOCAL is set.
++                       * 3) DCD (fake or real) is active.
++                       */
++
++                      if (file->f_flags & O_NONBLOCK) {
++                              break;
++                      }
++
++                      if (tty->flags & (1 << TTY_IO_ERROR)) {
++                              break;
++                      }
++
++                      if (ch->ch_flags & CH_CD) {
++                              DPR_OPEN(("%d: ch_flags: %x\n", __LINE__, ch->ch_flags));
++                              break;
++                      }
++
++                      if (ch->ch_flags & CH_FCAR) {
++                              DPR_OPEN(("%d: ch_flags: %x\n", __LINE__, ch->ch_flags));
++                              break;
++                      }
++              }
++
++              /*
++               * If there is a signal pending, the user probably
++               * interrupted (ctrl-c) us.
++               * Leave loop with error set.
++               */
++              if (signal_pending(current)) {
++                      DPR_OPEN(("%d: signal pending...\n", __LINE__));
++                      retval = -ERESTARTSYS;
++                      break;
++              }
++
++              DPR_OPEN(("block_til_ready - blocking.\n"));
++
++              /*
++               * Store the channel flags before we let go of channel lock
++               */
++              old_ch_flags = ch->ch_flags;
++
++              /*
++               * Let go of channel lock before calling schedule.
++               * Our poller will get any FEP events and wake us up when DCD
++               * eventually goes active.
++               */
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++              DPR_OPEN(("Going to sleep...\n"));
++
++              /*
++               * Wait for something in the ch_flags to change from the current value.
++               */
++              retval = wait_event_interruptible(ch->ch_flags_wait, (old_ch_flags != ch->ch_flags));
++
++              DPR_OPEN(("After sleep... retval: %x\n", retval));
++
++              /*
++               * We got woken up for some reason.
++               * Before looping around, grab our channel lock.
++               */
++              DGAP_LOCK(ch->ch_lock, lock_flags);
++      }
++
++      ch->ch_wopen--;
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      DPR_OPEN(("block_til_ready - after blocking.\n"));
++
++      if (retval) {
++              DPR_OPEN(("block_til_ready - done. error. retval: %x\n", retval));
++              return(retval);
++      }
++
++      DPR_OPEN(("block_til_ready - done no error. jiffies: %lu\n", jiffies));
++
++      return(0);
++}
++
++
++/*
++ * dgap_tty_hangup()
++ *
++ * Hangup the port.  Like a close, but don't wait for output to drain.
++ */
++static void dgap_tty_hangup(struct tty_struct *tty)
++{
++      struct board_t  *bd;
++      struct channel_t *ch;
++      struct un_t     *un;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_CLOSE(("dgap_hangup called. ch->ch_open_count: %d un->un_open_count: %d\n",
++              ch->ch_open_count, un->un_open_count));
++
++      /* flush the transmit queues */
++      dgap_tty_flush_buffer(tty);
++
++      DPR_CLOSE(("dgap_hangup finished. ch->ch_open_count: %d un->un_open_count: %d\n",
++              ch->ch_open_count, un->un_open_count));
++}
++
++
++
++/*
++ * dgap_tty_close()
++ *
++ */
++static void dgap_tty_close(struct tty_struct *tty, struct file *file)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      struct termios *ts;
++      ulong lock_flags;
++      int rc = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      ts = tty->termios;
++
++      DPR_CLOSE(("Close called\n"));
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++
++      /*
++       * Determine if this is the last close or not - and if we agree about
++       * which type of close it is with the Line Discipline
++       */
++      if ((tty->count == 1) && (un->un_open_count != 1)) {
++              /*
++               * Uh, oh.  tty->count is 1, which means that the tty
++               * structure will be freed.  un_open_count should always
++               * be one in these conditions.  If it's greater than
++               * one, we've got real problems, since it means the
++               * serial port won't be shutdown.
++               */
++              APR(("tty->count is 1, un open count is %d\n", un->un_open_count));
++              un->un_open_count = 1;
++      }
++
++      if (--un->un_open_count < 0) {
++              APR(("bad serial port open count of %d\n", un->un_open_count));
++              un->un_open_count = 0;
++      }
++
++      ch->ch_open_count--;
++
++      if (ch->ch_open_count && un->un_open_count) {
++              DPR_CLOSE(("dgap_tty_close: not last close ch: %d un:%d\n",
++                      ch->ch_open_count, un->un_open_count));
++
++              DGAP_MOD_DEC_USE_COUNT;
++              DGAP_UNLOCK(ch->ch_lock, lock_flags);
++                return;
++        }
++
++      /* OK, its the last close on the unit */
++      DPR_CLOSE(("dgap_tty_close - last close on unit procedures\n"));
++
++      un->un_flags |= UN_CLOSING;
++
++      tty->closing = 1;
++
++      /*
++       * Only officially close channel if count is 0 and
++         * DIGI_PRINTER bit is not set.
++       */
++      if ((ch->ch_open_count == 0) && !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
++
++              ch->ch_flags &= ~(CH_RXBLOCK);
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++              /* wait for output to drain */
++              /* This will also return if we take an interrupt */
++
++              DPR_CLOSE(("Calling wait_for_drain\n"));
++              rc = dgap_wait_for_drain(tty);
++              DPR_CLOSE(("After calling wait_for_drain\n"));
++
++              if (rc) {
++                      DPR_BASIC(("dgap_tty_close - bad return: %d ", rc));
++              }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++              if (tty->driver->flush_buffer) {
++                      DPR_CLOSE(("Calling driver flush buffer\n"));
++                      tty->driver->flush_buffer(tty);
++              }
++#else
++              if (tty->driver.flush_buffer) {
++                      DPR_CLOSE(("Calling driver flush buffer\n"));
++                      tty->driver.flush_buffer(tty);
++              }
++#endif
++              if (tty->ldisc.flush_buffer) {
++                      DPR_CLOSE(("Calling ldisc flush buffer\n"));
++                      tty->ldisc.flush_buffer(tty);
++              }
++
++              DGAP_LOCK(ch->ch_lock, lock_flags);
++
++              tty->closing = 0;
++
++              /*
++               * If we have HUPCL set, lower DTR and RTS
++               */
++              if (ch->ch_c_cflag & HUPCL ) {
++                      DPR_CLOSE(("Close. HUPCL set, dropping DTR/RTS\n"));
++                      ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch));
++                      dgap_cmdb( ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0 );
++
++                      /*
++                       * Go to sleep to ensure RTS/DTR
++                       * have been dropped for modems to see it.
++                       */
++                      if (ch->ch_close_delay) {
++                              DPR_CLOSE(("Close. Sleeping for RTS/DTR drop\n"));
++
++                              DGAP_UNLOCK(ch->ch_lock, lock_flags);
++                              dgap_ms_sleep(ch->ch_close_delay);
++                              DGAP_LOCK(ch->ch_lock, lock_flags);
++
++                              DPR_CLOSE(("Close. After sleeping for RTS/DTR drop\n"));
++                      }
++              }
++
++              ch->pscan_state = 0;
++              ch->pscan_savechar = 0;
++      }
++
++      /*
++       * turn off print device when closing print device.
++       */
++      if ((un->un_type == DGAP_PRINT)  && (ch->ch_flags & CH_PRON) ) {
++              dgap_wmove(ch, ch->ch_digi.digi_offstr,
++                      (int) ch->ch_digi.digi_offlen);
++              ch->ch_flags &= ~CH_PRON;
++      }
++
++      un->un_tty = 0;
++      un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);
++
++      DPR_CLOSE(("Close. Doing wakeups\n"));
++      wake_up_interruptible(&ch->ch_flags_wait);
++      wake_up_interruptible(&un->un_flags_wait);
++
++      DGAP_MOD_DEC_USE_COUNT;
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++        DPR_BASIC(("dgap_tty_close - complete\n"));
++}
++
++
++/*
++ * dgap_tty_chars_in_buffer()
++ *
++ * Return number of characters that have not been transmitted yet.
++ *
++ * This routine is used by the line discipline to determine if there
++ * is data waiting to be transmitted/drained/flushed or not.
++ */
++static int dgap_tty_chars_in_buffer(struct tty_struct *tty)
++{
++      struct board_t *bd = NULL;
++      struct channel_t *ch = NULL;
++      struct un_t *un = NULL;
++      struct bs_t *bs = NULL;
++      uchar tbusy;
++      u16 thead, ttail, tmask, chead, ctail;
++      u32 chars = 0;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++
++      if (tty == NULL)
++              return(0);
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return (0);
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return (0);
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return (0);
++
++        bs = ch->ch_bs;
++      if (!bs)
++              return (0);
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      tmask = (ch->ch_tsize - 1);
++
++      /* Get Transmit queue pointers */
++      thead = readw(&(bs->tx_head)) & tmask;
++      ttail = readw(&(bs->tx_tail)) & tmask;
++
++      /* Get tbusy flag */
++      tbusy = readb(&(bs->tbusy));
++
++      /* Get Command queue pointers */
++      chead = readw(&(ch->ch_cm->cm_head));
++      ctail = readw(&(ch->ch_cm->cm_tail));
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      /*
++       * The only way we know for sure if there is no pending
++       * data left to be transferred, is if:
++       * 1) Transmit head and tail are equal (empty).
++       * 2) Command queue head and tail are equal (empty).
++       * 3) The "TBUSY" flag is 0. (Transmitter not busy).
++       */
++      if ((ttail == thead) && (tbusy == 0) && (chead == ctail)) {
++              chars = 0;
++      }
++      else {
++              if (thead >= ttail)
++                      chars = thead - ttail;
++              else
++                      chars = thead - ttail + ch->ch_tsize;
++              /*
++               * Fudge factor here.
++               * If chars is zero, we know that the command queue had
++               * something in it or tbusy was set.  Because we cannot
++               * be sure if there is still some data to be transmitted,
++               * lets lie, and tell ld we have 1 byte left.
++               */
++              if (chars == 0)
++                      chars = 1;
++      }
++
++      DPR_WRITE(("dgap_tty_chars_in_buffer. Port: %x - %d (head: %d tail: %d tsize: %d)\n",
++              ch->ch_portnum, chars, thead, ttail, ch->ch_tsize));
++
++        return(chars);
++}
++
++
++static int dgap_wait_for_drain(struct tty_struct *tty)
++{
++      struct channel_t *ch;
++      struct un_t *un;
++      struct bs_t *bs;
++      int ret = -EIO;
++      u32 count = 1;
++      ulong   lock_flags = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return ret;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return ret;
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return ret;
++
++        bs = ch->ch_bs;
++      if (!bs)
++              return ret;
++
++      ret = 0;
++
++      DPR_DRAIN(("dgap_wait_for_drain start\n"));
++
++      /* Loop until data is drained */
++      while (count != 0) {
++
++              count = dgap_tty_chars_in_buffer(tty);
++
++              if (count == 0)
++                      break;
++
++              /* Set flag waiting for drain */
++              DGAP_LOCK(ch->ch_lock, lock_flags);
++              un->un_flags |= UN_EMPTY;
++              writeb(1, &(bs->iempty));
++              DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++              /* Go to sleep till we get woken up */
++              ret = wait_event_interruptible(un->un_flags_wait, ((un->un_flags & UN_EMPTY) == 0));
++
++              /* If ret is non-zero, user ctrl-c'ed us */
++              if (ret)
++                      break;
++      }
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++      un->un_flags &= ~(UN_EMPTY);
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      DPR_DRAIN(("dgap_wait_for_drain finish\n"));
++
++      return (ret);
++}
++
++
++/*
++ * dgap_maxcps_room
++ *
++ * Reduces bytes_available to the max number of characters
++ * that can be sent currently given the maxcps value, and
++ * returns the new bytes_available.  This only affects printer
++ * output.
++ */
++static int maxcps_room(struct tty_struct *tty, int bytes_available)
++{
++      struct channel_t *ch = NULL;
++      struct un_t *un = NULL;
++
++      if (tty == NULL)
++              return (bytes_available);
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return (bytes_available);
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return (bytes_available);
++
++      /*
++       * If its not the Transparent print device, return
++       * the full data amount.
++       */
++      if (un->un_type != DGAP_PRINT)
++              return (bytes_available);
++
++      if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0 ) {
++              int cps_limit = 0;
++              unsigned long current_time = jiffies;
++              unsigned long buffer_time = current_time +
++                      (HZ * ch->ch_digi.digi_bufsize) / ch->ch_digi.digi_maxcps;
++
++              if (ch->ch_cpstime < current_time) {
++                      /* buffer is empty */
++                      ch->ch_cpstime = current_time;            /* reset ch_cpstime */
++                      cps_limit = ch->ch_digi.digi_bufsize;
++              }
++              else if (ch->ch_cpstime < buffer_time) {
++                      /* still room in the buffer */
++                      cps_limit = ((buffer_time - ch->ch_cpstime) * ch->ch_digi.digi_maxcps) / HZ;
++              }
++              else {
++                      /* no room in the buffer */
++                      cps_limit = 0;
++              }
++
++              bytes_available = min(cps_limit, bytes_available);
++      }
++
++      return (bytes_available);
++}
++
++
++/*
++ * dgap_tty_write_room()
++ *
++ * Return space available in Tx buffer
++ */
++static int dgap_tty_write_room(struct tty_struct *tty)
++{
++      struct channel_t *ch = NULL;
++      struct un_t *un = NULL;
++      struct bs_t *bs = NULL;
++      u16 head, tail, tmask;
++      int ret = 0;
++      ulong   lock_flags = 0;
++
++      if (tty == NULL || dgap_TmpWriteBuf == NULL)
++              return(0);
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return (0);
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return (0);
++
++        bs = ch->ch_bs;
++      if (!bs)
++              return (0);
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++
++      tmask = ch->ch_tsize - 1;
++      head = readw(&(bs->tx_head)) & tmask;
++      tail = readw(&(bs->tx_tail)) & tmask;
++
++        if ((ret = tail - head - 1) < 0)
++                ret += ch->ch_tsize;
++
++      /* Limit printer to maxcps */
++      ret = maxcps_room(tty, ret);
++
++      /*
++       * If we are printer device, leave space for
++       * possibly both the on and off strings.
++       */
++      if (un->un_type == DGAP_PRINT) {
++              if (!(ch->ch_flags & CH_PRON))
++                      ret -= ch->ch_digi.digi_onlen;
++              ret -= ch->ch_digi.digi_offlen;
++      }
++      else {
++              if (ch->ch_flags & CH_PRON)
++                      ret -= ch->ch_digi.digi_offlen;
++      }
++
++      if (ret < 0)
++              ret = 0;
++
++      if ((ret <= ch->ch_tlw) && ((un->un_flags & UN_LOW) == 0)) {
++              un->un_flags |= UN_LOW;
++              writeb(1, &(bs->ilow));
++      }
++      else if ((un->un_flags & UN_EMPTY) == 0) {
++              un->un_flags |= UN_EMPTY;
++              writeb(1, &(bs->iempty));
++      }
++      else {
++              un->un_flags |= UN_EMPTY;
++              writeb(1, &(bs->iempty));
++      }
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      DPR_WRITE(("dgap_tty_write_room - %d tail: %d head: %d\n", ret, tail, head));
++
++        return(ret);
++}
++
++
++/*
++ * dgap_tty_put_char()
++ *
++ * Put a character into ch->ch_buf
++ *
++ *      - used by the line discipline for OPOST processing
++ */
++static void dgap_tty_put_char(struct tty_struct *tty, unsigned char c)
++{
++      /*
++       * Simply call tty_write.
++       */
++      DPR_WRITE(("dgap_tty_put_char called\n"));
++      dgap_tty_write(tty, 0, &c, 1);
++        return;
++}
++
++
++/*
++ * dgap_tty_write()
++ *
++ * Take data from the user or kernel and send it out to the FEP.
++ * In here exists all the Transparent Print magic as well.
++ */
++static int dgap_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf,
++              int count)
++{
++      struct channel_t *ch = NULL;
++      struct un_t *un = NULL;
++      struct bs_t *bs = NULL;
++      char *vaddr = NULL;
++      u16 head, tail, tmask, remain;
++      int bufcount = 0, n = 0;
++      int orig_count = 0;
++
++      if (tty == NULL || dgap_TmpWriteBuf == NULL)
++              return(0);
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return (0);
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return (0);
++
++        bs = ch->ch_bs;
++      if (!bs)
++              return (0);
++
++      DPR_WRITE(("dgap_tty_write: Port: %x tty=%x user=%d len=%d\n",
++              ch->ch_portnum, (int) tty, from_user, count));
++
++      /*
++       * Store original amount of characters passed in.
++       * This helps to figure out if we should ask the FEP
++       * to send us an event when it has more space available.
++       */
++      orig_count = count;
++
++      /*
++       * If data is coming from user space, copy it into a temporary
++       * buffer so we don't get swapped out while doing the copy to
++       * the board.
++       */
++      if (from_user) {
++              /* we're allowed to block if it's from_user */
++              if (down_interruptible(&dgap_TmpWriteSem)) {
++                      return(-EINTR);
++              }
++              /* if we get a non-zero return, we couldn't lock, bail. */
++              if (!spin_trylock(&ch->ch_lock)) {
++                      DPR_WRITE(("Unable to get lock\n"));
++                      up(&dgap_TmpWriteSem);
++                      return(-EAGAIN);
++              }
++      }
++      else {
++              /* if we get a non-zero return, we couldn't lock, bail. */
++              if (!spin_trylock(&ch->ch_lock)) {
++                      DPR_WRITE(("Unable to get lock\n"));
++                      return(-EAGAIN);
++              }
++      }
++
++      /* Get our space available for the channel from the board */
++      tmask = ch->ch_tsize - 1;
++      head = readw(&(bs->tx_head)) & tmask;
++      tail = readw(&(bs->tx_tail)) & tmask;
++
++      if ((bufcount = tail - head - 1) < 0)
++              bufcount += ch->ch_tsize;
++
++      DPR_WRITE(("%d: bufcount: %x count: %x tail: %x head: %x tmask: %x\n",
++              __LINE__, bufcount, count, tail, head, tmask));
++
++      /*
++       * Limit printer output to maxcps overall, with bursts allowed
++       * up to bufsize characters.
++       */
++      bufcount = maxcps_room(tty, bufcount);
++
++      /*
++       * Take minimum of what the user wants to send, and the
++       * space available in the FEP buffer.
++       */
++      count = min(count, bufcount);
++
++      /*
++       * Bail if no space left.
++       */
++      if (count <= 0)
++              goto out;
++
++      /*
++       * Output the printer ON string, if we are in terminal mode, but
++       * need to be in printer mode.
++       */
++      if ((un->un_type == DGAP_PRINT) && !(ch->ch_flags & CH_PRON)) {
++              dgap_wmove(ch, ch->ch_digi.digi_onstr,
++                  (int) ch->ch_digi.digi_onlen);
++              head = readw(&(bs->tx_head)) & tmask;
++              ch->ch_flags |= CH_PRON;
++      }
++
++      /*
++       * On the other hand, output the printer OFF string, if we are
++       * currently in printer mode, but need to output to the terminal.
++       */
++      if ((un->un_type != DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
++              dgap_wmove(ch, ch->ch_digi.digi_offstr,
++                      (int) ch->ch_digi.digi_offlen);
++              head = readw(&(bs->tx_head)) & tmask;
++              ch->ch_flags &= ~CH_PRON;
++      }
++
++      if (from_user) {
++              /*
++               * If there is nothing left to copy, or I can't handle any more data, leave.
++               */
++              if (count <= 0) {
++                      goto out;
++              }
++
++              count = min(count, WRITEBUFLEN);
++
++              /*
++               * copy_from_user() returns the number
++               * of bytes that could *NOT* be copied.
++               */
++              spin_unlock(&ch->ch_lock);
++              count -= copy_from_user(dgap_TmpWriteBuf, buf, count);
++              spin_lock(&ch->ch_lock);
++              if (!count) {
++                      spin_unlock(&ch->ch_lock);
++                      up(&dgap_TmpWriteSem);
++                      return(-EFAULT);
++              }
++
++              buf = dgap_TmpWriteBuf;
++      }
++
++      n = count;
++
++      /*
++       * If the write wraps over the top of the circular buffer,
++       * move the portion up to the wrap point, and reset the
++       * pointers to the bottom.
++       */
++      remain = ch->ch_tstart + ch->ch_tsize - head;
++
++      if (n >= remain) {
++              n -= remain;
++              vaddr = ch->ch_taddr + head;
++              memcpy_toio(vaddr, buf, remain);
++              head = ch->ch_tstart;
++              buf += remain;
++      }
++
++      if (n > 0) {
++
++              /*
++               * Move rest of data.
++               */
++              vaddr = ch->ch_taddr + head;
++              remain = n;
++
++              memcpy_toio(vaddr, buf, remain);
++              head += remain;
++
++      }
++
++      if (count) {
++              head &= tmask;
++              writew(head, &(bs->tx_head));
++      }
++
++out:
++
++      /*
++       * If we are doing an incomplete write, we need to tell
++       * the FEP to send us an event when we have more space available.
++       *
++       * If we are over the low water mark, then we can use that.
++       * If we are under the low water mark, just wait for the empty event.
++       */
++      if (count != orig_count) {
++
++              if ((bufcount = tail - head - 1) < 0)
++                      bufcount += ch->ch_tsize;
++
++              if ((bufcount <= ch->ch_tlw) && ((un->un_flags & UN_LOW) == 0)) {
++                      un->un_flags |= UN_LOW;
++                      writeb(1, &(bs->ilow));
++              }
++              else if ((un->un_flags & UN_EMPTY) == 0) {
++                      un->un_flags |= UN_EMPTY;
++                      writeb(1, &(bs->iempty));
++              }
++              else {
++                      un->un_flags |= UN_EMPTY;
++                      writeb(1, &(bs->iempty));
++              }
++      }
++      else {
++              /*
++               * If this is the print device, and the
++               * printer is still on, we need to turn it
++               * off before going idle.  If the buffer is
++               * non-empty, wait until it goes empty.
++               * Otherwise turn it off right now.
++               */
++              if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
++                      tail = readw(&(bs->tx_tail)) & tmask;
++
++                      if (tail != head) {
++                              un->un_flags |= UN_EMPTY;
++                              writeb(1, &(bs->iempty));
++                      }
++                      else {
++                              dgap_wmove(ch, ch->ch_digi.digi_offstr,
++                                      (int) ch->ch_digi.digi_offlen);
++                              head = readw(&(bs->tx_head)) & tmask;
++                              ch->ch_flags &= ~CH_PRON;
++                      }
++              }
++      }
++
++      /* Update printer buffer empty time. */
++      if ((un->un_type == DGAP_PRINT) && (ch->ch_digi.digi_maxcps > 0)
++          && (ch->ch_digi.digi_bufsize > 0)) {
++                ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
++      }
++
++      if (from_user) {
++              spin_unlock(&ch->ch_lock);
++              up(&dgap_TmpWriteSem);
++      }
++      else {
++              spin_unlock(&ch->ch_lock);
++      }
++
++      DPR_WRITE(("Write finished - Write %d bytes of %d.\n", count, orig_count));
++
++      return (count);
++}
++
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++
++/*
++ * Return modem signals to ld.
++ */
++static int dgap_tty_tiocmget(struct tty_struct *tty, struct file *file)
++{
++      struct channel_t *ch;
++      struct un_t *un;
++      int result = -EIO;
++      uchar mstat = 0;
++      ulong   lock_flags = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return result;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return result;
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return result;
++
++      DPR_IOCTL(("dgap_tty_tiocmget start\n"));
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++
++      mstat = readb(&(ch->ch_bs->m_stat));
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      result = 0;
++
++      if (mstat & D_DTR(ch))
++              result |= TIOCM_DTR;
++      if (mstat & D_RTS(ch))
++              result |= TIOCM_RTS;
++      if (mstat & D_CTS(ch))
++              result |= TIOCM_CTS;
++      if (mstat & D_DSR(ch))
++              result |= TIOCM_DSR;
++      if (mstat & D_RI(ch))
++              result |= TIOCM_RI;
++      if (mstat & D_CD(ch))
++              result |= TIOCM_CD;
++
++      DPR_IOCTL(("dgap_tty_tiocmget finish\n"));
++
++      return result;
++}
++
++
++/*
++ * dgap_tty_tiocmset()
++ *
++ * Set modem signals, called by ld.
++ */
++static int dgap_tty_tiocmset(struct tty_struct *tty, struct file *file,
++              unsigned int set, unsigned int clear)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      int ret = -EIO;
++      int mflag = 0;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return ret;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return ret;
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return ret;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return ret;
++
++      DPR_IOCTL(("dgap_tty_tiocmset start\n"));
++
++      ch->ch_mforce = D_DTR(ch)|D_RTS(ch);
++
++      if (set & TIOCM_RTS) {
++              mflag |= D_RTS(ch);
++        }
++
++      if (set & TIOCM_DTR) {
++              mflag |= D_DTR(ch);
++        }
++
++      if (clear & TIOCM_RTS) {
++              mflag &= ~(D_RTS(ch));
++        }
++
++      if (clear & TIOCM_DTR) {
++              mflag &= ~(D_DTR(ch));
++        }
++
++      ch->ch_mval = mflag;
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      dgap_param(tty);
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_tiocmset finish\n"));
++
++      return (0);
++}
++
++#endif /* LINUX 2,6,0 */
++
++
++/*
++ * Return modem signals to ld.
++ */
++static int dgap_get_modem_info(struct channel_t *ch, unsigned int *value)
++{
++      int result = 0;
++      uchar mstat = 0;
++      ulong   lock_flags = 0;
++
++      DPR_IOCTL(("dgap_get_modem_info start\n"));
++
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return(-ENXIO);
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++
++      mstat = readb(&(ch->ch_bs->m_stat));
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      result = 0;
++
++      if (mstat & D_DTR(ch))
++              result |= TIOCM_DTR;
++      if (mstat & D_RTS(ch))
++              result |= TIOCM_RTS;
++      if (mstat & D_CTS(ch))
++              result |= TIOCM_CTS;
++      if (mstat & D_DSR(ch))
++              result |= TIOCM_DSR;
++      if (mstat & D_RI(ch))
++              result |= TIOCM_RI;
++      if (mstat & D_CD(ch))
++              result |= TIOCM_CD;
++
++      put_user(result, value);
++
++      DPR_IOCTL(("dgap_get_modem_info finish\n"));
++      return(0);
++}
++
++
++/*
++ * dgap_set_modem_info()
++ *
++ * Set modem signals, called by ld.
++ */
++static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int *value)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      int ret = -ENXIO;
++      unsigned int arg = 0;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return ret;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return ret;
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return ret;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return ret;
++
++      ret = 0;
++
++      DPR_IOCTL(("dgap_set_modem_info() start\n"));
++
++      ret = verify_area(VERIFY_READ, value, sizeof(int));
++      if (ret)
++              return(ret);
++
++      GET_USER(arg, value);
++
++      switch (command) {
++      case TIOCMBIS:
++              if (arg & TIOCM_RTS) {
++                      ch->ch_mforce |= D_RTS(ch);
++                      ch->ch_mval   |= D_RTS(ch);
++              }
++
++              if (arg & TIOCM_DTR) {
++                      ch->ch_mforce |= D_DTR(ch);
++                      ch->ch_mval   |= D_DTR(ch);
++              }
++
++              break;
++
++      case TIOCMBIC:
++              if (arg & TIOCM_RTS) {
++                      ch->ch_mforce |= D_RTS(ch);
++                      ch->ch_mval   &= ~(D_RTS(ch));
++              }
++
++              if (arg & TIOCM_DTR) {
++                      ch->ch_mforce |= D_DTR(ch);
++                      ch->ch_mval   &= ~(D_DTR(ch));
++              }
++
++              break;
++
++        case TIOCMSET:
++              ch->ch_mforce = D_DTR(ch)|D_RTS(ch);
++
++              if (arg & TIOCM_RTS) {
++                      ch->ch_mval |= D_RTS(ch);
++              }
++              else {
++                      ch->ch_mval &= ~(D_RTS(ch));
++              }
++
++              if (arg & TIOCM_DTR) {
++                      ch->ch_mval |= (D_DTR(ch));
++              }
++              else {
++                      ch->ch_mval &= ~(D_DTR(ch));
++              }
++
++              break;
++
++      default:
++              return(-EINVAL);
++      }
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      dgap_param(tty);
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_set_modem_info finish\n"));
++
++      return (0);
++}
++
++
++/*
++ * dgap_tty_digigeta()
++ *
++ * Ioctl to get the information for ditty.
++ *
++ *
++ *
++ */
++static int dgap_tty_digigeta(struct tty_struct *tty, struct digi_t *retinfo)
++{
++      struct channel_t *ch;
++      struct un_t *un;
++      struct digi_t tmp;
++      ulong   lock_flags = 0;
++
++      if (!retinfo)
++              return (-EFAULT);
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return (-EFAULT);
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return (-EFAULT);
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return (-EFAULT);
++
++      memset(&tmp, 0, sizeof(tmp));
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++      memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
++              return (-EFAULT);
++
++      return (0);
++}
++
++
++/*
++ * dgap_tty_digiseta()
++ *
++ * Ioctl to set the information for ditty.
++ *
++ *
++ *
++ */
++static int dgap_tty_digiseta(struct tty_struct *tty, struct digi_t *new_info)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      struct digi_t new_digi;
++      ulong   lock_flags = 0;
++      unsigned long lock_flags2;
++
++      DPR_IOCTL(("DIGI_SETA start\n"));
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return (-EFAULT);
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return (-EFAULT);
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return (-EFAULT);
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return (-EFAULT);
++
++        if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) {
++              DPR_IOCTL(("DIGI_SETA failed copy_from_user\n"));
++                return(-EFAULT);
++      }
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      memcpy(&ch->ch_digi, new_info, sizeof(struct digi_t));
++
++      if (ch->ch_digi.digi_maxcps < 1)
++              ch->ch_digi.digi_maxcps = 1;
++
++      if (ch->ch_digi.digi_maxcps > 10000)
++              ch->ch_digi.digi_maxcps = 10000;
++
++      if (ch->ch_digi.digi_bufsize < 10)
++              ch->ch_digi.digi_bufsize = 10;
++
++      if (ch->ch_digi.digi_maxchar < 1)
++              ch->ch_digi.digi_maxchar = 1;
++
++      if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
++              ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
++
++      if (ch->ch_digi.digi_onlen > DIGI_PLEN)
++              ch->ch_digi.digi_onlen = DIGI_PLEN;
++
++      if (ch->ch_digi.digi_offlen > DIGI_PLEN)
++              ch->ch_digi.digi_offlen = DIGI_PLEN;
++
++      dgap_param(tty);
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("DIGI_SETA finish\n"));
++
++      return(0);
++}
++
++
++/*
++ * dgap_set_termios()
++ */
++static void dgap_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      unsigned long lock_flags;
++      unsigned long lock_flags2;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      ch->ch_c_cflag   = tty->termios->c_cflag;
++      ch->ch_c_iflag   = tty->termios->c_iflag;
++      ch->ch_c_oflag   = tty->termios->c_oflag;
++      ch->ch_c_lflag   = tty->termios->c_lflag;
++      ch->ch_startc = tty->termios->c_cc[VSTART];
++      ch->ch_stopc  = tty->termios->c_cc[VSTOP];
++
++      dgap_carrier(ch);
++
++      dgap_param(tty);
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++}
++
++
++static void dgap_tty_throttle(struct tty_struct *tty)
++{
++      struct channel_t *ch;
++      struct un_t *un;
++      ulong   lock_flags = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++        ch = un->un_ch;
++        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++                return;
++
++      DPR_IOCTL(("dgap_tty_throttle start\n"));
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++
++      ch->ch_flags |= (CH_RXBLOCK);
++#if 1
++      dgap_cmdw(ch, RPAUSE, 0, 0);
++#endif
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_throttle finish\n"));
++}
++
++
++static void dgap_tty_unthrottle(struct tty_struct *tty)
++{
++      struct channel_t *ch;
++      struct un_t *un;
++      ulong   lock_flags = 0;
++
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++        ch = un->un_ch;
++        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++                return;
++
++      DPR_IOCTL(("dgap_tty_unthrottle start\n"));
++
++      DGAP_LOCK(ch->ch_lock, lock_flags);
++
++      ch->ch_flags &= ~(CH_RXBLOCK);
++
++#if 1
++      dgap_cmdw(ch, RRESUME, 0, 0);
++#endif
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_unthrottle finish\n"));
++}
++
++
++static void dgap_tty_start(struct tty_struct *tty)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++        ch = un->un_ch;
++        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++                return;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_IOCTL(("dgap_tty_start start\n"));
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      dgap_cmdw(ch, RESUMETX, 0, 0);
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_start finish\n"));
++}
++
++
++static void dgap_tty_stop(struct tty_struct *tty)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++        ch = un->un_ch;
++        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++                return;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_IOCTL(("dgap_tty_stop start\n"));
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      dgap_cmdw(ch, PAUSETX, 0, 0);
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_stop finish\n"));
++}
++
++
++/*
++ * dgap_tty_flush_chars()
++ *
++ * Flush the cook buffer
++ *
++ * Note to self, and any other poor souls who venture here:
++ *
++ * flush in this case DOES NOT mean dispose of the data.
++ * instead, it means "stop buffering and send it if you
++ * haven't already."  Just guess how I figured that out...   SRW 2-Jun-98
++ *
++ * It is also always called in interrupt context - JAR 8-Sept-99
++ */
++static void dgap_tty_flush_chars(struct tty_struct *tty)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++        ch = un->un_ch;
++        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++                return;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_IOCTL(("dgap_tty_flush_chars start\n"));
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      /* TODO: Do something here */
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_flush_chars finish\n"));
++}
++
++
++
++/*
++ * dgap_tty_flush_buffer()
++ *
++ * Flush Tx buffer (make in == out)
++ */
++static void dgap_tty_flush_buffer(struct tty_struct *tty)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++      u16     head = 0;
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return;
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return;
++
++        ch = un->un_ch;
++        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++                return;
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return;
++
++      DPR_IOCTL(("dgap_tty_flush_buffer on port: %d start\n", ch->ch_portnum));
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      ch->ch_flags &= ~CH_STOP;
++      head = readw(&(ch->ch_bs->tx_head));
++      dgap_cmdw(ch, FLUSHTX, (u16) head, 0 );
++      dgap_cmdw(ch, RESUMETX, 0, 0);
++      if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
++              ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
++              wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++      }
++      if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
++              ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
++              wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++      }
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_flush_buffer finish\n"));
++}
++
++
++
++/*****************************************************************************
++ *
++ * The IOCTL function and all of its helpers
++ *
++ *****************************************************************************/
++
++/*
++ * dgap_tty_ioctl()
++ *
++ * The usual assortment of ioctl's
++ */
++static int dgap_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
++              unsigned long arg)
++{
++      struct board_t *bd;
++      struct channel_t *ch;
++      struct un_t *un;
++      int rc;
++      u16     head = 0;
++      ulong   lock_flags = 0;
++      ulong   lock_flags2 = 0;
++
++
++      if (!tty || tty->magic != TTY_MAGIC)
++              return (-ENODEV);
++
++      un = tty->driver_data;
++      if (!un || un->magic != DGAP_UNIT_MAGIC)
++              return (-ENODEV);
++
++      ch = un->un_ch;
++      if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
++              return (-ENODEV);
++
++      bd = ch->ch_bd;
++      if (!bd || bd->magic != DGAP_BOARD_MAGIC)
++              return (-ENODEV);
++
++      DPR_IOCTL(("dgap_tty_ioctl start on port %d - cmd %s (%x), arg %lx\n",
++              ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++      DGAP_LOCK(bd->bd_lock, lock_flags);
++      DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++      if (un->un_open_count <= 0) {
++              DPR_BASIC(("dgap_tty_ioctl - unit not open.\n"));
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(-EIO);
++      }
++
++      switch (cmd) {
++
++      /* Here are all the standard ioctl's that we MUST implement */
++
++      case TCSBRK:
++              /*
++               * TCSBRK is SVID version: non-zero arg --> no break
++               * this behaviour is exploited by tcdrain().
++               *
++               * According to POSIX.1 spec (7.2.2.1.2) breaks should be
++               * between 0.25 and 0.5 seconds so we'll ask for something
++               * in the middle: 0.375 seconds.
++               */
++              rc = tty_check_change(tty);
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              if (rc) {
++                      return(rc);
++              }
++
++              rc = dgap_wait_for_drain(tty);
++
++              if (rc) {
++                      DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++                      return(-EINTR);
++              }
++
++              DGAP_LOCK(bd->bd_lock, lock_flags);
++              DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++              if(((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP)) {
++                      dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
++              }
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++              DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
++                      ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++                return(0);
++
++
++      case TCSBRKP:
++              /* support for POSIX tcsendbreak()
++
++               * According to POSIX.1 spec (7.2.2.1.2) breaks should be
++               * between 0.25 and 0.5 seconds so we'll ask for something
++               * in the middle: 0.375 seconds.
++               */
++              rc = tty_check_change(tty);
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              if (rc) {
++                      return(rc);
++              }
++
++              rc = dgap_wait_for_drain(tty);
++              if (rc) {
++                      DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++                      return(-EINTR);
++              }
++
++              DGAP_LOCK(bd->bd_lock, lock_flags);
++              DGAP_LOCK(ch->ch_lock, lock_flags2);
++
++              dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++              DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
++                      ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++              return(0);
++
++
++      case TIOCGSOFTCAR:
++              rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
++              if (rc) {
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      return(rc);
++              }
++              PUT_USER(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(0);
++
++      case TIOCSSOFTCAR:
++              GET_USER(arg, (unsigned long *) arg);
++              tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
++
++              dgap_param(tty);
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(0);
++
++      case TIOCMGET:
++              rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int));
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              if (rc) {
++                      return(rc);
++              }
++                return(dgap_get_modem_info(ch, (unsigned int *) arg));
++
++      case TIOCMBIS:
++      case TIOCMBIC:
++      case TIOCMSET:
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(dgap_set_modem_info(tty, cmd, (unsigned int *) arg));
++
++              /*
++               * Here are any additional ioctl's that we want to implement
++               */
++
++      case TCFLSH:
++              /*
++               * The linux tty driver doesn't have a flush
++               * input routine for the driver, assuming all backed
++               * up data is in the line disc. buffers.  However,
++               * we all know that's not the case.  Here, we
++               * act on the ioctl, but then lie and say we didn't
++               * so the line discipline will process the flush
++               * also.
++               */
++              rc = tty_check_change(tty);
++              if (rc) {
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      return(rc);
++              }
++
++              if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
++                      ch->ch_flags &= ~CH_STOP;
++                      head = readw(&(ch->ch_bs->tx_head));
++                      dgap_cmdw(ch, FLUSHTX, (u16) head, 0 );
++                      dgap_cmdw(ch, RESUMETX, 0, 0);
++                      if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
++                              ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
++                              wake_up_interruptible(&ch->ch_tun.un_flags_wait);
++                      }
++                      if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
++                              ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
++                              wake_up_interruptible(&ch->ch_pun.un_flags_wait);
++                      }
++              }
++
++              if ((arg == TCOFLUSH) || (arg == TCIOFLUSH)) {
++                      if (!(un->un_type == DGAP_PRINT)) {
++                              head = readw(&(ch->ch_bs->rx_head));
++                              writew(head, &(ch->ch_bs->rx_tail));
++                              writeb(0, &(ch->ch_bs->orun));
++                      }
++              }
++
++              /* pretend we didn't recognize this IOCTL */
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(-ENOIOCTLCMD);
++
++#ifdef TIOCGETP
++      case TIOCGETP:
++#endif
++      case TCGETS:
++      case TCGETA:
++              if (tty->ldisc.ioctl) {
++                      int retval = (-ENXIO);
++
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++                      if (tty->termios) {
++                              retval = ((tty->ldisc.ioctl) (tty, file, cmd, arg));
++                      }
++
++                      DPR_IOCTL(("dgap_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n",
++                              __LINE__, ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++                      return(retval);
++              }
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              DPR_IOCTL(("dgap_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n",
++                      __LINE__, ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++              return(-ENOIOCTLCMD);
++
++      case TCSETSF:
++      case TCSETSW:
++              /*
++               * The linux tty driver doesn't have a flush
++               * input routine for the driver, assuming all backed
++               * up data is in the line disc. buffers.  However,
++               * we all know that's not the case.  Here, we
++               * act on the ioctl, but then lie and say we didn't
++               * so the line discipline will process the flush
++               * also.
++               */
++              if (cmd == TCSETSF) {
++                      /* flush rx */
++                      ch->ch_flags &= ~CH_STOP;
++                      head = readw(&(ch->ch_bs->rx_head));
++                      writew(head, &(ch->ch_bs->rx_tail));
++              }
++
++              /* now wait for all the output to drain */
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              rc = dgap_wait_for_drain(tty);
++              if (rc) {
++                      DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++                      return(-EINTR);
++              }
++
++              DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
++                      ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg));
++
++              /* pretend we didn't recognize this */
++              return(-ENOIOCTLCMD);
++
++      case TCSETAW:
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              rc = dgap_wait_for_drain(tty);
++              if (rc) {
++                      DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++                      return(-EINTR);
++              }
++
++              /* pretend we didn't recognize this */
++              return(-ENOIOCTLCMD);
++
++      case TCXONC:
++              /*
++               * The Linux Line Discipline (LD) would do this for us if we
++               * let it, but we have the special firmware options to do this
++               * the "right way" regardless of hardware or software flow
++               * control so we'll do it outselves instead of letting the LD
++               * do it.
++               */
++              rc = tty_check_change(tty);
++              if (rc) {
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      return(rc);
++              }
++
++              DPR_IOCTL(("dxb_ioctl - in TCXONC - %d\n", cmd));
++              switch (arg) {
++
++              case TCOON:
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      dgap_tty_start(tty);
++                      return(0);
++              case TCOOFF:
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      dgap_tty_stop(tty);
++                      return(0);
++              case TCION:
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      /* Make the ld do it */
++                      return(-ENOIOCTLCMD);
++              case TCIOFF:
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      /* Make the ld do it */
++                      return(-ENOIOCTLCMD);
++              default:
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      return(-EINVAL);
++              }
++
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(-ENOIOCTLCMD);
++
++      case DIGI_GETA:
++              /* get information for ditty */
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(dgap_tty_digigeta(tty, (struct digi_t *) arg));
++
++      case DIGI_SETAW:
++      case DIGI_SETAF:
++
++              /* set information for ditty */
++              if (cmd == (DIGI_SETAW)) {
++
++                      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++                      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++                      rc = dgap_wait_for_drain(tty);
++                      if (rc) {
++                              DPR_IOCTL(("dgap_tty_ioctl - bad return: %d ", rc));
++                              return(-EINTR);
++                      }
++                      DGAP_LOCK(bd->bd_lock, lock_flags);
++                      DGAP_LOCK(ch->ch_lock, lock_flags2);
++              }
++              else {
++                      if (tty->ldisc.flush_buffer)
++                              tty->ldisc.flush_buffer(tty);
++              }
++              /* fall thru */
++
++      case DIGI_SETA:
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++              return(dgap_tty_digiseta(tty, (struct digi_t *) arg));
++
++      default:
++              DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++              DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++              DPR_IOCTL(("dgap_tty_ioctl - in default\n"));
++              DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n",
++                      dgap_ioctl_name(cmd), cmd, arg));
++
++              return(-ENOIOCTLCMD);
++      }
++
++      DGAP_UNLOCK(ch->ch_lock, lock_flags2);
++      DGAP_UNLOCK(bd->bd_lock, lock_flags);
++
++      DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n",
++              dgap_ioctl_name(cmd), cmd, arg));
++
++      return(0);
++}
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_tty.h   2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_tty.h        2003-09-27 11:38:20.971340256 +0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_TTY_H
++#define __DGAP_TTY_H
++
++#include "dgap_driver.h"
++
++int   dgap_tty_register(struct board_t *brd);
++
++int   dgap_tty_preinit(void);
++int     dgap_tty_init(struct board_t *);
++
++void  dgap_tty_post_uninit(void);
++void  dgap_tty_uninit(struct board_t *);
++
++int   dgap_event(struct board_t *);
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/dgap_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/dgap_types.h 2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/dgap_types.h      2003-09-27 11:38:20.971340256 +0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DGAP_TYPES_H
++#define __DGAP_TYPES_H
++
++#if defined(__KERNEL__)
++# include <linux/string.h>
++#endif
++
++#include <linux/types.h>
++
++#if !defined (TRUE)
++# define      TRUE            1
++#endif
++
++#if !defined (FALSE)
++# define      FALSE           0
++#endif
++
++#if !defined(NULL)
++# define      NULL            0
++#endif
++
++/* Required for our shared headers! */
++typedef unsigned char         uchar;
++
++#endif
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/digi.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/digi.h       2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/digi.h    2003-09-27 11:38:20.973339952 +0800
+@@ -0,0 +1,369 @@
++/*
++ * Copyright 2003 Digi International (www.digi.com)
++ *    Scott H Kilau <Scott_Kilau at digi dot 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, EXPRESS OR IMPLIED; 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.
++ *
++ * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++ *
++ *    NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
++ */
++
++#ifndef __DIGI_H
++#define __DIGI_H
++
++/************************************************************************
++ ***  Definitions for Digi ditty(1) command.
++ ************************************************************************/
++
++
++/*
++ * Copyright (c) 1988-96 Digi International Inc., All Rights Reserved.
++ */
++
++/************************************************************************
++ * This module provides application access to special Digi
++ * serial line enhancements which are not standard UNIX(tm) features.
++ ************************************************************************/
++
++#if !defined(TIOCMODG)
++
++#define       TIOCMODG        ('d'<<8) | 250          /* get modem ctrl state */
++#define       TIOCMODS        ('d'<<8) | 251          /* set modem ctrl state */
++
++#ifndef TIOCM_LE
++#define               TIOCM_LE        0x01            /* line enable          */
++#define               TIOCM_DTR       0x02            /* data terminal ready  */
++#define               TIOCM_RTS       0x04            /* request to send      */
++#define               TIOCM_ST        0x08            /* secondary transmit   */
++#define               TIOCM_SR        0x10            /* secondary receive    */
++#define               TIOCM_CTS       0x20            /* clear to send        */
++#define               TIOCM_CAR       0x40            /* carrier detect       */
++#define               TIOCM_RNG       0x80            /* ring indicator       */
++#define               TIOCM_DSR       0x100           /* data set ready       */
++#define               TIOCM_RI        TIOCM_RNG       /* ring (alternate)     */
++#define               TIOCM_CD        TIOCM_CAR       /* carrier detect (alt) */
++#endif
++
++#endif
++
++#if !defined(TIOCMSET)
++#define       TIOCMSET        ('d'<<8) | 252          /* set modem ctrl state */
++#define       TIOCMGET        ('d'<<8) | 253          /* set modem ctrl state */
++#endif
++
++#if !defined(TIOCMBIC)
++#define       TIOCMBIC        ('d'<<8) | 254          /* set modem ctrl state */
++#define       TIOCMBIS        ('d'<<8) | 255          /* set modem ctrl state */
++#endif
++
++
++#if !defined(TIOCSDTR)
++#define       TIOCSDTR        ('e'<<8) | 0            /* set DTR              */
++#define       TIOCCDTR        ('e'<<8) | 1            /* clear DTR            */
++#endif
++
++/************************************************************************
++ * Ioctl command arguments for DIGI parameters.
++ ************************************************************************/
++#define DIGI_GETA     ('e'<<8) | 94           /* Read params          */
++
++#define DIGI_SETA     ('e'<<8) | 95           /* Set params           */
++#define DIGI_SETAW    ('e'<<8) | 96           /* Drain & set params   */
++#define DIGI_SETAF    ('e'<<8) | 97           /* Drain, flush & set params */
++
++#define DIGI_KME      ('e'<<8) | 98           /* Read/Write Host      */
++                                              /* Adapter Memory       */
++
++#define       DIGI_GETFLOW    ('e'<<8) | 99           /* Get startc/stopc flow */
++                                              /* control characters    */
++#define       DIGI_SETFLOW    ('e'<<8) | 100          /* Set startc/stopc flow */
++                                              /* control characters    */
++#define       DIGI_GETAFLOW   ('e'<<8) | 101          /* Get Aux. startc/stopc */
++                                              /* flow control chars    */
++#define       DIGI_SETAFLOW   ('e'<<8) | 102          /* Set Aux. startc/stopc */
++                                              /* flow control chars    */
++
++#define DIGI_GEDELAY  ('d'<<8) | 246          /* Get edelay */
++#define DIGI_SEDELAY  ('d'<<8) | 247          /* Set edelay */
++
++struct        digiflow_t {
++      unsigned char   startc;                         /* flow cntl start char */
++      unsigned char   stopc;                          /* flow cntl stop char  */
++};
++
++
++#ifdef        FLOW_2200
++#define       F2200_GETA      ('e'<<8) | 104          /* Get 2x36 flow cntl flags */
++#define       F2200_SETAW     ('e'<<8) | 105          /* Set 2x36 flow cntl flags */
++#define               F2200_MASK      0x03            /* 2200 flow cntl bit mask  */
++#define               FCNTL_2200      0x01            /* 2x36 terminal flow cntl  */
++#define               PCNTL_2200      0x02            /* 2x36 printer flow cntl   */
++#define       F2200_XON       0xf8
++#define       P2200_XON       0xf9
++#define       F2200_XOFF      0xfa
++#define       P2200_XOFF      0xfb
++
++#define       FXOFF_MASK      0x03                    /* 2200 flow status mask    */
++#define       RCVD_FXOFF      0x01                    /* 2x36 Terminal XOFF rcvd  */
++#define       RCVD_PXOFF      0x02                    /* 2x36 Printer XOFF rcvd   */
++#endif
++
++/************************************************************************
++ * Values for digi_flags
++ ************************************************************************/
++#define DIGI_IXON     0x0001          /* Handle IXON in the FEP       */
++#define DIGI_FAST     0x0002          /* Fast baud rates              */
++#define RTSPACE               0x0004          /* RTS input flow control       */
++#define CTSPACE               0x0008          /* CTS output flow control      */
++#define DSRPACE               0x0010          /* DSR output flow control      */
++#define DCDPACE               0x0020          /* DCD output flow control      */
++#define DTRPACE               0x0040          /* DTR input flow control       */
++#define DIGI_COOK     0x0080          /* Cooked processing done in FEP */
++#define DIGI_FORCEDCD 0x0100          /* Force carrier                */
++#define       DIGI_ALTPIN     0x0200          /* Alternate RJ-45 pin config   */
++#define       DIGI_AIXON      0x0400          /* Aux flow control in fep      */
++#define       DIGI_PRINTER    0x0800          /* Hold port open for flow cntrl*/
++#define DIGI_PP_INPUT 0x1000          /* Change parallel port to input*/
++#define       DIGI_422        0x4000          /* for 422/232 selectable panel */
++
++/************************************************************************
++ * These options are not supported on the comxi.
++ ************************************************************************/
++#define       DIGI_COMXI      (DIGI_FAST|DIGI_COOK|DSRPACE|DCDPACE|DTRPACE)
++
++#define DIGI_PLEN     28              /* String length                */
++#define       DIGI_TSIZ       10              /* Terminal string len          */
++
++/************************************************************************
++ * Structure used with ioctl commands for DIGI parameters.
++ ************************************************************************/
++struct digi_t {
++      unsigned short  digi_flags;             /* Flags (see above)    */
++      unsigned short  digi_maxcps;            /* Max printer CPS      */
++      unsigned short  digi_maxchar;           /* Max chars in print queue */
++      unsigned short  digi_bufsize;           /* Buffer size          */
++      unsigned char   digi_onlen;             /* Length of ON string  */
++      unsigned char   digi_offlen;            /* Length of OFF string */
++      char            digi_onstr[DIGI_PLEN];  /* Printer on string    */
++      char            digi_offstr[DIGI_PLEN]; /* Printer off string   */
++      char            digi_term[DIGI_TSIZ];   /* terminal string      */
++};
++
++/************************************************************************
++ * KME definitions and structures.
++ ************************************************************************/
++#define       RW_IDLE         0       /* Operation complete                   */
++#define       RW_READ         1       /* Read Concentrator Memory             */
++#define       RW_WRITE        2       /* Write Concentrator Memory            */
++
++struct rw_t {
++      unsigned char   rw_req;         /* Request type                 */
++      unsigned char   rw_board;       /* Host Adapter board number    */
++      unsigned char   rw_conc;        /* Concentrator number          */
++      unsigned char   rw_reserved;    /* Reserved for expansion       */
++      unsigned long   rw_addr;        /* Address in concentrator      */
++      unsigned short  rw_size;        /* Read/write request length    */
++      unsigned char   rw_data[128];   /* Data to read/write           */
++};
++
++/***********************************************************************
++ * Shrink Buffer and Board Information definitions and structures.
++
++ ************************************************************************/
++                      /* Board type return codes */
++#define       PCXI_TYPE 1     /* Board type at the designated port is a PC/Xi */
++#define PCXM_TYPE 2     /* Board type at the designated port is a PC/Xm */
++#define       PCXE_TYPE 3     /* Board type at the designated port is a PC/Xe */
++#define       MCXI_TYPE 4     /* Board type at the designated port is a MC/Xi */
++#define COMXI_TYPE 5     /* Board type at the designated port is a COM/Xi */
++
++                       /* Non-Zero Result codes. */
++#define RESULT_NOBDFND 1 /* A Digi product at that port is not config installed */
++#define RESULT_NODESCT 2 /* A memory descriptor was not obtainable */
++#define RESULT_NOOSSIG 3 /* FEP/OS signature was not detected on the board */
++#define RESULT_TOOSML  4 /* Too small an area to shrink.  */
++#define RESULT_NOCHAN  5 /* Channel structure for the board was not found */
++
++struct shrink_buf_struct {
++      unsigned long   shrink_buf_vaddr;       /* Virtual address of board */
++      unsigned long   shrink_buf_phys;        /* Physical address of board */
++      unsigned long   shrink_buf_bseg;        /* Amount of board memory */
++      unsigned long   shrink_buf_hseg;        /* '186 Begining of Dual-Port */
++
++      unsigned long   shrink_buf_lseg;        /* '186 Begining of freed memory                                                */
++      unsigned long   shrink_buf_mseg;        /* Linear address from start of
++                                                 dual-port were freed memory
++                                                 begins, host viewpoint. */
++
++      unsigned long   shrink_buf_bdparam;     /* Parameter for xxmemon and
++                                                 xxmemoff */
++
++      unsigned long   shrink_buf_reserva;     /* Reserved */
++      unsigned long   shrink_buf_reservb;     /* Reserved */
++      unsigned long   shrink_buf_reservc;     /* Reserved */
++      unsigned long   shrink_buf_reservd;     /* Reserved */
++
++      unsigned char   shrink_buf_result;      /* Reason for call failing
++                                                 Zero is Good return */
++      unsigned char   shrink_buf_init;        /* Non-Zero if it caused an
++                                                 xxinit call. */
++
++      unsigned char   shrink_buf_anports;     /* Number of async ports  */
++      unsigned char   shrink_buf_snports;     /* Number of sync  ports */
++      unsigned char   shrink_buf_type;        /* Board type 1 = PC/Xi,
++                                                            2 = PC/Xm,
++                                                            3 = PC/Xe
++                                                            4 = MC/Xi
++                                                            5 = COMX/i */
++      unsigned char   shrink_buf_card;        /* Card number */
++
++};
++
++/************************************************************************
++ * Structure to get driver status information
++ ************************************************************************/
++struct digi_dinfo {
++      unsigned long   dinfo_nboards;          /* # boards configured  */
++      char            dinfo_reserved[12];     /* for future expansion */
++      char            dinfo_version[16];      /* driver version       */
++};
++
++#define       DIGI_GETDD      ('d'<<8) | 248          /* get driver info      */
++
++/************************************************************************
++ * Structure used with ioctl commands for per-board information
++ *
++ * physsize and memsize differ when board has "windowed" memory
++ ************************************************************************/
++struct digi_info {
++      unsigned long   info_bdnum;             /* Board number (0 based)  */
++      unsigned long   info_ioport;            /* io port address         */
++      unsigned long   info_physaddr;          /* memory address          */
++      unsigned long   info_physsize;          /* Size of host mem window */
++      unsigned long   info_memsize;           /* Amount of dual-port mem */
++                                              /* on board                */
++      unsigned short  info_bdtype;            /* Board type              */
++      unsigned short  info_nports;            /* number of ports         */
++      char            info_bdstate;           /* board state             */
++      char            info_reserved[7];       /* for future expansion    */
++};
++
++#define       DIGI_GETBD      ('d'<<8) | 249          /* get board info          */
++
++struct digi_stat {
++      unsigned int    info_chan;              /* Channel number (0 based)  */
++      unsigned int    info_brd;               /* Board number (0 based)  */
++      unsigned long   info_cflag;             /* cflag for channel       */
++      unsigned long   info_iflag;             /* iflag for channel       */
++      unsigned long   info_oflag;             /* oflag for channel       */
++      unsigned long   info_mstat;             /* mstat for channel       */
++      unsigned long   info_tx_data;           /* tx_data for channel       */
++      unsigned long   info_rx_data;           /* rx_data for channel       */
++      unsigned long   info_hflow;             /* hflow for channel       */
++      unsigned long   info_reserved[8];       /* for future expansion    */
++};
++
++#define       DIGI_GETSTAT    ('d'<<8) | 244          /* get board info          */
++/************************************************************************
++ *
++ * Structure used with ioctl commands for per-channel information
++ *
++ ************************************************************************/
++struct digi_ch {
++      unsigned long   info_bdnum;             /* Board number (0 based)  */
++      unsigned long   info_channel;           /* Channel index number    */
++      unsigned long   info_ch_cflag;          /* Channel cflag           */
++      unsigned long   info_ch_iflag;          /* Channel iflag           */
++      unsigned long   info_ch_oflag;          /* Channel oflag           */
++      unsigned long   info_chsize;            /* Channel structure size  */
++      unsigned long   info_sleep_stat;        /* sleep status            */
++      dev_t           info_dev;               /* device number           */
++      unsigned char   info_initstate;         /* Channel init state      */
++      unsigned char   info_running;           /* Channel running state   */
++      long            reserved[8];            /* reserved for future use */
++};
++
++/*
++* This structure is used with the DIGI_FEPCMD ioctl to
++* tell the driver which port to send the command for.
++*/
++struct digi_cmd {
++      int     cmd;
++      int     word;
++      int     ncmds;
++      int     chan; /* channel index (zero based) */
++      int     bdid; /* board index (zero based) */
++};
++
++/*
++*  info_sleep_stat defines
++*/
++#define INFO_RUNWAIT  0x0001
++#define INFO_WOPEN    0x0002
++#define INFO_TTIOW    0x0004
++#define INFO_CH_RWAIT 0x0008
++#define INFO_CH_WEMPTY        0x0010
++#define INFO_CH_WLOW  0x0020
++#define INFO_XXBUF_BUSY 0x0040
++
++#define       DIGI_GETCH      ('d'<<8) | 245          /* get board info          */
++
++/* Board type definitions */
++
++#define       SUBTYPE         0007
++#define       T_PCXI          0000
++#define T_PCXM                0001
++#define T_PCXE                0002
++#define T_PCXR                0003
++#define T_SP          0004
++#define T_SP_PLUS     0005
++#     define T_HERC   0000
++#     define T_HOU    0001
++#     define T_LON    0002
++#     define T_CHA    0003
++#define FAMILY                0070
++#define T_COMXI               0000
++#define T_PCXX                0010
++#define T_CX          0020
++#define T_EPC         0030
++#define       T_PCLITE        0040
++#define       T_SPXX          0050
++#define       T_AVXX          0060
++#define T_DXB         0070
++#define T_A2K_4_8     0070
++#define BUSTYPE               0700
++#define T_ISABUS      0000
++#define T_MCBUS               0100
++#define       T_EISABUS       0200
++#define       T_PCIBUS        0400
++
++/* Board State Definitions */
++
++#define       BD_RUNNING      0x0
++#define       BD_REASON       0x7f
++#define       BD_NOTFOUND     0x1
++#define       BD_NOIOPORT     0x2
++#define       BD_NOMEM        0x3
++#define       BD_NOBIOS       0x4
++#define       BD_NOFEP        0x5
++#define       BD_FAILED       0x6
++#define BD_ALLOCATED  0x7
++#define BD_TRIBOOT    0x8
++#define       BD_BADKME       0x80
++
++#define DIGI_SPOLL            ('d'<<8) | 254  /* change poller rate   */
++
++#endif /* DIGI_H */
+Index: linux-2.6.0-test5/drivers/char/digi/dgap/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/digi/dgap/Makefile     2003-09-27 11:38:18.449723600 +0800
++++ linux-2.6.0-test5/drivers/char/digi/dgap/Makefile  2003-09-27 11:38:20.973339952 +0800
+@@ -0,0 +1,19 @@
++# Makefile for the in-kernel version of the DGAP driver.
++
++PACKAGE=dgap
++TRUE_VERSION="1.0-2"
++DGAP_PART_NUM=40002347_A-INKERNEL
++SBINDIR=/usr/sbin
++
++RPMNAME := $(PACKAGE)-$(TRUE_VERSION)
++PARTNUM := $(DGAP_PART_NUM)
++
++# Send in some extra things...
++EXTRA_CFLAGS += -DDGAP_TRACER -DSBINDIR=\"$(SBINDIR)\" \
++              -DDG_NAME=\"$(RPMNAME)\" -DDG_PART=\"$(PARTNUM)\"
++
++obj-$(CONFIG_DIGI_DGAP) += dgap.o
++
++dgap-objs :=  dgap_driver.o dgap_mgmt.o\
++              dgap_parse.o dgap_proc.o\
++              dgap_trace.o dgap_tty.o
+Index: linux-2.6.0-test5/drivers/char/drm/drm_drv.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/drm/drm_drv.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/drm/drm_drv.h       2003-09-27 11:38:20.982338584 +0800
+@@ -848,7 +848,7 @@
+        */
+       DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+-                 current->pid, (long)dev->device, dev->open_count );
++                 current->pid, (long)old_encode_dev(dev->device), dev->open_count );
+       if ( priv->lock_count && dev->lock.hw_lock &&
+            _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+@@ -983,7 +983,7 @@
+       ++priv->ioctl_count;
+       DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
+-                 current->pid, cmd, nr, (long)dev->device, 
++                 current->pid, cmd, nr, (long)old_encode_dev(dev->device), 
+                  priv->authenticated );
+       if ( nr >= DRIVER_IOCTL_COUNT ) {
+Index: linux-2.6.0-test5/drivers/char/drm/drm_fops.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/drm/drm_fops.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/drm/drm_fops.h      2003-09-27 11:38:20.984338280 +0800
+@@ -111,7 +111,7 @@
+       drm_device_t  *dev    = priv->dev;
+       DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
+-                current->pid, (long)dev->device, dev->open_count);
++                current->pid, (long)old_encode_dev(dev->device), dev->open_count);
+       return 0;
+ }
+@@ -122,7 +122,7 @@
+       drm_device_t  *dev    = priv->dev;
+       int           retcode;
+-      DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device);
++      DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(dev->device));
+       retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+       if (retcode < 0) return retcode;
+       return 0;
+Index: linux-2.6.0-test5/drivers/char/drm/drm_proc.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/drm/drm_proc.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/drm/drm_proc.h      2003-09-27 11:38:20.989337520 +0800
+@@ -184,9 +184,9 @@
+       if (dev->unique) {
+               DRM_PROC_PRINT("%s 0x%lx %s\n",
+-                             dev->name, (long)dev->device, dev->unique);
++                             dev->name, (long)old_encode_dev(dev->device), dev->unique);
+       } else {
+-              DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device);
++              DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)old_encode_dev(dev->device));
+       }
+       if (len > request + offset) return request;
+Index: linux-2.6.0-test5/drivers/char/epca.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/epca.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/epca.c      2003-09-27 11:38:21.025332048 +0800
+@@ -3,8 +3,10 @@
+  
+       Copyright (C) 1996  Digi International.
+  
+-      For technical support please email digiLinux@dgii.com or
+-      call Digi tech support at (612) 912-3456
++      NOTE:   As of the 2.6 Linux kernel, Digi International
++              no longer supports this version of the driver.
++              If you have a PCI EPCA DigiBoard, please use the DGAP
++              driver instead.
+       Much of this design and code came from epca.c which was 
+       copyright (C) 1994, 1995 Troy De Jongh, and subsquently 
+@@ -44,9 +46,12 @@
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+-#ifdef CONFIG_PCI
+-#define ENABLE_PCI
+-#endif /* CONFIG_PCI */
++/*
++ * NOTE: DO NOT enable PCI in this driver anymore!
++ * There is a new replacement for this driver for the PCI boards
++ * called DGAP which should be used instead.
++ */
++#undef ENABLE_PCI
+ #define putUser(arg1, arg2) put_user(arg1, (unsigned long *)arg2)
+ #define getUser(arg1, arg2) get_user(arg1, (unsigned int *)arg2)
+@@ -3868,7 +3873,7 @@
+ };
+-static int __init epca_init_one (struct pci_dev *pdev,
++static int __devinit epca_init_one (struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
+ {
+       static int board_num = -1;
+Index: linux-2.6.0-test5/drivers/char/ftape/lowlevel/ftape-init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/ftape/lowlevel/ftape-init.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/ftape/lowlevel/ftape-init.c 2003-09-27 11:38:21.028331592 +0800
+@@ -55,14 +55,24 @@
+ char ft_dat[] __initdata = "$Date: 2003/10/02 19:51:59 $";
++#ifndef CONFIG_FT_NO_TRACE_AT_ALL
++static int ft_tracing = -1;
++#endif
++
++
+ /*  Called by modules package when installing the driver
+  *  or by kernel during the initialization phase
+  */
+-int __init ftape_init(void)
++static int __init ftape_init(void)
+ {
+       TRACE_FUN(ft_t_flow);
+ #ifdef MODULE
++#ifndef CONFIG_FT_NO_TRACE_AT_ALL
++      if (ft_tracing != -1) {
++              ftape_tracing = ft_tracing;
++      }
++#endif
+       printk(KERN_INFO FTAPE_VERSION "\n");
+         if (TRACE_LEVEL >= ft_t_info) {
+               printk(
+@@ -112,13 +122,6 @@
+ #endif
+       TRACE_EXIT 0;
+ }
+-
+-#ifdef MODULE
+-
+-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
+-static int ft_tracing = -1;
+-#endif
+-
+ #define FT_MOD_PARM(var,type,desc) \
+       MODULE_PARM(var,type); MODULE_PARM_DESC(var,desc)
+@@ -141,21 +144,7 @@
+       "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives.");
+ MODULE_LICENSE("GPL");
+-/*  Called by modules package when installing the driver
+- */
+-int init_module(void)
+-{
+-#ifndef CONFIG_FT_NO_TRACE_AT_ALL
+-      if (ft_tracing != -1) {
+-              ftape_tracing = ft_tracing;
+-      }
+-#endif
+-      return ftape_init();
+-}
+-
+-/*  Called by modules package when removing the driver
+- */
+-void cleanup_module(void)
++static void __exit ftape_exit(void)
+ {
+       TRACE_FUN(ft_t_flow);
+@@ -166,4 +155,6 @@
+         printk(KERN_INFO "ftape: unloaded.\n");
+       TRACE_EXIT;
+ }
+-#endif /* MODULE */
++
++module_init(ftape_init);
++module_exit(ftape_exit);
+Index: linux-2.6.0-test5/drivers/char/hvc_console.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/hvc_console.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/hvc_console.c       2003-09-27 11:38:21.030331288 +0800
+@@ -284,9 +284,6 @@
+       if (tty_register_driver(hvc_driver))
+               panic("Couldn't register hvc console driver\n");
+-      for (i = 0; i < num; i++)
+-              tty_register_device(hvc_driver, i, NULL);
+-
+       if (num > 0)
+               kernel_thread(khvcd, NULL, CLONE_KERNEL);
+Index: linux-2.6.0-test5/drivers/char/hw_random.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/hw_random.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/hw_random.c 2003-09-27 11:38:21.035330528 +0800
+@@ -149,7 +149,7 @@
+  * register a pci_driver, because someone else might one day
+  * want to register another driver on the same PCI id.
+  */
+-static struct pci_device_id rng_pci_tbl[] __initdata = {
++static struct pci_device_id rng_pci_tbl[] = {
+       { 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
+       { 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
+Index: linux-2.6.0-test5/drivers/char/istallion.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/istallion.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/istallion.c 2003-09-27 11:38:21.070325208 +0800
+@@ -2303,7 +2303,7 @@
+       /*
+        * FIXME: There's a module removal race here: tty_hangup
+-       * calls schedule_task which will call into this
++       * calls schedule_work which will call into this
+        * driver later.
+        */
+       portp = (stliport_t *) arg;
+@@ -2944,7 +2944,7 @@
+                           ((portp->sigs & TIOCM_CD) == 0)) {
+                               if (portp->flags & ASYNC_CHECK_CD) {
+                                       if (tty)
+-                                              schedule_task(&portp->tqhangup);
++                                              schedule_work(&portp->tqhangup);
+                               }
+                       }
+               }
+Index: linux-2.6.0-test5/drivers/char/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/Kconfig        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/Kconfig     2003-09-27 11:38:21.080323688 +0800
+@@ -143,15 +143,33 @@
+         status of the Cyclades-Z ports. The default op mode is polling. If
+         unsure, say N.
++config DIGI_DGAP
++      tristate "Digi International EPCA PCI Acceleport Async Support"
++      depends on SERIAL_NONSTANDARD
++      ---help---
++        This is a driver for Digi International's Xr, Xem, C/X and EPC/X PCI
++        series of cards which provide multiple serial ports. You would need
++        something like this to connect more than two modems to your Linux
++        box, for instance in order to become a dial-in server.
++        This driver supports only the PCI versions of these cards.
++        If you have a card like this, say Y here and read the file
++        <file:Documentation/digidgap.txt>.
++
++        NOTE: There is another, separate driver for the EPCA ISA boards:
++        "Digiboard Intelligent ISA Async Support" below.
++
++        If you want to compile this driver as a module, say M here: the
++        module will be called dgap.
++
+ config DIGIEPCA
+-      tristate "Digiboard Intelligent Async Support"
++      tristate "Digiboard Intelligent ISA Async Support"
+       depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+       ---help---
+-        This is a driver for Digi International's Xx, Xeve, and Xem series
+-        of cards which provide multiple serial ports. You would need
++        This is a driver for Digi International's Xx, Xeve, and Xem ISA
++        series of cards which provide multiple serial ports. You would need
+         something like this to connect more than two modems to your Linux
+         box, for instance in order to become a dial-in server. This driver
+-        supports the original PC (ISA) boards as well as PCI, and EISA. If
++        supports the original PC (ISA) boards as well as EISA. If
+         you have a card like this, say Y here and read the file
+         <file:Documentation/digiepca.txt>.
+@@ -159,12 +177,12 @@
+         "Digiboard PC/Xx Support" below. You should (and can) only select
+         one of the two drivers.
+-        If you want to compile this driver as a module, say M here and read
+-        <file:Documentation/modules.txt>. The module will be called epca.
++        If you want to compile this driver as a module, say M here: the
++        module will be called epca.
+ config DIGI
+       tristate "Digiboard PC/Xx Support"
+-      depends on SERIAL_NONSTANDARD && DIGIEPCA=n && BROKEN_ON_SMP
++      depends on SERIAL_NONSTANDARD && DIGIEPCA=n && BROKEN_ON_SMP && OBSOLETE
+       help
+         This is a driver for the Digiboard PC/Xe, PC/Xi, and PC/Xeve cards
+         that give you many serial ports. You would need something like this
+@@ -172,8 +190,8 @@
+         order to become a dial-in server. If you have a card like that, say
+         Y here and read the file <file:Documentation/digiboard.txt>.
+-        If you want to compile this driver as a module, say M here and read
+-        <file:Documentation/modules.txt>. The module will be called pcxx.
++        If you want to compile this driver as a module, say M here: the
++        module will be called pcxx.
+ config ESPSERIAL
+       tristate "Hayes ESP serial port support"
+@@ -352,7 +370,7 @@
+ config ISTALLION
+       tristate "Stallion EC8/64, ONboard, Brumby support"
+-      depends on STALDRV && BROKEN
++      depends on STALDRV && BROKEN_ON_SMP
+       help
+         If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
+         serial multiport card, say Y here. Make sure to read
+@@ -959,6 +977,7 @@
+ config MWAVE
+       tristate "ACP Modem (Mwave) support"
+       depends on X86
++      select SERIAL_8250
+       ---help---
+         The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
+         kernel driver and a user level application. Together these components
+@@ -1001,6 +1020,7 @@
+ config HANGCHECK_TIMER
+       tristate "Hangcheck timer"
++      depends on X86_64 || X86
+       help
+         The hangcheck-timer module detects when the system has gone
+         out to lunch past a certain margin.  It can reboot the system
+Index: linux-2.6.0-test5/drivers/char/keyboard.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/keyboard.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/keyboard.c  2003-09-27 11:38:21.088322472 +0800
+@@ -205,7 +205,7 @@
+       INPUT_KEYCODE(dev, scancode) = keycode;
+       for (i = 0; i < dev->keycodemax; i++)
+-              if(INPUT_KEYCODE(dev, scancode) == oldkey)
++              if(keycode == oldkey)
+                       break;
+       if (i == dev->keycodemax)
+               clear_bit(oldkey, dev->keybit);
+@@ -1058,6 +1058,9 @@
+       }
+       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
+Index: linux-2.6.0-test5/drivers/char/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/Makefile       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/Makefile    2003-09-27 11:38:21.090322168 +0800
+@@ -7,7 +7,7 @@
+ #
+ FONTMAPFILE = cp437.uni
+-obj-y  += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o
++obj-y  += mem.o random.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o
+ obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o
+ obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
+@@ -18,6 +18,7 @@
+ obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
+ obj-$(CONFIG_DIGI) += pcxx.o
+ obj-$(CONFIG_DIGIEPCA) += epca.o
++obj-$(CONFIG_DIGI_DGAP) += digi/dgap/
+ obj-$(CONFIG_CYCLADES) += cyclades.o
+ obj-$(CONFIG_STALLION) += stallion.o
+ obj-$(CONFIG_ISTALLION) += istallion.o
+Index: linux-2.6.0-test5/drivers/char/mem.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/mem.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/mem.c       2003-09-27 11:38:21.094321560 +0800
+@@ -680,18 +680,9 @@
+                               S_IFCHR | devlist[i].mode, devlist[i].name);
+       }
+       
+-      rand_initialize();
+ #if defined (CONFIG_FB)
+       fbmem_init();
+ #endif
+-      tty_init();
+-#ifdef CONFIG_M68K_PRINTER
+-      lp_m68k_init();
+-#endif
+-      misc_init();
+-#ifdef CONFIG_FTAPE
+-      ftape_init();
+-#endif
+       return 0;
+ }
+Index: linux-2.6.0-test5/drivers/char/misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/misc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/misc.c      2003-09-27 11:38:21.097321104 +0800
+@@ -43,6 +43,7 @@
+ #include <linux/major.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include <linux/stat.h>
+ #include <linux/init.h>
+@@ -53,7 +54,7 @@
+ /*
+  * Head entry for the doubly linked miscdevice list
+  */
+-static struct miscdevice misc_list = { 0, "head", NULL, &misc_list, &misc_list };
++static LIST_HEAD(misc_list);
+ static DECLARE_MUTEX(misc_sem);
+ /*
+@@ -73,30 +74,64 @@
+ extern int tosh_init(void);
+ extern int i8k_init(void);
+-static int misc_read_proc(char *buf, char **start, off_t offset,
+-                        int len, int *eof, void *private)
++#ifdef CONFIG_PROC_FS
++static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       struct miscdevice *p;
+-      int written;
++      loff_t off = 0;
+-      written=0;
+-      for (p = misc_list.next; p != &misc_list && written < len; p = p->next) {
+-              written += sprintf(buf+written, "%3i %s\n",p->minor, p->name ?: "");
+-              if (written < offset) {
+-                      offset -= written;
+-                      written = 0;
+-              }
+-      }
+-      *start = buf + offset;
+-      written -= offset;
+-      if(written > len) {
+-              *eof = 0;
+-              return len;
++      down(&misc_sem);
++      list_for_each_entry(p, &misc_list, list) {
++              if (*pos == off++) 
++                      return p;
+       }
+-      *eof = 1;
+-      return (written<0) ? 0 : written;
++      return NULL;
++}
++
++static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct list_head *n = ((struct miscdevice *)v)->list.next;
++
++      ++*pos;
++
++      return (n != &misc_list) ? list_entry(n, struct miscdevice, list)
++               : NULL;
++}
++
++static void misc_seq_stop(struct seq_file *seq, void *v)
++{
++      up(&misc_sem);
++}
++
++static int misc_seq_show(struct seq_file *seq, void *v)
++{
++      const struct miscdevice *p = v;
++
++      seq_printf(seq, "%3i %s\n", p->minor, p->name ? p->name : "");
++      return 0;
++}
++
++
++static struct seq_operations misc_seq_ops = {
++      .start = misc_seq_start,
++      .next  = misc_seq_next,
++      .stop  = misc_seq_stop,
++      .show  = misc_seq_show,
++};
++
++static int misc_seq_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &misc_seq_ops);
+ }
++static struct file_operations misc_proc_fops = {
++      .owner   = THIS_MODULE,
++      .open    = misc_seq_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = seq_release,
++};
++#endif
+ static int misc_open(struct inode * inode, struct file * file)
+ {
+@@ -107,21 +142,27 @@
+       
+       down(&misc_sem);
+       
+-      c = misc_list.next;
+-
+-      while ((c != &misc_list) && (c->minor != minor))
+-              c = c->next;
+-      if (c != &misc_list)
+-              new_fops = fops_get(c->fops);
++      list_for_each_entry(c, &misc_list, list) {
++              if (c->minor == minor) {
++                      new_fops = fops_get(c->fops);           
++                      break;
++              }
++      }
++              
+       if (!new_fops) {
+               up(&misc_sem);
+               request_module("char-major-%d-%d", MISC_MAJOR, minor);
+               down(&misc_sem);
+-              c = misc_list.next;
+-              while ((c != &misc_list) && (c->minor != minor))
+-                      c = c->next;
+-              if (c == &misc_list || (new_fops = fops_get(c->fops)) == NULL)
+-                      goto fail;
++
++              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;
+       }
+       err = 0;
+@@ -166,16 +207,12 @@
+ {
+       struct miscdevice *c;
+       
+-      if (misc->next || misc->prev)
+-              return -EBUSY;
+       down(&misc_sem);
+-      c = misc_list.next;
+-
+-      while ((c != &misc_list) && (c->minor != misc->minor))
+-              c = c->next;
+-      if (c != &misc_list) {
+-              up(&misc_sem);
+-              return -EBUSY;
++      list_for_each_entry(c, &misc_list, list) {
++              if (c->minor == misc->minor) {
++                      up(&misc_sem);
++                      return -EBUSY;
++              }
+       }
+       if (misc->minor == MISC_DYNAMIC_MINOR) {
+@@ -205,10 +242,7 @@
+        * Add it to the front, so that later devices can "override"
+        * earlier defaults
+        */
+-      misc->prev = &misc_list;
+-      misc->next = misc_list.next;
+-      misc->prev->next = misc;
+-      misc->next->prev = misc;
++      list_add(&misc->list, &misc_list);
+       up(&misc_sem);
+       return 0;
+ }
+@@ -226,13 +260,12 @@
+ int misc_deregister(struct miscdevice * misc)
+ {
+       int i = misc->minor;
+-      if (!misc->next || !misc->prev)
++
++      if (list_empty(&misc->list))
+               return -EINVAL;
++
+       down(&misc_sem);
+-      misc->prev->next = misc->next;
+-      misc->next->prev = misc->prev;
+-      misc->next = NULL;
+-      misc->prev = NULL;
++      list_del(&misc->list);
+       devfs_remove(misc->devfs_name);
+       if (i < DYNAMIC_MINORS && i>0) {
+               misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
+@@ -244,9 +277,15 @@
+ EXPORT_SYMBOL(misc_register);
+ EXPORT_SYMBOL(misc_deregister);
+-int __init misc_init(void)
++static int __init misc_init(void)
+ {
+-      create_proc_read_entry("misc", 0, 0, misc_read_proc, NULL);
++#ifdef CONFIG_PROC_FS
++      struct proc_dir_entry *ent;
++
++      ent = create_proc_entry("misc", 0, NULL);
++      if (ent)
++              ent->proc_fops = &misc_proc_fops;
++#endif
+ #ifdef CONFIG_MVME16x
+       rtc_MK48T08_init();
+ #endif
+@@ -281,3 +320,4 @@
+       }
+       return 0;
+ }
++module_init(misc_init);
+Index: linux-2.6.0-test5/drivers/char/mwave/mwavedd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/mwave/mwavedd.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/mwave/mwavedd.c     2003-09-27 11:38:21.102320344 +0800
+@@ -293,8 +293,6 @@
+       
+               case IOCTL_MW_GET_IPC: {
+                       unsigned int ipcnum = (unsigned int) ioarg;
+-                      spinlock_t ipc_lock = SPIN_LOCK_UNLOCKED;
+-                      unsigned long flags;
+       
+                       PRINTK_3(TRACE_MWAVE,
+                               "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC"
+@@ -310,32 +308,29 @@
+                       }
+       
+                       if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
++                              DECLARE_WAITQUEUE(wait, current);
++
+                               PRINTK_2(TRACE_MWAVE,
+                                       "mwavedd::mwave_ioctl, thread for"
+                                       " ipc %x going to sleep\n",
+                                       ipcnum);
+-      
+-                              spin_lock_irqsave(&ipc_lock, flags);
++                              add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
++                              pDrvData->IPCs[ipcnum].bIsHere = TRUE;
++                              set_current_state(TASK_INTERRUPTIBLE);
+                               /* check whether an event was signalled by */
+                               /* the interrupt handler while we were gone */
+                               if (pDrvData->IPCs[ipcnum].usIntCount == 1) {   /* first int has occurred (race condition) */
+                                       pDrvData->IPCs[ipcnum].usIntCount = 2;  /* first int has been handled */
+-                                      spin_unlock_irqrestore(&ipc_lock, flags);
+                                       PRINTK_2(TRACE_MWAVE,
+                                               "mwavedd::mwave_ioctl"
+                                               " IOCTL_MW_GET_IPC ipcnum %x"
+                                               " handling first int\n",
+                                               ipcnum);
+                               } else {        /* either 1st int has not yet occurred, or we have already handled the first int */
+-                                      pDrvData->IPCs[ipcnum].bIsHere = TRUE;
+-#warning "Sleeping on spinlock"
+-                                      interruptible_sleep_on(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
+-                                      pDrvData->IPCs[ipcnum].bIsHere = FALSE;
++                                      schedule();
+                                       if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
+-                                              pDrvData->IPCs[ipcnum].
+-                                              usIntCount = 2;
++                                              pDrvData->IPCs[ipcnum].usIntCount = 2;
+                                       }
+-                                      spin_unlock_irqrestore(&ipc_lock, flags);
+                                       PRINTK_2(TRACE_MWAVE,
+                                               "mwavedd::mwave_ioctl"
+                                               " IOCTL_MW_GET_IPC ipcnum %x"
+@@ -343,6 +338,9 @@
+                                               " application\n",
+                                               ipcnum);
+                               }
++                              pDrvData->IPCs[ipcnum].bIsHere = FALSE;
++                              remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait);
++                              set_current_state(TASK_RUNNING);
+                               PRINTK_2(TRACE_MWAVE,
+                                       "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC,"
+                                       " returning thread for ipc %x"
+Index: linux-2.6.0-test5/drivers/char/n_r3964.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/n_r3964.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/n_r3964.c   2003-09-27 11:38:21.112318824 +0800
+@@ -150,22 +150,18 @@
+ static int  r3964_receive_room(struct tty_struct *tty);
+ static struct tty_ldisc tty_ldisc_N_R3964 = {
+-        TTY_LDISC_MAGIC,       /* magic */
+-      "R3964",               /* name */
+-        0,                     /* num */
+-        0,                     /* flags */
+-        r3964_open,            /* open */
+-        r3964_close,           /* close */
+-        0,                     /* flush_buffer */
+-        0,                     /* chars_in_buffer */
+-        r3964_read,            /* read */
+-        r3964_write,           /* write */
+-        r3964_ioctl,           /* ioctl */
+-        r3964_set_termios,     /* set_termios */
+-        r3964_poll,            /* poll */            
+-        r3964_receive_buf,     /* receive_buf */
+-        r3964_receive_room,    /* receive_room */
+-        0                      /* write_wakeup */
++      .owner   = THIS_MODULE,
++      .magic  = TTY_LDISC_MAGIC, 
++      .name   = "R3964",
++      .open   = r3964_open,
++      .close  = r3964_close,
++      .read   = r3964_read,
++      .write  = r3964_write,
++      .ioctl  = r3964_ioctl,
++      .set_termios = r3964_set_termios,
++      .poll   = r3964_poll,            
++      .receive_buf = r3964_receive_buf,
++      .receive_room = r3964_receive_room,
+ };
+@@ -1070,8 +1066,6 @@
+ {
+    struct r3964_info *pInfo;
+    
+-   MOD_INC_USE_COUNT;
+-
+    TRACE_L("open");
+    TRACE_L("tty=%x, PID=%d, disc_data=%x", 
+           (int)tty, current->pid, (int)tty->disc_data);
+@@ -1188,8 +1182,6 @@
+     TRACE_M("r3964_close - tx_buf kfree %x",(int)pInfo->tx_buf);
+     kfree(pInfo);
+     TRACE_M("r3964_close - info kfree %x",(int)pInfo);
+-
+-    MOD_DEC_USE_COUNT;
+ }
+ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+Index: linux-2.6.0-test5/drivers/char/n_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/n_tty.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/n_tty.c     2003-09-27 11:38:21.120317608 +0800
+@@ -977,11 +977,11 @@
+       if (file->f_op->write != redirected_tty_write && current->tty == tty) {
+               if (tty->pgrp <= 0)
+                       printk("read_chan: tty->pgrp <= 0!\n");
+-              else if (current->pgrp != tty->pgrp) {
++              else if (process_group(current) != tty->pgrp) {
+                       if (is_ignored(SIGTTIN) ||
+-                          is_orphaned_pgrp(current->pgrp))
++                          is_orphaned_pgrp(process_group(current)))
+                               return -EIO;
+-                      kill_pg(current->pgrp, SIGTTIN, 1);
++                      kill_pg(process_group(current), SIGTTIN, 1);
+                       return -ERESTARTSYS;
+               }
+       }
+Index: linux-2.6.0-test5/drivers/char/pcmcia/synclink_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/pcmcia/synclink_cs.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/pcmcia/synclink_cs.c        2003-09-27 11:38:21.149313200 +0800
+@@ -725,14 +725,6 @@
+     if (debug_level >= DEBUG_LEVEL_INFO)
+           printk("mgslpc_release(0x%p)\n", link);
+-    if (link->open) {
+-          if (debug_level >= DEBUG_LEVEL_INFO)
+-                  printk("synclink_cs: release postponed, '%s' still open\n",
+-                         link->dev->dev_name);
+-          link->state |= DEV_STALE_CONFIG;
+-          return;
+-    }
+-
+     /* Unlink the device chain */
+     link->dev = NULL;
+     link->state &= ~DEV_CONFIG;
+Index: linux-2.6.0-test5/drivers/char/pcxx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/pcxx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/pcxx.c      2003-09-27 11:38:21.164310920 +0800
+@@ -12,11 +12,12 @@
+  *  This driver does NOT support DigiBoard's fastcook FEP option and
+  *  does not support the transparent print (i.e. digiprint) option.
+  *
+- * This Driver is currently maintained by Christoph Lameter (christoph@lameter.com)
+  *
+- * Please contact digi for support issues at digilnux@dgii.com.
+- * Some more information can be found at
+- * http://lameter.com/digi.
++ *    NOTE:   As of the 2.6 Linux kernel, Digi International
++ *            no longer supports this version of the driver.
++ *            If you have a PCI EPCA DigiBoard, please use the DGAP
++ *            driver instead.
++ *
+  *
+  *  1.5.2 Fall 1995 Bug fixes by David Nugent
+  *  1.5.3 March 9, 1996 Christoph Lameter: Fixed 115.2K Support. Memory
+Index: linux-2.6.0-test5/drivers/char/random.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/random.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/random.c    2003-09-27 11:38:21.184307880 +0800
+@@ -253,6 +253,7 @@
+ #include <linux/genhd.h>
+ #include <linux/interrupt.h>
+ #include <linux/spinlock.h>
++#include <linux/percpu.h>
+ #include <asm/processor.h>
+ #include <asm/uaccess.h>
+@@ -281,6 +282,15 @@
+ static int random_write_wakeup_thresh = 128;
+ /*
++ * When the input pool goes over trickle_thresh, start dropping most
++ * samples to avoid wasting CPU time and reduce lock contention.
++ */
++
++static int trickle_thresh = DEFAULT_POOL_SIZE * 7;
++
++static DEFINE_PER_CPU(int, trickle_count) = 0;
++
++/*
+  * A pool of size .poolwords is stirred with a primitive polynomial
+  * of degree .poolwords over GF(2).  The taps for various sizes are
+  * defined below.  They are chosen to be evenly spaced (minimum RMS
+@@ -778,6 +788,11 @@
+       __s32           delta, delta2, delta3;
+       int             entropy = 0;
++      /* if over the trickle threshold, use only 1 in 4096 samples */
++      if ( random_state->entropy_count > trickle_thresh &&
++           (__get_cpu_var(trickle_count)++ & 0xfff))
++              return;
++
+ #if defined (__i386__) || defined (__x86_64__)
+       if (cpu_has_tsc) {
+               __u32 high;
+@@ -1478,16 +1493,16 @@
+       }
+ }
+-void __init rand_initialize(void)
++static int __init rand_initialize(void)
+ {
+       int i;
+       if (create_entropy_store(DEFAULT_POOL_SIZE, &random_state))
+-              return;         /* Error, return */
++              goto err;
+       if (batch_entropy_init(BATCH_ENTROPY_SIZE, random_state))
+-              return;         /* Error, return */
++              goto err;
+       if (create_entropy_store(SECONDARY_POOL_SIZE, &sec_random_state))
+-              return;         /* Error, return */
++              goto err;
+       clear_entropy_store(random_state);
+       clear_entropy_store(sec_random_state);
+       init_std_data(random_state);
+@@ -1500,7 +1515,11 @@
+       memset(&mouse_timer_state, 0, sizeof(struct timer_rand_state));
+       memset(&extract_timer_state, 0, sizeof(struct timer_rand_state));
+       extract_timer_state.dont_count_entropy = 1;
++      return 0;
++err:
++      return -1;
+ }
++module_init(rand_initialize);
+ void rand_initialize_irq(int irq)
+ {
+Index: linux-2.6.0-test5/drivers/char/rio/rio_linux.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/rio/rio_linux.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/rio/rio_linux.c     2003-09-27 11:38:21.194306360 +0800
+@@ -234,14 +234,12 @@
+    support up to 64 bits on 64bit architectures. -- REW 20/06/99 */
+ long rio_irqmask = -1;
+-#ifndef TWO_ZERO
+ MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
+ MODULE_DESCRIPTION("RIO driver");
+ MODULE_LICENSE("GPL");
+ MODULE_PARM(rio_poll, "i");
+ MODULE_PARM(rio_debug, "i");
+ MODULE_PARM(rio_irqmask, "i");
+-#endif
+ static struct real_driver rio_real_driver = {
+   rio_disable_tx_interrupts,
+@@ -1034,13 +1032,6 @@
+   func_exit();
+ }
+-#ifdef TWO_ZERO
+-#define PDEV unsigned char pci_bus, unsigned pci_fun
+-#define pdev pci_bus, pci_fun
+-#else
+-#define PDEV   struct pci_dev *pdev
+-#endif
+-
+ #ifdef CONFIG_PCI
+  /* This was written for SX, but applies to RIO too...
+@@ -1062,7 +1053,7 @@
+    EEprom.  As the bit is read/write for the CPU, we can fix it here,
+    if we detect that it isn't set correctly. -- REW */
+-void fix_rio_pci (PDEV)
++void fix_rio_pci (struct pci_dev *pdev)
+ {
+   unsigned int hwbase;
+   unsigned long rebase;
+@@ -1095,12 +1086,7 @@
+   int okboard;
+ #ifdef CONFIG_PCI
+-#ifndef TWO_ZERO
+   struct pci_dev *pdev = NULL;
+-#else
+-  unsigned char pci_bus, pci_fun;
+-  /* in 2.2.x pdev is a pointer defining a PCI device. In 2.0 its the bus/fn */
+-#endif
+   unsigned int tint;
+   unsigned short tshort;
+ #endif
+@@ -1128,17 +1114,11 @@
+ #ifdef CONFIG_PCI
+     /* First look for the JET devices: */
+-#ifndef TWO_ZERO
+     while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+                                     PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
+                                     pdev))) {
+        if (pci_enable_device(pdev)) continue;
+-#else
+-    for (i=0;i< RIO_NBOARDS;i++) {
+-      if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
+-                             PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, i,
+-                             &pci_bus, &pci_fun)) break;
+-#endif
++
+       /* Specialix has a whole bunch of cards with
+          0x2000 as the device ID. They say its because
+          the standard requires it. Stupid standard. */
+@@ -1196,16 +1176,9 @@
+       } else {
+               iounmap((char*) (p->RIOHosts[p->RIONumHosts].Caddr));
+       }
+-      
+-#ifdef TWO_ZERO
+-    }  /* We have two variants with the opening brace, so to prevent */
+-#else
+-    }  /* Emacs from getting confused we have two closing braces too. */
+-#endif
++    }
+     
+     /* Then look for the older PCI card.... : */
+-#ifndef TWO_ZERO
+-
+   /* These older PCI cards have problems (only byte-mode access is
+      supported), which makes them a bit awkward to support. 
+@@ -1219,12 +1192,6 @@
+                                     PCI_DEVICE_ID_SPECIALIX_RIO, 
+                                     pdev))) {
+        if (pci_enable_device(pdev)) continue;
+-#else
+-    for (i=0;i< RIO_NBOARDS;i++) {
+-      if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
+-                             PCI_DEVICE_ID_SPECIALIX_RIO, i,
+-                             &pci_bus, &pci_fun)) break;
+-#endif
+ #ifdef CONFIG_RIO_OLDPCI
+       pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &tint);
+@@ -1272,11 +1239,7 @@
+       printk (KERN_ERR "Found an older RIO PCI card, but the driver is not "
+               "compiled to support it.\n");
+ #endif
+-#ifdef TWO_ZERO
+-    }  /* We have two variants with the opening brace, so to prevent */
+-#else
+-    }  /* Emacs from getting confused we have two closing braces too. */
+-#endif
++    }
+ #endif /* PCI */
+   /* Now probe for ISA cards... */
+Index: linux-2.6.0-test5/drivers/char/rocket.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/rocket.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/rocket.c    2003-09-27 11:38:21.219302560 +0800
+@@ -956,7 +956,7 @@
+        * Info->count is now 1; so it's safe to sleep now.
+        */
+       info->session = current->session;
+-      info->pgrp = current->pgrp;
++      info->pgrp = process_group(current);
+       if ((info->flags & ROCKET_INITIALIZED) == 0) {
+               cp = &info->channel;
+Index: linux-2.6.0-test5/drivers/char/specialix.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/specialix.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/specialix.c 2003-09-27 11:38:21.236299976 +0800
+@@ -92,40 +92,7 @@
+ #include <linux/delay.h>
+ #include <linux/version.h>
+ #include <linux/pci.h>
+-
+-
+-/* ************************************************************** */
+-/* * This section can be removed when 2.0 becomes outdated....  * */
+-/* ************************************************************** */
+-
+-#if LINUX_VERSION_CODE < 131328    /* Less than 2.1.0 */
+-#define TWO_ZERO
+-#else
+-#if LINUX_VERSION_CODE < 131371   /* less than 2.1.43 */
+-/* This has not been extensively tested yet. Sorry. */
+-#warning "You're on your own between 2.1.0 and 2.1.43.... "
+-#warning "Please use a recent kernel."
+-#endif
+-#endif
+-
+-
+-#ifdef TWO_ZERO
+-#define Get_user(a,b)         a = get_user(b)
+-#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+-#define copy_to_user(a,b,c)   memcpy_tofs(a,b,c)
+-#define queue_task            queue_task_irq_off
+-#else
+-#define Get_user(a,b)         get_user(a,b)
+-#endif
+-
+-/* ************************************************************** */
+-/* *                End of compatibility section..              * */
+-/* ************************************************************** */
+-
+-
+-#ifndef TWO_ZERO
+ #include <asm/uaccess.h>
+-#endif
+ #include "specialix_io8.h"
+ #include "cd1865.h"
+@@ -1733,7 +1700,7 @@
+       if (error) 
+               return error;
+-      Get_user(arg, (unsigned long *) value);
++      get_user(arg, (unsigned long *) value);
+       switch (cmd) {
+       case TIOCMBIS: 
+          /*   if (arg & TIOCM_RTS) 
+@@ -1925,7 +1892,7 @@
+                        (unsigned long *) arg);
+               return 0;
+        case TIOCSSOFTCAR:
+-              Get_user(arg, (unsigned long *) arg);
++              get_user(arg, (unsigned long *) arg);
+               tty->termios->c_cflag =
+                       ((tty->termios->c_cflag & ~CLOCAL) |
+                       (arg ? CLOCAL : 0));
+Index: linux-2.6.0-test5/drivers/char/sx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/sx.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/sx.c        2003-09-27 11:38:21.255297088 +0800
+@@ -2356,14 +2356,6 @@
+       func_exit();
+ }
+-#ifdef TWO_ZERO
+-#define PDEV unsigned char pci_bus, unsigned pci_fun
+-#define pdev pci_bus, pci_fun
+-#else
+-#define PDEV   struct pci_dev *pdev
+-#endif
+-
+-
+ #ifdef CONFIG_PCI
+  /******************************************************** 
+  * Setting bit 17 in the CNTRL register of the PLX 9050  * 
+@@ -2376,7 +2368,7 @@
+    EEprom.  As the bit is read/write for the CPU, we can fix it here,
+    if we detect that it isn't set correctly. -- REW */
+-static void fix_sx_pci (PDEV, struct sx_board *board)
++static void fix_sx_pci (struct pci_dev *pdev, struct sx_board *board)
+ {
+       unsigned int hwbase;
+       unsigned long rebase;
+@@ -2406,12 +2398,7 @@
+       struct sx_board *board;
+ #ifdef CONFIG_PCI
+-#ifndef TWO_ZERO
+       struct pci_dev *pdev = NULL;
+-#else
+-      unsigned char pci_bus, pci_fun;
+-      /* in 2.2.x pdev is a pointer defining a PCI device. In 2.0 its the bus/fn */
+-#endif
+       unsigned int tint;
+       unsigned short tshort;
+ #endif
+@@ -2431,19 +2418,12 @@
+       }
+ #ifdef CONFIG_PCI
+-#ifndef TWO_ZERO
+       while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+                                       PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
+                                             pdev))) {
+               if (pci_enable_device(pdev))
+                       continue;
+-#else
+-      for (i=0;i< SX_NBOARDS;i++) {
+-              if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
+-                                       PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, i,
+-                                             &pci_bus, &pci_fun))
+-                      break;
+-#endif
++
+               /* Specialix has a whole bunch of cards with
+                  0x2000 as the device ID. They say its because
+                  the standard requires it. Stupid standard. */
+Index: linux-2.6.0-test5/drivers/char/sysrq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/sysrq.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/sysrq.c     2003-09-27 11:38:21.259296480 +0800
+@@ -35,9 +35,27 @@
+ #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);
+-extern struct list_head super_blocks;
+ /* Whether we react on sysrq keys or just ignore them */
+ int sysrq_enabled = 1;
+@@ -239,8 +257,8 @@
+ /* 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,
+Index: linux-2.6.0-test5/drivers/char/tty_io.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/tty_io.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/tty_io.c    2003-09-27 11:38:21.276293896 +0800
+@@ -325,13 +325,13 @@
+               printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
+               return 0;
+       }
+-      if (current->pgrp == tty->pgrp)
++      if (process_group(current) == tty->pgrp)
+               return 0;
+       if (is_ignored(SIGTTOU))
+               return 0;
+-      if (is_orphaned_pgrp(current->pgrp))
++      if (is_orphaned_pgrp(process_group(current)))
+               return -EIO;
+-      (void) kill_pg(current->pgrp,SIGTTOU,1);
++      (void) kill_pg(process_group(current), SIGTTOU, 1);
+       return -ERESTARTSYS;
+ }
+@@ -826,7 +826,6 @@
+       if(!tty)
+               goto fail_no_mem;
+       initialize_tty_struct(tty);
+-      tty->device = MKDEV(driver->major, driver->minor_start) + idx;
+       tty->driver = driver;
+       tty->index = idx;
+       tty_line_name(driver, idx, tty->name);
+@@ -854,8 +853,6 @@
+               if (!o_tty)
+                       goto free_mem_out;
+               initialize_tty_struct(o_tty);
+-              o_tty->device = MKDEV(driver->other->major,
+-                                      driver->other->minor_start) + idx;
+               o_tty->driver = driver->other;
+               o_tty->index = idx;
+               tty_line_name(driver->other, idx, o_tty->name);
+@@ -1406,7 +1403,7 @@
+               task_unlock(current);
+               current->tty_old_pgrp = 0;
+               tty->session = current->session;
+-              tty->pgrp = current->pgrp;
++              tty->pgrp = process_group(current);
+       }
+       return 0;
+ }
+@@ -1580,7 +1577,7 @@
+       task_unlock(current);
+       current->tty_old_pgrp = 0;
+       tty->session = current->session;
+-      tty->pgrp = current->pgrp;
++      tty->pgrp = process_group(current);
+       return 0;
+ }
+@@ -2423,7 +2420,7 @@
+  * Ok, now we can initialize the rest of the tty devices and can count
+  * on memory allocations, interrupts etc..
+  */
+-void __init tty_init(void)
++static int __init tty_init(void)
+ {
+       strcpy(tty_cdev.kobj.name, "dev.tty");
+       cdev_init(&tty_cdev, &tty_fops);
+@@ -2512,4 +2509,6 @@
+ #ifdef CONFIG_A2232
+       a2232board_init();
+ #endif
++      return 0;
+ }
++module_init(tty_init);
+Index: linux-2.6.0-test5/drivers/char/watchdog/alim1535_wdt.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/alim1535_wdt.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/alim1535_wdt.c     2003-09-27 11:38:21.279293440 +0800
+@@ -317,7 +317,7 @@
+  *    want to register another driver on the same PCI id.
+  */
+-static struct pci_device_id ali_pci_tbl[] __initdata = {
++static struct pci_device_id ali_pci_tbl[] = {
+       { PCI_VENDOR_ID_AL, 1535, PCI_ANY_ID, PCI_ANY_ID,},
+       { 0, },
+ };
+Index: linux-2.6.0-test5/drivers/char/watchdog/amd7xx_tco.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/amd7xx_tco.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/amd7xx_tco.c       2003-09-27 11:38:21.283292832 +0800
+@@ -294,7 +294,7 @@
+       .fops   = &amdtco_fops
+ };
+-static struct pci_device_id amdtco_pci_tbl[] __initdata = {
++static struct pci_device_id amdtco_pci_tbl[] = {
+       /* AMD 766 PCI_IDs here */
+       { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443, PCI_ANY_ID, PCI_ANY_ID, },
+       { 0, }
+Index: linux-2.6.0-test5/drivers/char/watchdog/i810-tco.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/i810-tco.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/i810-tco.c 2003-09-27 11:38:21.286292376 +0800
+@@ -301,7 +301,7 @@
+  * register a pci_driver, because someone else might one day
+  * want to register another driver on the same PCI id.
+  */
+-static struct pci_device_id i810tco_pci_tbl[] __initdata = {
++static struct pci_device_id i810tco_pci_tbl[] = {
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0,   PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0,   PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,   PCI_ANY_ID, PCI_ANY_ID, },
+Index: linux-2.6.0-test5/drivers/char/watchdog/wdt_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/char/watchdog/wdt_pci.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/char/watchdog/wdt_pci.c  2003-09-27 11:38:21.290291768 +0800
+@@ -505,7 +505,7 @@
+ };
+-static int __init wdtpci_init_one (struct pci_dev *dev,
++static int __devinit wdtpci_init_one (struct pci_dev *dev,
+                                  const struct pci_device_id *ent)
+ {
+       static int dev_count = 0;
+Index: linux-2.6.0-test5/drivers/cpufreq/cpufreq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cpufreq/cpufreq.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cpufreq/cpufreq.c        2003-09-27 11:38:21.298290552 +0800
+@@ -1,17 +1,16 @@
+ /*
+- *  linux/kernel/cpufreq.c
++ *  linux/drivers/cpufreq/cpufreq.c
+  *
+  *  Copyright (C) 2001 Russell King
+  *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+  *
+- *  $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+- *
+  * 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/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -743,26 +742,9 @@
+ EXPORT_SYMBOL(cpufreq_get_policy);
+-/**
+- *    cpufreq_set_policy - set a new CPUFreq policy
+- *    @policy: policy to be set.
+- *
+- *    Sets a new CPU frequency and voltage scaling policy.
+- */
+-int cpufreq_set_policy(struct cpufreq_policy *policy)
++static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy)
+ {
+       int ret = 0;
+-      struct cpufreq_policy *data;
+-
+-      if (!policy)
+-              return -EINVAL;
+-
+-      data = cpufreq_cpu_get(policy->cpu);
+-      if (!data)
+-              return -EINVAL;
+-
+-      /* lock this CPU */
+-      down(&data->lock);
+       memcpy(&policy->cpuinfo, 
+              &data->cpuinfo, 
+@@ -829,6 +811,36 @@
+       }
+  error_out:
++      return ret;
++}
++
++/**
++ *    cpufreq_set_policy - set a new CPUFreq policy
++ *    @policy: policy to be set.
++ *
++ *    Sets a new CPU frequency and voltage scaling policy.
++ */
++int cpufreq_set_policy(struct cpufreq_policy *policy)
++{
++      int ret = 0;
++      struct cpufreq_policy *data;
++
++      if (!policy)
++              return -EINVAL;
++
++      data = cpufreq_cpu_get(policy->cpu);
++      if (!data)
++              return -EINVAL;
++
++      /* lock this CPU */
++      down(&data->lock);
++
++      ret = __cpufreq_set_policy(data, policy);
++      data->user_policy.min = data->min;
++      data->user_policy.max = data->max;
++      data->user_policy.policy = data->policy;
++      data->user_policy.governor = data->governor;
++
+       up(&data->lock);
+       cpufreq_cpu_put(data);
+@@ -837,6 +849,41 @@
+ EXPORT_SYMBOL(cpufreq_set_policy);
++/**
++ *    cpufreq_update_policy - re-evaluate an existing cpufreq policy
++ *    @cpu: CPU which shall be re-evaluated
++ *
++ *    Usefull for policy notifiers which have different necessities
++ *    at different times.
++ */
++int cpufreq_update_policy(unsigned int cpu)
++{
++      struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
++      struct cpufreq_policy policy;
++      int ret = 0;
++
++      if (!data)
++              return -ENODEV;
++
++      down(&data->lock);
++
++      memcpy(&policy, 
++             &data, 
++             sizeof(struct cpufreq_policy));
++      policy.min = data->user_policy.min;
++      policy.max = data->user_policy.max;
++      policy.policy = data->user_policy.policy;
++      policy.governor = data->user_policy.governor;
++
++      ret = __cpufreq_set_policy(data, &policy);
++
++      up(&data->lock);
++
++      cpufreq_cpu_put(data);
++      return ret;
++}
++EXPORT_SYMBOL(cpufreq_update_policy);
++
+ /*********************************************************************
+  *            EXTERNALLY AFFECTING FREQUENCY CHANGES                 *
+Index: linux-2.6.0-test5/drivers/cpufreq/cpufreq_userspace.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/cpufreq/cpufreq_userspace.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/cpufreq/cpufreq_userspace.c      2003-09-27 11:38:21.302289944 +0800
+@@ -1,17 +1,16 @@
+ /*
+- *  drivers/cpufreq/userspace.c
++ *  linux/drivers/cpufreq/cpufreq_userspace.c
+  *
+  *  Copyright (C)  2001 Russell King
+  *            (C)  2002 - 2003 Dominik Brodowski <linux@brodo.de>
+  *
+- * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+- *
+  * 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/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/smp.h>
+Index: linux-2.6.0-test5/drivers/eisa/eisa-bus.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/eisa/eisa-bus.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/eisa/eisa-bus.c  2003-09-27 11:38:21.306289336 +0800
+@@ -427,6 +427,11 @@
+ postcore_initcall (eisa_init);
++#ifndef CONFIG_EISA_ALWAYS
++int EISA_bus;
++EXPORT_SYMBOL(EISA_bus);
++#endif
++
+ EXPORT_SYMBOL (eisa_bus_type);
+ EXPORT_SYMBOL (eisa_driver_register);
+ EXPORT_SYMBOL (eisa_driver_unregister);
+Index: linux-2.6.0-test5/drivers/ide/ide.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide.c        2003-09-27 11:38:21.325286448 +0800
+@@ -1800,27 +1800,26 @@
+ #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 @@
+ #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 @@
+       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;
+Index: linux-2.6.0-test5/drivers/ide/ide-cd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-cd.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-cd.c     2003-09-27 11:38:21.351282496 +0800
+@@ -2365,7 +2365,7 @@
+       /* Now try to get the total cdrom capacity. */
+       stat = cdrom_get_last_written(cdi, (long *) &toc->capacity);
+-      if (stat)
++      if (stat || !toc->capacity)
+               stat = cdrom_read_capacity(drive, &toc->capacity, sense);
+       if (stat)
+               toc->capacity = 0x1fffff;
+Index: linux-2.6.0-test5/drivers/ide/ide-default.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-default.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-default.c        2003-09-27 11:38:21.353282192 +0800
+@@ -57,6 +57,14 @@
+                       "driver with ide.c\n", drive->name);
+               return 1;
+       }
++      
++      /* For the sake of the request layer, we must make sure we have a
++       * correct ready_stat value, that is 0 for ATAPI devices or we will
++       * fail any request like Power Management
++       */
++      if (drive->media != ide_disk)
++              drive->ready_stat = 0;
++
+       return 0;
+ }
+Index: linux-2.6.0-test5/drivers/ide/ide-floppy.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-floppy.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-floppy.c 2003-09-27 11:38:21.370279608 +0800
+@@ -156,7 +156,6 @@
+       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 @@
+       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,28 +571,31 @@
+ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
+ {
+       struct request *rq = pc->rq;
++      struct bio_vec *bvec;
+       struct bio *bio = rq->bio;
+-      int count;
++      unsigned long flags;
++      char *data;
++      int count, i;
++
++      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);
++                      bcount -= count;
++                      pc->b_count += 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;
++                      idefloppy_do_end_request(drive, 1, count >> 9);
++              }
++      }
++
++      if (bcount) {
++              printk(KERN_ERR "%s: bio == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);
++              idefloppy_discard_data(drive, bcount);
+       }
+ }
+@@ -604,30 +603,30 @@
+ {
+       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_vec *bvec;
++      unsigned long flags;
++      int count, i;
++      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);
++                      bcount -= count;
++                      pc->b_count += count;
++                      bvec_kunmap_irq(data, &flags);
++
++                      idefloppy_do_end_request(drive, 1, count >> 9);
+               }
+-              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;
++      }
++
++      if (bio == NULL) {
++              printk(KERN_ERR "%s: bio == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
++              idefloppy_write_zeros(drive, bcount);
+       }
+ }
+@@ -732,7 +731,6 @@
+       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 +1197,6 @@
+       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);
+Index: linux-2.6.0-test5/drivers/ide/ide-io.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-io.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-io.c     2003-09-27 11:38:21.381277936 +0800
+@@ -928,13 +928,10 @@
+                * 
+                * We let requests forced at head of queue with ide-preempt
+                * though. I hope that doesn't happen too much, hopefully not
+-               * unless the subdriver triggers such a thing in it's own PM
++               * unless the subdriver triggers such a thing in its own PM
+                * state machine.
+                */
+               if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) {
+-#ifdef DEBUG_PM
+-                      printk("%s: a request made it's way while we are power managing...\n", drive->name);
+-#endif
+                       /* We clear busy, there should be no pending ATA command at this point. */
+                       hwgroup->busy = 0;
+                       break;
+@@ -1417,8 +1414,9 @@
+       }
+       spin_lock_irqsave(&ide_lock, flags);
+-      if (action == ide_preempt || action == ide_head_wait) {
++      if (action == ide_preempt)
+               hwgroup->rq = NULL;
++      if (action == ide_preempt || action == ide_head_wait) {
+               where = ELEVATOR_INSERT_FRONT;
+               rq->flags |= REQ_PREEMPT;
+       }
+Index: linux-2.6.0-test5/drivers/ide/ide-tcq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/ide-tcq.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/ide-tcq.c    2003-09-27 11:38:21.386277176 +0800
+@@ -596,7 +596,7 @@
+        * enable block tagging
+        */
+       if (!blk_queue_tagged(drive->queue))
+-              blk_queue_init_tags(drive->queue, IDE_MAX_TAG);
++              blk_queue_init_tags(drive->queue, IDE_MAX_TAG, NULL);
+       /*
+        * check auto-poll support
+Index: linux-2.6.0-test5/drivers/ide/legacy/ali14xx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/ali14xx.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/ali14xx.c     2003-09-27 11:38:21.389276720 +0800
+@@ -198,22 +198,12 @@
+       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 @@
+               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");
+Index: linux-2.6.0-test5/drivers/ide/legacy/dtc2278.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/dtc2278.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/dtc2278.c     2003-09-27 11:38:21.392276264 +0800
+@@ -95,9 +95,16 @@
+       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 @@
+ #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
+-
+Index: linux-2.6.0-test5/drivers/ide/legacy/ht6560b.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/ht6560b.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/ht6560b.c     2003-09-27 11:38:21.395275808 +0800
+@@ -304,35 +304,16 @@
+ #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 @@
+               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 @@
+       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");
+Index: linux-2.6.0-test5/drivers/ide/legacy/pdc4030.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/pdc4030.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/pdc4030.c     2003-09-27 11:38:21.403274592 +0800
+@@ -147,8 +147,6 @@
+       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,28 @@
+       }
+ }
+-
+-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);
++                      if (!setup_pdc4030(hwif))
++                              return -ENODEV;
++                      return 0;
+ #endif
+               }
+       }
+-#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 +326,24 @@
+       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
+  */
+Index: linux-2.6.0-test5/drivers/ide/legacy/qd65xx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/qd65xx.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/qd65xx.c      2003-09-27 11:38:21.407273984 +0800
+@@ -338,12 +338,12 @@
+  * 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 @@
+       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 @@
+                       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 @@
+  * 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 @@
+               /* 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 @@
+                       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 @@
+               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 @@
+       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");
+Index: linux-2.6.0-test5/drivers/ide/legacy/umc8672.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ide/legacy/umc8672.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ide/legacy/umc8672.c     2003-09-27 11:38:21.410273528 +0800
+@@ -124,16 +124,16 @@
+       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 @@
+       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");
+Index: linux-2.6.0-test5/drivers/ieee1394/nodemgr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/ieee1394/nodemgr.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/ieee1394/nodemgr.c       2003-09-27 11:38:21.424271400 +0800
+@@ -1744,8 +1744,7 @@
+       sprintf(hi->daemon_name, "knodemgrd_%d", host->id);
+-      hi->pid = kernel_thread(nodemgr_host_thread, hi,
+-                              CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      hi->pid = kernel_thread(nodemgr_host_thread, hi, CLONE_KERNEL);
+       if (hi->pid < 0) {
+               HPSB_ERR ("NodeMgr: failed to start %s thread for %s",
+Index: linux-2.6.0-test5/drivers/input/evdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/evdev.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/evdev.c    2003-09-27 11:38:21.428270792 +0800
+@@ -208,7 +208,7 @@
+       struct evdev *evdev = list->evdev;
+       struct input_dev *dev = evdev->handle.dev;
+       struct input_absinfo abs;
+-      int i, t, u;
++      int i, t, u, v;
+       if (!evdev->exist) return -ENODEV;
+@@ -239,14 +239,12 @@
+               case EVIOCSKEYCODE:
+                       if (get_user(t, ((int *) arg) + 0)) return -EFAULT;
+                       if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
++                      if (get_user(v, ((int *) arg) + 1)) return -EFAULT;
+                       u = INPUT_KEYCODE(dev, t);
+-                      if (get_user(INPUT_KEYCODE(dev, t), ((int *) arg) + 1)) return -EFAULT;
+-
+-                      for (i = 0; i < dev->keycodemax; i++)
+-                              if(INPUT_KEYCODE(dev, t) == u) break;
++                      INPUT_KEYCODE(dev, t) = v;
++                      for (i = 0; i < dev->keycodemax; i++) if (v == u) break;
+                       if (i == dev->keycodemax) clear_bit(u, dev->keybit);
+-                      set_bit(INPUT_KEYCODE(dev, t), dev->keybit);
+-
++                      set_bit(v, dev->keybit);
+                       return 0;
+               case EVIOCSFF:
+Index: linux-2.6.0-test5/drivers/input/input.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/input.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/input.c    2003-09-27 11:38:21.434269880 +0800
+@@ -426,8 +426,10 @@
+       init_timer(&dev->timer);
+       dev->timer.data = (long) dev;
+       dev->timer.function = input_repeat_key;
+-      dev->rep[REP_DELAY] = HZ/4;
+-      dev->rep[REP_PERIOD] = HZ/33;
++      if (!dev->rep[REP_DELAY])
++              dev->rep[REP_DELAY] = HZ/4;
++      if (!dev->rep[REP_PERIOD])
++              dev->rep[REP_PERIOD] = HZ/33;
+       INIT_LIST_HEAD(&dev->h_list);
+       list_add_tail(&dev->node, &input_dev_list);
+@@ -676,20 +678,10 @@
+       return (count > cnt) ? cnt : count;
+ }
+-#endif
+-
+-struct class input_class = {
+-      .name           = "input",
+-};
+-
+-static int __init input_init(void)
++static int __init input_proc_init(void)
+ {
+       struct proc_dir_entry *entry;
+-      int retval = -ENOMEM;
+-
+-      class_register(&input_class);
+-#ifdef CONFIG_PROC_FS
+       proc_bus_input_dir = proc_mkdir("input", proc_bus);
+       if (proc_bus_input_dir == NULL)
+               return -ENOMEM;
+@@ -708,7 +700,22 @@
+               return -ENOMEM;
+       }
+       entry->owner = THIS_MODULE;
++      return 0;
++}
++#else /* !CONFIG_PROC_FS */
++static inline int input_proc_init(void) { return 0; }
+ #endif
++
++struct class input_class = {
++      .name           = "input",
++};
++
++static int __init input_init(void)
++{
++      int retval = -ENOMEM;
++
++      class_register(&input_class);
++      input_proc_init();
+       retval = register_chrdev(INPUT_MAJOR, "input", &input_fops);
+       if (retval) {
+               printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
+@@ -730,11 +737,10 @@
+ static void __exit input_exit(void)
+ {
+-#ifdef CONFIG_PROC_FS
+       remove_proc_entry("devices", proc_bus_input_dir);
+       remove_proc_entry("handlers", proc_bus_input_dir);
+       remove_proc_entry("input", proc_bus);
+-#endif
++
+       devfs_remove("input");
+       unregister_chrdev(INPUT_MAJOR, "input");
+       class_unregister(&input_class);
+Index: linux-2.6.0-test5/drivers/input/joydev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joydev.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joydev.c   2003-09-27 11:38:21.438269272 +0800
+@@ -466,13 +466,43 @@
+ static struct input_device_id joydev_ids[] = {
+       {
+-              .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
++              .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++                       INPUT_DEVICE_ID_MATCH_BUS,
++              .evbit = { BIT(EV_ABS) },
++              .absbit = { BIT(ABS_X) },
++              .id = { .bustype = BUS_GAMEPORT },
++      }, /* anything connected to a gameport is a fair game */
++      {
++              .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++                       INPUT_DEVICE_ID_MATCH_BUS,
++              .evbit = { BIT(EV_ABS) },
++              .absbit = { BIT(ABS_X) },
++              .id = { .bustype = BUS_AMIGA },
++      }, /* amiga joystick does not report any special buttons but luckily it is
++            the only device rporting absolute coordinates on Amiga bus */
++      {
++              .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++                       INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT(EV_ABS) },
+               .absbit = { BIT(ABS_X) },
++              .keybit = { BIT(BTN_TRIGGER) },
++      }, /* most joysticks have either BTN_TRIGGER or BTN_A or both */
++      {
++              .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT |
++                       INPUT_DEVICE_ID_MATCH_KEYBIT,
++              .evbit = { BIT(EV_ABS) },
++              .absbit = { BIT(ABS_X) },
++              .keybit = { BIT(BTN_A) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+               .evbit = { BIT(EV_ABS) },
++              .absbit = { BIT(ABS_RX), BIT(ABS_RY) },
++      }, /* magellan and some others report only MISC buttons but we can identify
++            them by using special axis auch as RX/RY, ABS_WHEEL or ABS_THROTTLE */
++      {
++              .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
++              .evbit = { BIT(EV_ABS) },
+               .absbit = { BIT(ABS_WHEEL) },
+       },
+       {
+Index: linux-2.6.0-test5/drivers/input/joystick/db9.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/db9.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/db9.c     2003-09-27 11:38:21.443268512 +0800
+@@ -55,7 +55,9 @@
+ #define DB9_MULTI_0802                0x08
+ #define DB9_MULTI_0802_2      0x09
+ #define DB9_CD32_PAD          0x0A
+-#define DB9_MAX_PAD           0x0B
++#define DB9_SATURN_DPP                0x0B
++#define DB9_SATURN_DPP_2      0x0C
++#define DB9_MAX_PAD           0x0D
+ #define DB9_UP                        0x01
+ #define DB9_DOWN              0x02
+@@ -69,10 +71,7 @@
+ #define DB9_NORMAL            0x0a
+ #define DB9_NOSELECT          0x08
+-#define DB9_SATURN0           0x00
+-#define DB9_SATURN1           0x02
+-#define DB9_SATURN2           0x04
+-#define DB9_SATURN3           0x06
++#define DB9_MAX_DEVICES 2
+ #define DB9_GENESIS6_DELAY    14
+ #define DB9_REFRESH_TIME      HZ/100
+@@ -82,7 +81,7 @@
+ static int db9_3[] __initdata = { -1, 0 };
+ struct db9 {
+-      struct input_dev dev[2];
++      struct input_dev dev[DB9_MAX_DEVICES];
+       struct timer_list timer;
+       struct pardevice *pd;   
+       int mode;
+@@ -96,12 +95,247 @@
+ static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
+ static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
+-static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 };
++static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
+ static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
+-                                      db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn };
++                                      db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
++                                      db9_cd32_btn, db9_cd32_btn };
+ static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
+                                     NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
+-                                   "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad" };
++                                   "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
++
++static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
++static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
++static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
++static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
++static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
++
++/*
++ * Saturn controllers
++ */
++#define DB9_SATURN_DELAY 300
++static const int db9_saturn_byte[] = { 1, 1, 1, 2, 2, 2, 2, 2, 1 };
++static const unsigned char db9_saturn_mask[] = { 0x04, 0x01, 0x02, 0x40, 0x20, 0x10, 0x08, 0x80, 0x08 };
++
++/*
++ * db9_saturn_write_sub() writes 2 bit data.
++ */
++static void db9_saturn_write_sub(struct parport *port, int type, unsigned char data, int powered, int pwr_sub)
++{
++      unsigned char c;
++
++      switch (type) {
++      case 1: /* DPP1 */
++              c = 0x80 | 0x30 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | data;
++              parport_write_data(port, c);
++              break;
++      case 2: /* DPP2 */
++              c = 0x40 | data << 4 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | 0x03;
++              parport_write_data(port, c);
++              break;
++      case 0: /* DB9 */
++              c = ((((data & 2) ? 2 : 0) | ((data & 1) ? 4 : 0)) ^ 0x02) | !powered;
++              parport_write_control(port, c);
++              break;
++      }
++}
++
++/*
++ * gc_saturn_read_sub() reads 4 bit data.
++ */
++static unsigned char db9_saturn_read_sub(struct parport *port, int type)
++{
++      unsigned char data;
++
++      if (type) {
++              /* DPP */
++              data = parport_read_status(port) ^ 0x80;
++              return (data & 0x80 ? 1 : 0) | (data & 0x40 ? 2 : 0)
++                   | (data & 0x20 ? 4 : 0) | (data & 0x10 ? 8 : 0);
++      } else {
++              /* DB9 */
++              data = parport_read_data(port) & 0x0f;
++              return (data & 0x8 ? 1 : 0) | (data & 0x4 ? 2 : 0)
++                   | (data & 0x2 ? 4 : 0) | (data & 0x1 ? 8 : 0);
++      }
++}
++
++/*
++ * db9_saturn_read_analog() sends clock and reads 8 bit data.
++ */
++static unsigned char db9_saturn_read_analog(struct parport *port, int type, int powered)
++{
++      unsigned char data;
++
++      db9_saturn_write_sub(port, type, 0, powered, 0);
++      udelay(DB9_SATURN_DELAY);
++      data = db9_saturn_read_sub(port, type) << 4;
++      db9_saturn_write_sub(port, type, 2, powered, 0);
++      udelay(DB9_SATURN_DELAY);
++      data |= db9_saturn_read_sub(port, type);
++      return data;
++}
++
++/*
++ * db9_saturn_read_packet() reads whole saturn packet at connector 
++ * and returns device identifier code.
++ */
++static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
++{
++      int i, j;
++      unsigned char tmp;
++
++      db9_saturn_write_sub(port, type, 3, powered, 0);
++      data[0] = db9_saturn_read_sub(port, type);
++      switch (data[0] & 0x0f) {
++      case 0xf:
++              /* 1111  no pad */
++              return data[0] = 0xff;
++      case 0x4: case 0x4 | 0x8:
++              /* ?100 : digital controller */
++              db9_saturn_write_sub(port, type, 0, powered, 1);
++              data[2] = db9_saturn_read_sub(port, type) << 4;
++              db9_saturn_write_sub(port, type, 2, powered, 1);
++              data[1] = db9_saturn_read_sub(port, type) << 4;
++              db9_saturn_write_sub(port, type, 1, powered, 1);
++              data[1] |= db9_saturn_read_sub(port, type);
++              db9_saturn_write_sub(port, type, 3, powered, 1);
++              /* data[2] |= db9_saturn_read_sub(port, type); */
++              data[2] |= data[0];
++              return data[0] = 0x02;
++      case 0x1:
++              /* 0001 : analog controller or multitap */
++              db9_saturn_write_sub(port, type, 2, powered, 0);
++              udelay(DB9_SATURN_DELAY);
++              data[0] = db9_saturn_read_analog(port, type, powered);
++              if (data[0] != 0x41) {
++                      /* read analog controller */
++                      for (i = 0; i < (data[0] & 0x0f); i++)
++                              data[i + 1] = db9_saturn_read_analog(port, type, powered);
++                      db9_saturn_write_sub(port, type, 3, powered, 0);
++                      return data[0];
++              } else {
++                      /* read multitap */
++                      if (db9_saturn_read_analog(port, type, powered) != 0x60)
++                              return data[0] = 0xff;
++                      for (i = 0; i < 60; i += 10) {
++                              data[i] = db9_saturn_read_analog(port, type, powered);
++                              if (data[i] != 0xff)
++                                      /* read each pad */
++                                      for (j = 0; j < (data[i] & 0x0f); j++)
++                                              data[i + j + 1] = db9_saturn_read_analog(port, type, powered);
++                      }
++                      db9_saturn_write_sub(port, type, 3, powered, 0);
++                      return 0x41;
++              }
++      case 0x0:
++              /* 0000 : mouse */
++              db9_saturn_write_sub(port, type, 2, powered, 0);
++              udelay(DB9_SATURN_DELAY);
++              tmp = db9_saturn_read_analog(port, type, powered);
++              if (tmp == 0xff) {
++                      for (i = 0; i < 3; i++)
++                              data[i + 1] = db9_saturn_read_analog(port, type, powered);
++                      db9_saturn_write_sub(port, type, 3, powered, 0);
++                      return data[0] = 0xe3;
++              }
++      default:
++              return data[0];
++      }
++}
++
++/*
++ * db9_saturn_report() analyzes packet and reports.
++ */
++static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *dev, int n, int max_pads)
++{
++      int tmp, i, j;
++
++      tmp = (id == 0x41) ? 60 : 10;
++      for (j = 0; (j < tmp) && (n < max_pads); j += 10, n++) {
++              switch (data[j]) {
++              case 0x16: /* multi controller (analog 4 axis) */
++                      input_report_abs(dev + n, db9_abs[5], data[j + 6]);
++              case 0x15: /* mission stick (analog 3 axis) */
++                      input_report_abs(dev + n, db9_abs[3], data[j + 4]);
++                      input_report_abs(dev + n, db9_abs[4], data[j + 5]);
++              case 0x13: /* racing controller (analog 1 axis) */
++                      input_report_abs(dev + n, db9_abs[2], data[j + 3]);
++              case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
++              case 0x02: /* digital pad (digital 2 axis + buttons) */
++                      input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
++                      input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
++                      for (i = 0; i < 9; i++)
++                              input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
++                      break;
++              case 0x19: /* mission stick x2 (analog 6 axis + buttons) */
++                      input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
++                      input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
++                      for (i = 0; i < 9; i++)
++                              input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
++                      input_report_abs(dev + n, db9_abs[2], data[j + 3]);
++                      input_report_abs(dev + n, db9_abs[3], data[j + 4]);
++                      input_report_abs(dev + n, db9_abs[4], data[j + 5]);
++                      /*
++                      input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
++                      input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
++                      */
++                      input_report_abs(dev + n, db9_abs[6], data[j + 7]);
++                      input_report_abs(dev + n, db9_abs[7], data[j + 8]);
++                      input_report_abs(dev + n, db9_abs[5], data[j + 9]);
++                      break;
++              case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */
++                      input_report_key(dev + n, BTN_A, data[j + 3] & 0x80);
++                      input_report_abs(dev + n, db9_abs[2], data[j + 3] & 0x7f);
++                      break;
++              case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */
++                      input_report_key(dev + n, BTN_START, data[j + 1] & 0x08);
++                      input_report_key(dev + n, BTN_A, data[j + 1] & 0x04);
++                      input_report_key(dev + n, BTN_C, data[j + 1] & 0x02);
++                      input_report_key(dev + n, BTN_B, data[j + 1] & 0x01);
++                      input_report_abs(dev + n, db9_abs[2], data[j + 2] ^ 0x80);
++                      input_report_abs(dev + n, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */
++                      break;
++              case 0xff:
++              default: /* no pad */
++                      input_report_abs(dev + n, db9_abs[0], 0);
++                      input_report_abs(dev + n, db9_abs[1], 0);
++                      for (i = 0; i < 9; i++)
++                              input_report_key(dev + n, db9_cd32_btn[i], 0);
++                      break;
++              }
++      }
++      return n;
++}
++
++static int db9_saturn(int mode, struct parport *port, struct input_dev *dev)
++{
++      unsigned char id, data[60];
++      int type, n, max_pads;
++      int tmp, i;
++
++      switch (mode) {
++      case DB9_SATURN_PAD:
++              type = 0;
++              n = 1;
++              break;
++      case DB9_SATURN_DPP:
++              type = 1;
++              n = 1;
++              break;
++      case DB9_SATURN_DPP_2:
++              type = 1;
++              n = 2;
++              break;
++      default:
++              return -1;
++      }
++      max_pads = min(db9_max_pads[mode], DB9_MAX_DEVICES);
++      for (tmp = 0, i = 0; i < n; i++) {
++              id = db9_saturn_read_packet(port, data, type + i, 1);
++              tmp = db9_saturn_report(id, data, dev, tmp, max_pads);
++      }
++      return 0;
++}
+ static void db9_timer(unsigned long private)
+ {
+@@ -222,28 +456,10 @@
+                       break;
+               case DB9_SATURN_PAD:
++              case DB9_SATURN_DPP:
++              case DB9_SATURN_DPP_2:
+-                      parport_write_control(port, DB9_SATURN0);
+-                      data = parport_read_data(port);
+-
+-                      input_report_key(dev, BTN_Y,  ~data & DB9_LEFT);
+-                      input_report_key(dev, BTN_Z,  ~data & DB9_DOWN);
+-                      input_report_key(dev, BTN_TL, ~data & DB9_UP);
+-                      input_report_key(dev, BTN_TR, ~data & DB9_RIGHT);
+-
+-                      parport_write_control(port, DB9_SATURN2);
+-                      data = parport_read_data(port);
+-
+-                      input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+-                      input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
+-                      
+-                      parport_write_control(port, DB9_NORMAL);
+-                      data = parport_read_data(port);
+-
+-                      input_report_key(dev, BTN_A, ~data & DB9_LEFT);
+-                      input_report_key(dev, BTN_B, ~data & DB9_UP);
+-                      input_report_key(dev, BTN_C, ~data & DB9_DOWN);
+-                      input_report_key(dev, BTN_X, ~data & DB9_RIGHT);
++                      db9_saturn(db9->mode, port, dev);
+                       break;
+               case DB9_CD32_PAD:
+@@ -279,8 +495,10 @@
+       if (!db9->used++) {
+               parport_claim(db9->pd);
+               parport_write_data(port, 0xff);
+-              parport_data_reverse(port);
+-              parport_write_control(port, DB9_NORMAL);
++              if (db9_reverse[db9->mode]) {
++                      parport_data_reverse(port);
++                      parport_write_control(port, DB9_NORMAL);
++              }
+               mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
+       }
+@@ -321,11 +539,13 @@
+               return NULL;
+       }
+-      if (!(pp->modes & PARPORT_MODE_TRISTATE) && config[1] != DB9_MULTI_0802) {
+-              printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
+-              return NULL;
++      if (db9_bidirectional[config[1]]) {
++              if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
++                      printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
++                      return NULL;
++              }
+       }
+-      
++
+       if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL)))
+               return NULL;
+       memset(db9, 0, sizeof(struct db9));
+@@ -343,7 +563,7 @@
+               return NULL;
+       }
+-      for (i = 0; i < 1 + (db9->mode == DB9_MULTI_0802_2); i++) {
++      for (i = 0; i < (min(db9_max_pads[db9->mode], DB9_MAX_DEVICES)); i++) {
+               sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i);
+@@ -359,14 +579,19 @@
+               db9->dev[i].id.version = 0x0100;
+               db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+-              db9->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+-
+               for (j = 0; j < db9_buttons[db9->mode]; j++)
+                       set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit); 
+-
+-              db9->dev[i].absmin[ABS_X] = -1; db9->dev[i].absmax[ABS_X] = 1;
+-              db9->dev[i].absmin[ABS_Y] = -1; db9->dev[i].absmax[ABS_Y] = 1;
+-
++              for (j = 0; j < db9_num_axis[db9->mode]; j++) {
++                      set_bit(db9_abs[j], db9->dev[i].absbit);
++                      if (j < 2) {
++                              db9->dev[i].absmin[db9_abs[j]] = -1;
++                              db9->dev[i].absmax[db9_abs[j]] = 1;
++                      } else {
++                              db9->dev[i].absmin[db9_abs[j]] = 1;
++                              db9->dev[i].absmax[db9_abs[j]] = 255;
++                              db9->dev[i].absflat[db9_abs[j]] = 0;
++                      }
++              }
+               input_register_device(db9->dev + i);
+               printk(KERN_INFO "input: %s on %s\n", db9->dev[i].name, db9->pd->port->name);
+       }
+@@ -419,7 +644,7 @@
+       for (i = 0; i < 3; i++) 
+               if (db9_base[i]) {
+-                      for (j = 0; j < 1 + (db9_base[i]->mode == DB9_MULTI_0802_2); j++)
++                      for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
+                               input_unregister_device(db9_base[i]->dev + j);
+               parport_unregister_device(db9_base[i]->pd);
+       }
+Index: linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-packets.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/iforce/iforce-packets.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-packets.c   2003-09-27 11:38:21.447267904 +0800
+@@ -166,8 +166,7 @@
+               iforce->expect_packet = 0;
+               iforce->ecmd = cmd;
+               memcpy(iforce->edata, data, IFORCE_MAX_LENGTH);
+-              if (waitqueue_active(&iforce->wait))
+-                      wake_up(&iforce->wait);
++              wake_up(&iforce->wait);
+       }
+ #endif
+@@ -264,7 +263,7 @@
+               set_current_state(TASK_INTERRUPTIBLE);
+               add_wait_queue(&iforce->wait, &wait);
+-              if (usb_submit_urb(iforce->ctrl, GFP_KERNEL)) {
++              if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) {
+                       set_current_state(TASK_RUNNING);
+                       remove_wait_queue(&iforce->wait, &wait);
+                       return -1;
+Index: linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/iforce/iforce-usb.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/iforce/iforce-usb.c       2003-09-27 11:38:21.449267600 +0800
+@@ -116,8 +116,7 @@
+       iforce_usb_xmit(iforce);
+-      if (waitqueue_active(&iforce->wait))
+-              wake_up(&iforce->wait);
++      wake_up(&iforce->wait);
+ }
+ static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs)
+@@ -125,8 +124,7 @@
+       struct iforce *iforce = urb->context;
+       if (urb->status) return;
+       iforce->ecmd = 0xff00 | urb->actual_length;
+-      if (waitqueue_active(&iforce->wait))
+-              wake_up(&iforce->wait);
++      wake_up(&iforce->wait);
+ }
+ static int iforce_usb_probe(struct usb_interface *intf,
+Index: linux-2.6.0-test5/drivers/input/joystick/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/joystick/Kconfig      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/joystick/Kconfig   2003-09-27 11:38:21.454266840 +0800
+@@ -155,7 +155,8 @@
+ config JOYSTICK_WARRIOR
+       tristate "Logitech WingMan Warrior joystick"
+-      depends on INPUT && INPUT_JOYSTICK && SERIO
++      depends on INPUT && INPUT_JOYSTICK
++      select SERIO
+       help
+         Say Y here if you have a Logitech WingMan Warrior joystick connected
+         to your computer's serial port. 
+@@ -167,7 +168,8 @@
+ config JOYSTICK_MAGELLAN
+       tristate "LogiCad3d Magellan/SpaceMouse 6dof controllers"
+-      depends on INPUT && INPUT_JOYSTICK && SERIO
++      depends on INPUT && INPUT_JOYSTICK
++      select SERIO
+       help
+         Say Y here if you have a Magellan or Space Mouse 6DOF controller
+         connected to your computer's serial port.
+@@ -179,7 +181,8 @@
+ config JOYSTICK_SPACEORB
+       tristate "SpaceTec SpaceOrb/Avenger 6dof controllers"
+-      depends on INPUT && INPUT_JOYSTICK && SERIO
++      depends on INPUT && INPUT_JOYSTICK
++      select SERIO
+       help
+         Say Y here if you have a SpaceOrb 360 or SpaceBall Avenger 6DOF
+         controller connected to your computer's serial port.
+@@ -191,7 +194,8 @@
+ config JOYSTICK_SPACEBALL
+       tristate "SpaceTec SpaceBall 6dof controllers"
+-      depends on INPUT && INPUT_JOYSTICK && SERIO
++      depends on INPUT && INPUT_JOYSTICK
++      select SERIO
+       help
+         Say Y here if you have a SpaceTec SpaceBall 2003/3003/4000 FLX
+         controller connected to your computer's serial port. For the
+@@ -204,7 +208,8 @@
+ config JOYSTICK_STINGER
+       tristate "Gravis Stinger gamepad"
+-      depends on INPUT && INPUT_JOYSTICK && SERIO
++      depends on INPUT && INPUT_JOYSTICK
++      select SERIO
+       help
+         Say Y here if you have a Gravis Stinger connected to one of your
+         serial ports.
+@@ -216,7 +221,8 @@
+ config JOYSTICK_TWIDDLER
+       tristate "Twiddler as a joystick"
+-      depends on INPUT && INPUT_JOYSTICK && SERIO
++      depends on INPUT && INPUT_JOYSTICK
++      select SERIO
+       help
+         Say Y here if you have a Handykey Twiddler connected to your
+         computer's serial port and want to use it as a joystick.
+Index: linux-2.6.0-test5/drivers/input/keyboard/atkbd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/keyboard/atkbd.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/keyboard/atkbd.c   2003-09-27 11:38:21.459266080 +0800
+@@ -18,6 +18,7 @@
+ #include <linux/input.h>
+ #include <linux/serio.h>
+ #include <linux/workqueue.h>
++#include <linux/timer.h>
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+ MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
+@@ -34,14 +35,14 @@
+ /*
+  * Scancode to keycode tables. These are just the default setting, and
+- * are loadable via an userland utility.
++ * are loadable via a userland utility.
+  */
+ static unsigned char atkbd_set2_keycode[512] = {
+         0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41, 85,
+         0, 56, 42,182, 29, 16,  2, 89,  0,  0, 44, 31, 30, 17,  3, 90,
+-        0, 46, 45, 32, 18,  5,  4, 91,  0, 57, 47, 33, 20, 19,  6,  0,
+-        0, 49, 48, 35, 34, 21,  7,  0,  0,  0, 50, 36, 22,  8,  9,  0,
++        0, 46, 45, 32, 18,  5,  4, 91, 90, 57, 47, 33, 20, 19,  6,  0,
++       91, 49, 48, 35, 34, 21,  7,  0,  0,  0, 50, 36, 22,  8,  9,  0,
+         0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
+       122, 89, 40,120, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0,  0,
+        85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121,  0,123,
+@@ -70,7 +71,7 @@
+       134, 46, 45, 32, 18,  5,  4, 63,135, 57, 47, 33, 20, 19,  6, 64,
+       136, 49, 48, 35, 34, 21,  7, 65,137,100, 50, 36, 22,  8,  9, 66,
+       125, 51, 37, 23, 24, 11, 10, 67,126, 52, 53, 38, 39, 25, 12, 68,
+-      113,114, 40, 84, 26, 13, 87, 99,100, 54, 28, 27, 43, 84, 88, 70,
++      113,114, 40, 84, 26, 13, 87, 99, 97, 54, 28, 27, 43, 84, 88, 70,
+       108,105,119,103,111,107, 14,110,  0, 79,106, 75, 71,109,102,104,
+        82, 83, 80, 76, 77, 72, 69, 98,  0, 96, 81,  0, 78, 73, 55, 85,
+        89, 90, 91, 92, 74,185,184,182,  0,  0,  0,125,126,127,112,  0,
+@@ -87,10 +88,10 @@
+ #define ATKBD_CMD_GSCANSET    0x11f0
+ #define ATKBD_CMD_SSCANSET    0x10f0
+ #define ATKBD_CMD_GETID               0x02f2
++#define ATKBD_CMD_SETREP      0x10f3
+ #define ATKBD_CMD_ENABLE      0x00f4
+ #define ATKBD_CMD_RESET_DIS   0x00f5
+ #define ATKBD_CMD_RESET_BAT   0x02ff
+-#define ATKBD_CMD_SETALL_MB   0x00f8
+ #define ATKBD_CMD_RESEND      0x00fe
+ #define ATKBD_CMD_EX_ENABLE   0x10ea
+ #define ATKBD_CMD_EX_SETLEDS  0x20eb
+@@ -114,23 +115,25 @@
+       unsigned char keycode[512];
+       struct input_dev dev;
+       struct serio *serio;
++      struct timer_list timer;
+       char name[64];
+       char phys[32];
+       unsigned char cmdbuf[4];
+       unsigned char cmdcnt;
+       unsigned char set;
+       unsigned char release;
++      int lastkey;
+       volatile signed char ack;
+       unsigned char emul;
+       unsigned short id;
+       unsigned char write;
+-      unsigned char resend;
+ };
+ /*
+  * atkbd_interrupt(). Here takes place processing of data received from
+  * the keyboard into events.
+  */
++void dump_i8042_history(void);
+ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
+                       unsigned int flags, struct pt_regs *regs)
+@@ -142,15 +145,13 @@
+       printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
+ #endif
+-      if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
++#if !defined(__i386__) && !defined (__x86_64__)
++      if ((flags & (SERIO_FRAME | SERIO_PARITY)) &&
++          (~flags & SERIO_TIMEOUT)) {
+               printk("atkbd.c: frame/parity error: %02x\n", flags);
+-              serio_write(serio, ATKBD_CMD_RESEND);
+-              atkbd->resend = 1;
+               goto out;
+       }
+-      
+-      if (!flags)
+-              atkbd->resend = 0;
++#endif
+       switch (code) {
+               case ATKBD_RET_ACK:
+@@ -193,8 +194,18 @@
+               case ATKBD_KEY_UNKNOWN:
+                       printk(KERN_WARNING "atkbd.c: Unknown key (set %d, scancode %#x, on %s) %s.\n",
+                               atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
++                      dump_i8042_history();
+                       break;
+               default:
++#if 0
++                      if (!atkbd->release) {
++                              mod_timer(&atkbd->timer,
++                                      jiffies + (test_bit(atkbd->keycode[code],
++                                              atkbd->dev.key) ? HZ/33 : HZ/4) + HZ/100);
++                              atkbd->lastkey = atkbd->keycode[code];
++                      }
++#endif
++
+                       input_regs(&atkbd->dev, regs);
+                       input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
+                       input_sync(&atkbd->dev);
+@@ -205,6 +216,13 @@
+       return IRQ_HANDLED;
+ }
++static void atkbd_force_key_up(unsigned long data)
++{
++      struct atkbd *atkbd = (void *) data;
++      input_report_key(&atkbd->dev, atkbd->lastkey, 0);
++      input_sync(&atkbd->dev);
++}
++
+ /*
+  * atkbd_sendbyte() sends a byte to the keyboard, and waits for
+  * acknowledge. It doesn't handle resends according to the keyboard
+@@ -214,7 +232,7 @@
+ static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
+ {
+-      int timeout = 10000; /* 100 msec */
++      int timeout = 20000; /* 200 msec */
+       atkbd->ack = 0;
+ #ifdef ATKBD_DEBUG
+@@ -322,6 +340,53 @@
+ }
+ /*
++ * atkbd_probe() probes for an AT keyboard on a serio port.
++ */
++
++static int atkbd_probe(struct atkbd *atkbd)
++{
++      unsigned char param[2];
++
++/*
++ * Some systems, where the bit-twiddling when testing the io-lines of the
++ * controller may confuse the keyboard need a full reset of the keyboard. On
++ * these systems the BIOS also usually doesn't do it for us.
++ */
++
++      if (atkbd_reset)
++              if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) 
++                      printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
++
++/*
++ * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
++ * Some keyboards report different values, but the first byte is always 0xab or
++ * 0xac. Some old AT keyboards don't report anything. If a mouse is connected, this
++ * should make sure we don't try to set the LEDs on it.
++ */
++
++      if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
++
++/*
++ * If the get ID command failed, we check if we can at least set the LEDs on
++ * the keyboard. This should work on every keyboard out there. It also turns
++ * the LEDs off, which we want anyway.
++ */
++              param[0] = 0;
++              if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
++                      return -1;
++              atkbd->id = 0xabba;
++              return 0;
++      }
++
++      if (param[0] != 0xab && param[0] != 0xac)
++              return -1;
++      atkbd->id = (param[0] << 8) | param[1];
++
++
++      return 0;
++}
++
++/*
+  * atkbd_set_3 checks if a keyboard has a working Set 3 support, and
+  * sets it into that. Unfortunately there are keyboards that can be switched
+  * to Set 3, but don't work well in that (BTC Multimedia ...)
+@@ -355,75 +420,26 @@
+                       return 4;
+       }
+-/*
+- * Try to set the set we want.
+- */
++      if (atkbd_set != 3) 
++              return 2;
+-      param[0] = atkbd_set;
++      param[0] = 3;
+       if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
+               return 2;
+-/*
+- * Read set number. Beware here. Some keyboards always send '2'
+- * or some other number regardless into what mode they have been
+- * attempted to be set. Other keyboards treat the '0' command as
+- * 'set to set 0', and not 'report current set' as they should.
+- * In that case we time out, and return 2.
+- */
+-
+       param[0] = 0;
+       if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET))
+               return 2;
+-/*
+- * Here we return the set number the keyboard reports about
+- * itself.
+- */
++      if (param[0] != 3)
++              return 2;
+-      return (param[0] == 3) ? 3 : 2;
++      return 3;
+ }
+-/*
+- * atkbd_probe() probes for an AT keyboard on a serio port.
+- */
+-
+-static int atkbd_probe(struct atkbd *atkbd)
++static int atkbd_enable(struct atkbd *atkbd)
+ {
+-      unsigned char param[2];
+-
+-/*
+- * Some systems, where the bit-twiddling when testing the io-lines of the
+- * controller may confuse the keyboard need a full reset of the keyboard. On
+- * these systems the BIOS also usually doesn't do it for us.
+- */
+-
+-      if (atkbd_reset)
+-              if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) 
+-                      printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
+-
+-/*
+- * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
+- * Some keyboards report different values, but the first byte is always 0xab or
+- * 0xac. Some old AT keyboards don't report anything.
+- */
+-
+-      if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
+-
+-/*
+- * If the get ID command failed, we check if we can at least set the LEDs on
+- * the keyboard. This should work on every keyboard out there. It also turns
+- * the LEDs off, which we want anyway.
+- */
+-              param[0] = 0;
+-              if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+-                      return -1;
+-              atkbd->id = 0xabba;
+-              return 0;
+-      }
+-
+-      if (param[0] != 0xab && param[0] != 0xac)
+-              return -1;
+-      atkbd->id = (param[0] << 8) | param[1];
++      unsigned char param[1];
+ /*
+  * Set the LEDs to a defined state.
+@@ -434,21 +450,22 @@
+               return -1;
+ /*
+- * Disable autorepeat. We don't need it, as we do it in software anyway,
+- * because that way can get faster repeat, and have less system load (less
+- * accesses to the slow ISA hardware). If this fails, we don't care, and will
+- * just ignore the repeated keys.
++ * Set autorepeat to fastest possible.
+  */
+-      atkbd_command(atkbd, NULL, ATKBD_CMD_SETALL_MB);
++      param[0] = 0;
++      if (atkbd_command(atkbd, param, ATKBD_CMD_SETREP))
++              return -1;
+ /*
+- * Last, we enable the keyboard to make sure  that we get keypresses from it.
++ * Enable the keyboard to receive keystrokes.
+  */
+-      if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE))
++      if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) {
+               printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
+                       atkbd->serio->phys);
++              return -1;
++      }
+       return 0;
+ }
+@@ -473,6 +490,7 @@
+       struct atkbd *atkbd = serio->private;
+       input_unregister_device(&atkbd->dev);
+       serio_close(serio);
++      serio->private = NULL;
+       kfree(atkbd);
+ }
+@@ -505,6 +523,9 @@
+               atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+       } else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++      atkbd->dev.rep[REP_DELAY] = HZ/4 + HZ/50;
++      atkbd->dev.rep[REP_PERIOD] = HZ/33;
++
+       atkbd->serio = serio;
+       init_input_dev(&atkbd->dev);
+@@ -517,7 +538,12 @@
+       serio->private = atkbd;
++      init_timer(&atkbd->timer);
++      atkbd->timer.data = (long) atkbd;
++      atkbd->timer.function = atkbd_force_key_up;
++
+       if (serio_open(serio, dev)) {
++              serio->private = NULL;
+               kfree(atkbd);
+               return;
+       }
+@@ -526,11 +552,13 @@
+               if (atkbd_probe(atkbd)) {
+                       serio_close(serio);
++                      serio->private = NULL;
+                       kfree(atkbd);
+                       return;
+               }
+               
+               atkbd->set = atkbd_set_3(atkbd);
++              atkbd_enable(atkbd);
+       } else {
+               atkbd->set = 2;
+Index: linux-2.6.0-test5/drivers/input/keyboard/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/keyboard/Kconfig      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/keyboard/Kconfig   2003-09-27 11:38:21.460265928 +0800
+@@ -14,7 +14,8 @@
+ config KEYBOARD_ATKBD
+       tristate "AT keyboard support" if EMBEDDED || !X86 
+       default y
+-      depends on INPUT && INPUT_KEYBOARD && SERIO
++      depends on INPUT && INPUT_KEYBOARD
++      select SERIO_I8042
+       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
+@@ -30,7 +31,8 @@
+ config KEYBOARD_SUNKBD
+       tristate "Sun Type 4 and Type 5 keyboard support"
+-      depends on INPUT && INPUT_KEYBOARD && SERIO
++      depends on INPUT && INPUT_KEYBOARD
++      select SERIO
+       help
+         Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
+         connected either to the Sun keyboard connector or to an serial
+@@ -43,7 +45,8 @@
+ config KEYBOARD_XTKBD
+       tristate "XT Keyboard support"
+-      depends on INPUT && INPUT_KEYBOARD && SERIO
++      depends on INPUT && INPUT_KEYBOARD
++      select SERIO
+       help
+         Say Y here if you want to use the old IBM PC/XT keyboard (or
+         compatible) on your system. This is only possible with a
+@@ -57,7 +60,8 @@
+ config KEYBOARD_NEWTON
+       tristate "Newton keyboard"
+-      depends on INPUT && INPUT_KEYBOARD && SERIO
++      depends on INPUT && INPUT_KEYBOARD
++      select SERIO
+       help
+         Say Y here if you have a Newton keyboard on a serial port.
+@@ -92,7 +96,8 @@
+ config KEYBOARD_98KBD
+       tristate "NEC PC-9800 Keyboard support"
+-      depends on X86_PC9800 && INPUT && INPUT_KEYBOARD && SERIO
++      depends on X86_PC9800 && INPUT && INPUT_KEYBOARD
++      select SERIO
+       help
+         Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or
+         compatible) on your system. 
+Index: linux-2.6.0-test5/drivers/input/mouse/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/Kconfig      2003-09-27 11:38:21.463265472 +0800
+@@ -14,14 +14,13 @@
+ config MOUSE_PS2
+       tristate "PS/2 mouse"
+       default y
+-      depends on INPUT && INPUT_MOUSE && SERIO
++      depends on INPUT && INPUT_MOUSE
++      select SERIO_I8042
+       ---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
+         mice with wheels and extra buttons, Microsoft, Logitech or Genius
+-        compatible. Support for Synaptics TouchPads is also included.
+-        For Synaptics TouchPad support in XFree86 you'll need this XFree86
+-        driver: http://w1.894.telia.com/~u89404340/touchpad/index.html
++        compatible.
+         If unsure, say Y.
+@@ -30,9 +29,26 @@
+         The module will be called psmouse. If you want to compile it as a
+         module, say M here and read <file:Documentation/modules.txt>.
++config MOUSE_PS2_SYNAPTICS
++      bool "Synaptics TouchPad"
++      default n
++      depends on INPUT && INPUT_MOUSE && MOUSE_PS2
++      ---help---
++        Say Y here if you have a Synaptics TouchPad connected to your system.
++        This touchpad is found on many modern laptop computers.
++
++        Note that you also need a user space driver to interpret the data
++        generated by the kernel. A compatible driver for XFree86 is available
++        from http://w1.894.telia.com/~u89404340/touchpad/index.html
++
++        The gpm program is not yet able to interpret the data from this
++        driver, so if you need to use the touchpad in the console, you have to
++        say N for now.
++
+ config MOUSE_SERIAL
+       tristate "Serial mouse"
+-      depends on INPUT && INPUT_MOUSE && SERIO
++      depends on INPUT && INPUT_MOUSE
++      select SERIO
+       ---help---
+         Say Y here if you have a serial (RS-232, COM port) mouse connected
+         to your system. This includes Sun, MouseSystems, Microsoft,
+Index: linux-2.6.0-test5/drivers/input/mouse/psmouse-base.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/psmouse-base.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/psmouse-base.c       2003-09-27 11:38:21.468264712 +0800
+@@ -17,30 +17,37 @@
+ #include <linux/input.h>
+ #include <linux/serio.h>
+ #include <linux/init.h>
++#include <linux/pm.h>
+ #include "psmouse.h"
+ #include "synaptics.h"
+ #include "logips2pp.h"
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+ MODULE_DESCRIPTION("PS/2 mouse driver");
++MODULE_PARM(psmouse_imps2, "1i");
++MODULE_PARM_DESC(psmouse_imps2, "Limit protocol extensions to the Intellimouse protocol.");
+ MODULE_PARM(psmouse_noext, "1i");
+ MODULE_PARM_DESC(psmouse_noext, "Disable any protocol extensions. Useful for KVM switches.");
+ MODULE_PARM(psmouse_resolution, "i");
+ MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
+ MODULE_PARM(psmouse_smartscroll, "i");
+ MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
++MODULE_PARM(psmouse_resetafter, "i");
++MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
+ MODULE_LICENSE("GPL");
+ #define PSMOUSE_LOGITECH_SMARTSCROLL  1
++static int psmouse_imps2;
+ static int psmouse_noext;
+ int psmouse_resolution;
+ int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
++unsigned int psmouse_resetafter;
+-static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "Synaptics"};
++static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
+ /*
+- * psmouse_process_packet() anlyzes the PS/2 mouse packet contents and
++ * psmouse_process_packet() analyzes the PS/2 mouse packet contents and
+  * reports relevant events to the input module.
+  */
+@@ -108,6 +115,9 @@
+ {
+       struct psmouse *psmouse = serio->private;
++      if (psmouse->state == PSMOUSE_IGNORE)
++              goto out;
++
+       if (psmouse->acking) {
+               switch (data) {
+                       case PSMOUSE_RET_ACK:
+@@ -132,31 +142,46 @@
+       }
+       if (psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
+-              printk(KERN_WARNING "psmouse.c: Lost synchronization, throwing %d bytes away.\n", psmouse->pktcnt);
++              printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
++                     psmouse->name, psmouse->phys, psmouse->pktcnt);
+               psmouse->pktcnt = 0;
+       }
+       
+       psmouse->last = jiffies;
+       psmouse->packet[psmouse->pktcnt++] = data;
+-      if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
+-              psmouse_process_packet(psmouse, regs);
+-              psmouse->pktcnt = 0;
+-              goto out;
++      if (psmouse->packet[0] == PSMOUSE_RET_BAT) {
++              if (psmouse->pktcnt == 1)
++                      goto out;
++              
++              if (psmouse->pktcnt == 2) {
++                      if (psmouse->packet[1] == PSMOUSE_RET_ID) {
++                              psmouse->state = PSMOUSE_IGNORE;
++                              serio_rescan(serio);
++                              goto out;
++                      }
++                      if (psmouse->type == PSMOUSE_SYNAPTICS) {
++                              /* neither 0xAA nor 0x00 are valid first bytes
++                               * for a packet in absolute mode
++                               */
++                              psmouse->pktcnt = 0;
++                              goto out;
++                      }
++              }
+       }
+-      if (psmouse->pktcnt == 1 && psmouse->type == PSMOUSE_SYNAPTICS) {
++      if (psmouse->type == PSMOUSE_SYNAPTICS) {
+               /*
+                * The synaptics driver has its own resync logic,
+                * so it needs to receive all bytes one at a time.
+                */
+               synaptics_process_byte(psmouse, regs);
+-              psmouse->pktcnt = 0;
+               goto out;
+       }
+-      if (psmouse->pktcnt == 1 && psmouse->packet[0] == PSMOUSE_RET_BAT) {
+-              serio_rescan(serio);
++      if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
++              psmouse_process_packet(psmouse, regs);
++              psmouse->pktcnt = 0;
+               goto out;
+       }
+ out:
+@@ -200,7 +225,7 @@
+       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))
+@@ -227,7 +252,7 @@
+       for (i = 0; i < receive; i++)
+               param[i] = psmouse->cmdbuf[(receive - 1) - i];
+-      if (psmouse->cmdcnt) 
++      if (psmouse->cmdcnt)
+               return (psmouse->cmdcnt = 0) - 1;
+       return 0;
+@@ -250,66 +275,68 @@
+       if (psmouse_noext)
+               return PSMOUSE_PS2;
+-/*
+- * Try Synaptics TouchPad magic ID
+- */
++      if (!psmouse_imps2) {
+-       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) {
+-              psmouse->vendor = "Synaptics";
+-              psmouse->name = "TouchPad";
+-              if (!synaptics_init(psmouse))
+-                      return PSMOUSE_SYNAPTICS;
+-              else
+-                      return PSMOUSE_PS2;
+-       }
++              /*
++               * Try Synaptics TouchPad magic ID
++               */
+-/*
+- * Try Genius NetMouse magic init.
+- */
++              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) {
++                      psmouse->vendor = "Synaptics";
++                      psmouse->name = "TouchPad";
++                      if (!synaptics_init(psmouse))
++                              return PSMOUSE_SYNAPTICS;
++                      else
++                              return PSMOUSE_PS2;
++              }
+-      param[0] = 3;
+-      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++              /*
++               * Try Genius NetMouse magic init.
++               */
+-      if (param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) {
++              param[0] = 3;
++              psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++              psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++              psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++              psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++              psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+-              set_bit(BTN_EXTRA, psmouse->dev.keybit);
+-              set_bit(BTN_SIDE, psmouse->dev.keybit);
+-              set_bit(REL_WHEEL, psmouse->dev.relbit);
++              if (param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) {
+-              psmouse->vendor = "Genius";
+-              psmouse->name = "Wheel Mouse";
+-              return PSMOUSE_GENPS;
+-      }
++                      set_bit(BTN_EXTRA, psmouse->dev.keybit);
++                      set_bit(BTN_SIDE, psmouse->dev.keybit);
++                      set_bit(REL_WHEEL, psmouse->dev.relbit);
+-/*
+- * Try Logitech magic ID.
+- */
++                      psmouse->vendor = "Genius";
++                      psmouse->name = "Wheel Mouse";
++                      return PSMOUSE_GENPS;
++              }
+-      param[0] = 0;
+-      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      param[1] = 0;
+-      psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++              /*
++               * Try Logitech magic ID.
++               */
+-      if (param[1]) {
+-              int type = ps2pp_detect_model(psmouse, param);
+-              if (type)
+-                      return type;
++              param[0] = 0;
++              psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++              psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++              psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++              psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++              param[1] = 0;
++              psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++
++              if (param[1]) {
++                      int type = ps2pp_detect_model(psmouse, param);
++                      if (type)
++                              return type;
++              }
+       }
+-
+ /*
+  * Try IntelliMouse magic init.
+  */
+@@ -450,14 +477,18 @@
+  */
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM);
++}
+ /*
+- * Last, we enable the mouse so that we get reports from it.
++ * psmouse_activate() enables the mouse so that we get motion reports from it.
+  */
++static void psmouse_activate(struct psmouse *psmouse)
++{
+       if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
+               printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys);
++      psmouse->state = PSMOUSE_ACTIVATED;
+ }
+ /*
+@@ -478,13 +509,39 @@
+ static void psmouse_disconnect(struct serio *serio)
+ {
+       struct psmouse *psmouse = serio->private;
++
++      psmouse->state = PSMOUSE_IGNORE;
++      synaptics_disconnect(psmouse);
+       input_unregister_device(&psmouse->dev);
+       serio_close(serio);
+-      synaptics_disconnect(psmouse);
+       kfree(psmouse);
+ }
+ /*
++ * Reinitialize mouse hardware after software suspend.
++ */
++
++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);
++
++      return 0;
++}
++
++/*
+  * psmouse_connect() is a callback from the serio module when
+  * an unhandled serio port is found.
+  */
+@@ -492,8 +549,10 @@
+ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
+ {
+       struct psmouse *psmouse;
++      struct pm_dev *pmdev;
+       
+-      if ((serio->type & SERIO_TYPE) != SERIO_8042)
++      if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
++          (serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
+               return;
+       if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))
+@@ -506,6 +565,7 @@
+       psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+       psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
++      psmouse->state = PSMOUSE_NEW_DEVICE;
+       psmouse->serio = serio;
+       psmouse->dev.private = psmouse;
+@@ -522,6 +582,12 @@
+               return;
+       }
+       
++      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",
+               psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
+       sprintf(psmouse->phys, "%s/input0",
+@@ -539,6 +605,10 @@
+       printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
+       psmouse_initialize(psmouse);
++
++      synaptics_pt_init(psmouse);
++
++      psmouse_activate(psmouse);
+ }
+ static struct serio_dev psmouse_dev = {
+@@ -549,6 +619,12 @@
+ };
+ #ifndef MODULE
++static int __init psmouse_imps2_setup(char *str)
++{
++      psmouse_imps2 = 1;
++      return 1;
++}
++
+ static int __init psmouse_noext_setup(char *str)
+ {
+       psmouse_noext = 1;
+@@ -567,9 +643,17 @@
+       return 1;
+ }
++static int __init psmouse_resetafter_setup(char *str)
++{
++      get_option(&str, &psmouse_resetafter);
++      return 1;
++}
++
++__setup("psmouse_imps2", psmouse_imps2_setup);
+ __setup("psmouse_noext", psmouse_noext_setup);
+ __setup("psmouse_resolution=", psmouse_resolution_setup);
+ __setup("psmouse_smartscroll=", psmouse_smartscroll_setup);
++__setup("psmouse_resetafter=", psmouse_resetafter_setup);
+ #endif
+Index: linux-2.6.0-test5/drivers/input/mouse/psmouse.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/psmouse.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/psmouse.h    2003-09-27 11:38:21.470264408 +0800
+@@ -13,9 +13,15 @@
+ #define PSMOUSE_CMD_RESET_BAT 0x02ff
+ #define PSMOUSE_RET_BAT               0xaa
++#define PSMOUSE_RET_ID                0x00
+ #define PSMOUSE_RET_ACK               0xfa
+ #define PSMOUSE_RET_NAK               0xfe
++/* psmouse states */
++#define PSMOUSE_NEW_DEVICE    0
++#define PSMOUSE_ACTIVATED     1
++#define PSMOUSE_IGNORE                2
++
+ struct psmouse {
+       void *private;
+       struct input_dev dev;
+@@ -29,6 +35,7 @@
+       unsigned char type;
+       unsigned char model;
+       unsigned long last;
++      unsigned char state;
+       char acking;
+       volatile char ack;
+       char error;
+@@ -36,16 +43,17 @@
+       char phys[32];
+ };
+-#define PSMOUSE_PS2   1
+-#define PSMOUSE_PS2PP 2
+-#define PSMOUSE_PS2TPP        3
+-#define PSMOUSE_GENPS 4
+-#define PSMOUSE_IMPS  5
+-#define PSMOUSE_IMEX  6
+-#define PSMOUSE_SYNAPTICS 7
++#define PSMOUSE_PS2           1
++#define PSMOUSE_PS2PP         2
++#define PSMOUSE_PS2TPP                3
++#define PSMOUSE_GENPS         4
++#define PSMOUSE_IMPS          5
++#define PSMOUSE_IMEX          6
++#define PSMOUSE_SYNAPTICS     7
+ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
+ extern int psmouse_smartscroll;
++extern unsigned int psmouse_resetafter;
+ #endif /* _PSMOUSE_H */
+Index: linux-2.6.0-test5/drivers/input/mouse/synaptics.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/synaptics.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/synaptics.c  2003-09-27 11:38:21.474263800 +0800
+@@ -1,6 +1,9 @@
+ /*
+  * Synaptics TouchPad PS/2 mouse driver
+  *
++ *   2003 Dmitry Torokhov <dtor@mail.ru>
++ *     Added support for pass-through port
++ *
+  *   2003 Peter Osterlund <petero2@telia.com>
+  *     Ported to 2.5 input device infrastructure.
+  *
+@@ -21,6 +24,7 @@
+ #include <linux/module.h>
+ #include <linux/input.h>
++#include <linux/serio.h>
+ #include "psmouse.h"
+ #include "synaptics.h"
+@@ -32,7 +36,7 @@
+  * Use the Synaptics extended ps/2 syntax to write a special command byte.
+  * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
+  *                  is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd
+- *                  and synaptics_set_mode)
++ *                  and synaptics_mode_cmd)
+  */
+ static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command)
+ {
+@@ -65,13 +69,13 @@
+ /*
+  * Set the synaptics touchpad mode byte by special commands
+  */
+-static int synaptics_set_mode(struct psmouse *psmouse, unsigned char mode)
++static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
+ {
+       unsigned char param[1];
+       if (synaptics_special_cmd(psmouse, mode))
+               return -1;
+-      param[0] = 0x14;
++      param[0] = SYN_PS_SET_MODE2;
+       if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE))
+               return -1;
+       return 0;
+@@ -83,7 +87,7 @@
+       if (psmouse_command(psmouse, r, PSMOUSE_CMD_RESET_BAT))
+               return -1;
+-      if (r[0] == 0xAA && r[1] == 0x00)
++      if (r[0] == PSMOUSE_RET_BAT && r[1] == PSMOUSE_RET_ID)
+               return 0;
+       return -1;
+ }
+@@ -92,13 +96,14 @@
+  * Read the model-id bytes from the touchpad
+  * see also SYN_MODEL_* macros
+  */
+-static int synaptics_model_id(struct psmouse *psmouse, unsigned long int *model_id)
++static int synaptics_model_id(struct psmouse *psmouse)
+ {
++      struct synaptics_data *priv = psmouse->private;
+       unsigned char mi[3];
+       if (synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi))
+               return -1;
+-      *model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
++      priv->model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
+       return 0;
+ }
+@@ -106,47 +111,50 @@
+  * Read the capability-bits from the touchpad
+  * see also the SYN_CAP_* macros
+  */
+-static int synaptics_capability(struct psmouse *psmouse, unsigned long int *capability)
++static int synaptics_capability(struct psmouse *psmouse)
+ {
++      struct synaptics_data *priv = psmouse->private;
+       unsigned char cap[3];
+       if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
+               return -1;
+-      *capability = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+-      if (SYN_CAP_VALID(*capability))
+-              return 0;
+-      return -1;
++      priv->capabilities = (cap[0]<<16) | (cap[1]<<8) | cap[2];
++      priv->ext_cap = 0;
++      if (!SYN_CAP_VALID(priv->capabilities))
++              return -1;
++
++      if (SYN_EXT_CAP_REQUESTS(priv->capabilities)) {
++              if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
++                      printk(KERN_ERR "Synaptics claims to have extended capabilities,"
++                             " but I'm not able to read them.");
++              } else
++                      priv->ext_cap = (cap[0]<<16) | (cap[1]<<8) | cap[2];
++      }
++      return 0;
+ }
+ /*
+  * Identify Touchpad
+  * See also the SYN_ID_* macros
+  */
+-static int synaptics_identify(struct psmouse *psmouse, unsigned long int *ident)
++static int synaptics_identify(struct psmouse *psmouse)
+ {
++      struct synaptics_data *priv = psmouse->private;
+       unsigned char id[3];
+       if (synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id))
+               return -1;
+-      *ident = (id[0]<<16) | (id[1]<<8) | id[2];
+-      if (SYN_ID_IS_SYNAPTICS(*ident))
++      priv->identity = (id[0]<<16) | (id[1]<<8) | id[2];
++      if (SYN_ID_IS_SYNAPTICS(priv->identity))
+               return 0;
+       return -1;
+ }
+-static int synaptics_enable_device(struct psmouse *psmouse)
+-{
+-      if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
+-              return -1;
+-      return 0;
+-}
+-
+ static void print_ident(struct synaptics_data *priv)
+ {
+       printk(KERN_INFO "Synaptics Touchpad, model: %ld\n", SYN_ID_MODEL(priv->identity));
+-      printk(KERN_INFO " Firware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity),
++      printk(KERN_INFO " Firmware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity),
+              SYN_ID_MINOR(priv->identity));
+-
+       if (SYN_MODEL_ROT180(priv->model_id))
+               printk(KERN_INFO " 180 degree mounted touchpad\n");
+       if (SYN_MODEL_PORTRAIT(priv->model_id))
+@@ -159,38 +167,135 @@
+       if (SYN_CAP_EXTENDED(priv->capabilities)) {
+               printk(KERN_INFO " Touchpad has extended capability bits\n");
+-              if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
++              if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
++                  SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) <= 8)
++                      printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n",
++                             (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)));
++              else if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
+                       printk(KERN_INFO " -> four buttons\n");
+               if (SYN_CAP_MULTIFINGER(priv->capabilities))
+                       printk(KERN_INFO " -> multifinger detection\n");
+               if (SYN_CAP_PALMDETECT(priv->capabilities))
+                       printk(KERN_INFO " -> palm detection\n");
++              if (SYN_CAP_PASS_THROUGH(priv->capabilities))
++                      printk(KERN_INFO " -> pass-through port\n");
+       }
+ }
+-static int query_hardware(struct psmouse *psmouse)
++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");
+-      if (synaptics_identify(psmouse, &priv->identity))
++      if (synaptics_identify(psmouse))
+               return -1;
+-      if (synaptics_model_id(psmouse, &priv->model_id))
++      if (synaptics_model_id(psmouse))
+               return -1;
+-      if (synaptics_capability(psmouse, &priv->capabilities))
++      if (synaptics_capability(psmouse))
+               return -1;
+-      if (synaptics_set_mode(psmouse, (SYN_BIT_ABSOLUTE_MODE |
+-                                       SYN_BIT_HIGH_RATE |
+-                                       SYN_BIT_DISABLE_GESTURE |
+-                                       SYN_BIT_W_MODE)))
++
++      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))
++              mode |= SYN_BIT_W_MODE;
++      if (synaptics_mode_cmd(psmouse, mode))
+               return -1;
+-      synaptics_enable_device(psmouse);
++      return 0;
++}
+-      print_ident(priv);
++/*****************************************************************************
++ *    Synaptics pass-through PS/2 port support
++ ****************************************************************************/
++static int synaptics_pt_open(struct serio *port)
++{
++      return 0;
++}
++
++static void synaptics_pt_close(struct serio *port)
++{
++}
++
++static int synaptics_pt_write(struct serio *port, unsigned char c)
++{
++      struct psmouse *parent = port->driver;
++      char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
++
++      if (synaptics_special_cmd(parent, c))
++              return -1;
++      if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
++              return -1;
++      return 0;
++}
++
++static inline int synaptics_is_pt_packet(unsigned char *buf)
++{
++      return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
++}
++
++static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet)
++{
++      struct psmouse *child = ptport->private;
++
++      if (child) {
++              if (child->state == PSMOUSE_ACTIVATED) {
++                      serio_interrupt(ptport, packet[1], 0, NULL);
++                      serio_interrupt(ptport, packet[4], 0, NULL);
++                      serio_interrupt(ptport, packet[5], 0, NULL);
++                      if (child->type >= PSMOUSE_GENPS)
++                              serio_interrupt(ptport, packet[2], 0, NULL);
++              } else if (child->state != PSMOUSE_IGNORE) {
++                      serio_interrupt(ptport, packet[1], 0, NULL);
++              }
++      }
++}
++
++int synaptics_pt_init(struct psmouse *psmouse)
++{
++      struct synaptics_data *priv = psmouse->private;
++      struct serio *port;
++      struct psmouse *child;
++
++      if (psmouse->type != PSMOUSE_SYNAPTICS)
++              return -1;
++      if (!SYN_CAP_EXTENDED(priv->capabilities))
++              return -1;
++      if (!SYN_CAP_PASS_THROUGH(priv->capabilities))
++              return -1;
++
++      priv->ptport = port = kmalloc(sizeof(struct serio), GFP_KERNEL);
++      if (!port) {
++              printk(KERN_ERR "synaptics: not enough memory to allocate serio port\n");
++              return -1;
++      }
++
++      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;
++
++      printk(KERN_INFO "serio: %s port at %s\n", port->name, psmouse->phys);
++      serio_register_slave_port(port);
++
++      /* 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;
+ }
+@@ -209,44 +314,75 @@
+       set_bit(axis, dev->absbit);
+ }
++static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
++{
++      /*
++       * The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
++       * which says that they should be valid regardless of the actual size of
++       * the sensor.
++       */
++      set_bit(EV_ABS, dev->evbit);
++      set_abs_params(dev, ABS_X, 1472, 5472, 0, 0);
++      set_abs_params(dev, ABS_Y, 1408, 4448, 0, 0);
++      set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
++
++      set_bit(EV_MSC, dev->evbit);
++      set_bit(MSC_GESTURE, dev->mscbit);
++
++      set_bit(EV_KEY, dev->evbit);
++      set_bit(BTN_LEFT, dev->keybit);
++      set_bit(BTN_RIGHT, dev->keybit);
++      set_bit(BTN_FORWARD, dev->keybit);
++      set_bit(BTN_BACK, dev->keybit);
++      if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
++              switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
++              default:
++                      /*
++                       * if nExtBtn is greater than 8 it should be considered
++                       * invalid and treated as 0
++                       */
++                      break;
++              case 8:
++                      set_bit(BTN_7, dev->keybit);
++                      set_bit(BTN_6, dev->keybit);
++              case 6:
++                      set_bit(BTN_5, dev->keybit);
++                      set_bit(BTN_4, dev->keybit);
++              case 4:
++                      set_bit(BTN_3, dev->keybit);
++                      set_bit(BTN_2, dev->keybit);
++              case 2:
++                      set_bit(BTN_1, dev->keybit);
++                      set_bit(BTN_0, dev->keybit);
++                      break;
++              }
++      }
++
++      clear_bit(EV_REL, dev->evbit);
++      clear_bit(REL_X, dev->relbit);
++      clear_bit(REL_Y, dev->relbit);
++}
++
+ 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));
+-      priv->inSync = 1;
+-
+-      if (query_hardware(psmouse)) {
++      if (synaptics_query_hardware(psmouse)) {
+               printk(KERN_ERR "Unable to query/initialize Synaptics hardware.\n");
+               goto init_fail;
+       }
+-      /*
+-       * The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
+-       * which says that they should be valid regardless of the actual size of
+-       * the senser.
+-       */
+-      set_bit(EV_ABS, psmouse->dev.evbit);
+-      set_abs_params(&psmouse->dev, ABS_X, 1472, 5472, 0, 0);
+-      set_abs_params(&psmouse->dev, ABS_Y, 1408, 4448, 0, 0);
+-      set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 255, 0, 0);
+-
+-      set_bit(EV_MSC, psmouse->dev.evbit);
+-      set_bit(MSC_GESTURE, psmouse->dev.mscbit);
+-
+-      set_bit(EV_KEY, psmouse->dev.evbit);
+-      set_bit(BTN_LEFT, psmouse->dev.keybit);
+-      set_bit(BTN_RIGHT, psmouse->dev.keybit);
+-      set_bit(BTN_FORWARD, psmouse->dev.keybit);
+-      set_bit(BTN_BACK, psmouse->dev.keybit);
+-
+-      clear_bit(EV_REL, psmouse->dev.evbit);
+-      clear_bit(REL_X, psmouse->dev.relbit);
+-      clear_bit(REL_Y, psmouse->dev.relbit);
++      print_ident(priv);
++      set_input_params(&psmouse->dev, priv);
+       return 0;
+@@ -259,42 +395,89 @@
+ {
+       struct synaptics_data *priv = psmouse->private;
+-      kfree(priv);
++      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(struct synaptics_data *priv, struct synaptics_hw_state *hw)
++static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
+ {
+-      unsigned char *buf = priv->proto_buf;
+-
+-      hw->x = (((buf[3] & 0x10) << 8) |
+-               ((buf[1] & 0x0f) << 8) |
+-               buf[4]);
+-      hw->y = (((buf[3] & 0x20) << 7) |
+-               ((buf[1] & 0xf0) << 4) |
+-               buf[5]);
+-
+-      hw->z = buf[2];
+-      hw->w = (((buf[0] & 0x30) >> 2) |
+-               ((buf[0] & 0x04) >> 1) |
+-               ((buf[3] & 0x04) >> 2));
+-
+-      hw->left  = (buf[0] & 0x01) ? 1 : 0;
+-      hw->right = (buf[0] & 0x2) ? 1 : 0;
+       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;
++
++      if (SYN_MODEL_NEWABS(priv->model_id)) {
++              hw->x = (((buf[3] & 0x10) << 8) |
++                       ((buf[1] & 0x0f) << 8) |
++                       buf[4]);
++              hw->y = (((buf[3] & 0x20) << 7) |
++                       ((buf[1] & 0xf0) << 4) |
++                       buf[5]);
++
++              hw->z = buf[2];
++              hw->w = (((buf[0] & 0x30) >> 2) |
++                       ((buf[0] & 0x04) >> 1) |
++                       ((buf[3] & 0x04) >> 2));
++
++              hw->left  = (buf[0] & 0x01) ? 1 : 0;
++              hw->right = (buf[0] & 0x02) ? 1 : 0;
++              if (SYN_CAP_EXTENDED(priv->capabilities) &&
++                  (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
++                      hw->up = ((buf[3] & 0x01)) ? 1 : 0;
++                      if (hw->left)
++                              hw->up = !hw->up;
++                      hw->down = ((buf[3] & 0x02)) ? 1 : 0;
++                      if (hw->right)
++                              hw->down = !hw->down;
++              }
++              if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
++                  ((buf[3] & 2) ? !hw->right : hw->right)) {
++                      switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
++                      default:
++                              /*
++                               * if nExtBtn is greater than 8 it should be
++                               * considered invalid and treated as 0
++                               */
++                              break;
++                      case 8:
++                              hw->b7 = ((buf[5] & 0x08)) ? 1 : 0;
++                              hw->b6 = ((buf[4] & 0x08)) ? 1 : 0;
++                      case 6:
++                              hw->b5 = ((buf[5] & 0x04)) ? 1 : 0;
++                              hw->b4 = ((buf[4] & 0x04)) ? 1 : 0;
++                      case 4:
++                              hw->b3 = ((buf[5] & 0x02)) ? 1 : 0;
++                              hw->b2 = ((buf[4] & 0x02)) ? 1 : 0;
++                      case 2:
++                              hw->b1 = ((buf[5] & 0x01)) ? 1 : 0;
++                              hw->b0 = ((buf[4] & 0x01)) ? 1 : 0;
++                      }
++              }
++      } else {
++              hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
++              hw->y = (((buf[4] & 0x1f) << 8) | buf[5]);
+-      if (SYN_CAP_EXTENDED(priv->capabilities) &&
+-          (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
+-              hw->up = ((buf[3] & 0x01)) ? 1 : 0;
+-              if (hw->left)
+-                      hw->up = !hw->up;
+-              hw->down = ((buf[3] & 0x02)) ? 1 : 0;
+-              if (hw->right)
+-                      hw->down = !hw->down;
++              hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
++              hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
++
++              hw->left  = (buf[0] & 0x01) ? 1 : 0;
++              hw->right = (buf[0] & 0x02) ? 1 : 0;
+       }
+ }
+@@ -307,7 +490,7 @@
+       struct synaptics_data *priv = psmouse->private;
+       struct synaptics_hw_state hw;
+-      synaptics_parse_hw_state(priv, &hw);
++      synaptics_parse_hw_state(psmouse->packet, priv, &hw);
+       if (hw.z > 0) {
+               int w_ok = 0;
+@@ -347,7 +530,28 @@
+       input_report_key(dev, BTN_RIGHT,   hw.right);
+       input_report_key(dev, BTN_FORWARD, hw.up);
+       input_report_key(dev, BTN_BACK,    hw.down);
+-
++      if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
++              switch(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
++              default:
++                      /*
++                       * if nExtBtn is greater than 8 it should be considered
++                       * invalid and treated as 0
++                       */
++                      break;
++              case 8:
++                      input_report_key(dev, BTN_7,       hw.b7);
++                      input_report_key(dev, BTN_6,       hw.b6);
++              case 6:
++                      input_report_key(dev, BTN_5,       hw.b5);
++                      input_report_key(dev, BTN_4,       hw.b4);
++              case 4:
++                      input_report_key(dev, BTN_3,       hw.b3);
++                      input_report_key(dev, BTN_2,       hw.b2);
++              case 2:
++                      input_report_key(dev, BTN_1,       hw.b1);
++                      input_report_key(dev, BTN_0,       hw.b0);
++                      break;
++              }
+       input_sync(dev);
+ }
+@@ -355,35 +559,60 @@
+ {
+       struct input_dev *dev = &psmouse->dev;
+       struct synaptics_data *priv = psmouse->private;
+-      unsigned char *pBuf = priv->proto_buf;
+-      unsigned char u = psmouse->packet[0];
++      unsigned char data = psmouse->packet[psmouse->pktcnt - 1];
++      int newabs = SYN_MODEL_NEWABS(priv->model_id);
+       input_regs(dev, regs);
+-      pBuf[priv->proto_buf_tail++] = u;
++      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 */
+-      /* check first byte */
+-      if ((priv->proto_buf_tail == 1) && ((u & 0xC8) != 0x80)) {
+-              priv->inSync = 0;
+-              priv->proto_buf_tail = 0;
+-              printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
+-              return;
+-      }
+-
+-      /* check 4th byte */
+-      if ((priv->proto_buf_tail == 4) && ((u & 0xc8) != 0xc0)) {
+-              priv->inSync = 0;
+-              priv->proto_buf_tail = 0;
+-              printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
+-              return;
+-      }
+-
+-      if (priv->proto_buf_tail >= 6) { /* Full packet received */
+-              if (!priv->inSync) {
+-                      priv->inSync = 1;
++              if (priv->out_of_sync) {
++                      priv->out_of_sync = 0;
+                       printk(KERN_NOTICE "Synaptics driver resynced.\n");
+               }
+-              synaptics_process_packet(psmouse);
+-              priv->proto_buf_tail = 0;
++
++              if (priv->ptport && synaptics_is_pt_packet(psmouse->packet))
++                      synaptics_pass_pt_packet(priv->ptport, 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);
+       }
+ }
+Index: linux-2.6.0-test5/drivers/input/mouse/synaptics.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/mouse/synaptics.h     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/mouse/synaptics.h  2003-09-27 11:38:21.476263496 +0800
+@@ -12,6 +12,7 @@
+ extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
+ extern int synaptics_init(struct psmouse *psmouse);
++extern int synaptics_pt_init(struct psmouse *psmouse);
+ extern void synaptics_disconnect(struct psmouse *psmouse);
+ /* synaptics queries */
+@@ -22,12 +23,14 @@
+ #define SYN_QUE_SERIAL_NUMBER_PREFIX  0x06
+ #define SYN_QUE_SERIAL_NUMBER_SUFFIX  0x07
+ #define SYN_QUE_RESOLUTION            0x08
++#define SYN_QUE_EXT_CAPAB             0x09
+ /* synatics modes */
+ #define SYN_BIT_ABSOLUTE_MODE         (1 << 7)
+ #define SYN_BIT_HIGH_RATE             (1 << 6)
+ #define SYN_BIT_SLEEP_MODE            (1 << 3)
+ #define SYN_BIT_DISABLE_GESTURE               (1 << 2)
++#define SYN_BIT_FOUR_BYTE_CLIENT      (1 << 1)
+ #define SYN_BIT_W_MODE                        (1 << 0)
+ /* synaptics model ID bits */
+@@ -42,11 +45,14 @@
+ /* synaptics capability bits */
+ #define SYN_CAP_EXTENDED(c)           ((c) & (1 << 23))
++#define SYN_CAP_PASS_THROUGH(c)               ((c) & (1 << 7))
+ #define SYN_CAP_SLEEP(c)              ((c) & (1 << 4))
+ #define SYN_CAP_FOUR_BUTTON(c)                ((c) & (1 << 3))
+ #define SYN_CAP_MULTIFINGER(c)                ((c) & (1 << 1))
+ #define SYN_CAP_PALMDETECT(c)         ((c) & (1 << 0))
+ #define SYN_CAP_VALID(c)              ((((c) & 0x00ff00) >> 8) == 0x47)
++#define SYN_EXT_CAP_REQUESTS(c)               ((((c) & 0x700000) >> 20) == 1)
++#define SYN_CAP_MULTI_BUTTON_NO(ec)   (((ec) & 0x00f000) >> 12)
+ /* synaptics modes query bits */
+ #define SYN_MODE_ABSOLUTE(m)          ((m) & (1 << 7))
+@@ -62,6 +68,10 @@
+ #define SYN_ID_MINOR(i)               (((i) >> 16) & 0xff)
+ #define SYN_ID_IS_SYNAPTICS(i)                ((((i) >> 8) & 0xff) == 0x47)
++/* synaptics special commands */
++#define SYN_PS_SET_MODE2              0x14
++#define SYN_PS_CLIENT_CMD             0x28
++
+ /*
+  * A structure to describe the state of the touchpad hardware (buttons and pad)
+  */
+@@ -75,21 +85,28 @@
+       int right;
+       int up;
+       int down;
++      int b0;
++      int b1;
++      int b2;
++      int b3;
++      int b4;
++      int b5;
++      int b6;
++      int b7;
+ };
+ struct synaptics_data {
+       /* Data read from the touchpad */
+       unsigned long int model_id;             /* Model-ID */
+       unsigned long int capabilities;         /* Capabilities */
++      unsigned long int ext_cap;              /* Extended Capabilities */
+       unsigned long int identity;             /* Identification */
+       /* Data for normal processing */
+-      unsigned char proto_buf[6];             /* Buffer for Packet */
+-      unsigned char last_byte;                /* last received byte */
+-      int inSync;                             /* Packets in sync */
+-      int proto_buf_tail;
+-
++      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 */
+Index: linux-2.6.0-test5/drivers/input/serio/ambakmi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/ambakmi.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/ambakmi.c    2003-09-27 11:38:21.478263192 +0800
+@@ -73,7 +73,7 @@
+       writeb(kmi->divisor, KMICLKDIV);
+       writeb(KMICR_EN, KMICR);
+-      ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->io.phys, kmi);
++      ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi);
+       if (ret) {
+               printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
+               writeb(0, KMICR);
+@@ -108,11 +108,11 @@
+       kmi->io.write   = amba_kmi_write;
+       kmi->io.open    = amba_kmi_open;
+       kmi->io.close   = amba_kmi_close;
+-      kmi->io.name    = dev->dev.name;
++      kmi->io.name    = dev->dev.bus_id;
+       kmi->io.phys    = dev->dev.bus_id;
+       kmi->io.driver  = kmi;
+-      kmi->res        = request_mem_region(dev->res.start, KMI_SIZE, kmi->io.phys);
++      kmi->res        = request_mem_region(dev->res.start, KMI_SIZE, "kmi-pl050");
+       if (!kmi->res) {
+               kfree(kmi);
+               return -EBUSY;
+@@ -147,14 +147,12 @@
+       return 0;
+ }
+-static int amba_kmi_resume(struct amba_device *dev, u32 level)
++static int amba_kmi_resume(struct amba_device *dev)
+ {
+       struct amba_kmi_port *kmi = amba_get_drvdata(dev);
+-      if (level == RESUME_ENABLE) {
+-              /* kick the serio layer to rescan this port */
+-              serio_rescan(&kmi->io);
+-      }
++      /* kick the serio layer to rescan this port */
++      serio_rescan(&kmi->io);
+       return 0;
+ }
+Index: linux-2.6.0-test5/drivers/input/serio/i8042.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/i8042.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/i8042.c      2003-09-27 11:38:21.485262128 +0800
+@@ -62,6 +62,7 @@
+ static unsigned char i8042_last_release;
+ static unsigned char i8042_mux_open;
+ struct timer_list i8042_timer;
++unsigned char i8042_history[16];
+ /*
+  * Shared IRQ's require a device pointer, but this driver doesn't support
+@@ -334,6 +335,14 @@
+ static char i8042_mux_short[4][16];
+ static char i8042_mux_phys[4][32];
++void dump_i8042_history(void) {
++      int i;
++      printk(KERN_WARNING "i8042 history: ");
++      for (i=0; i<sizeof(i8042_history); i++)
++              printk("%02x ", i8042_history[i]);
++      printk("\n");
++}
++
+ /*
+  * i8042_interrupt() is the most important function in this driver -
+  * it handles the interrupts from the i8042, and sends incoming bytes
+@@ -405,6 +414,8 @@
+                       continue;
+               }
++              memmove(i8042_history, &i8042_history[1], sizeof(i8042_history)-1);
++              i8042_history[sizeof(i8042_history)-1] = data;
+               if (data > 0x7f) {
+                       unsigned char index = (data & 0x7f) | (i8042_last_e0 << 7);
+                       /* work around hardware that doubles key releases */
+Index: linux-2.6.0-test5/drivers/input/serio/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/Kconfig      2003-09-27 11:38:21.487261824 +0800
+@@ -2,7 +2,7 @@
+ # Input core configuration
+ #
+ config SERIO
+-      tristate "Serial i/o support (needed for keyboard and mouse)"
++      tristate "Serial i/o support" if EMBEDDED || !X86
+       default y
+       ---help---
+         Say Yes here if you have any input device that uses serial I/O to
+@@ -21,7 +21,7 @@
+ config SERIO_I8042
+       tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
+       default y
+-      depends on SERIO
++      select SERIO
+       ---help---
+         i8042 is the chip over which the standard AT keyboard and PS/2
+         mouse are connected to the computer. If you use these devices,
+Index: linux-2.6.0-test5/drivers/input/serio/serio.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/serio/serio.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/serio/serio.c      2003-09-27 11:38:21.490261368 +0800
+@@ -49,7 +49,9 @@
+ EXPORT_SYMBOL(serio_interrupt);
+ EXPORT_SYMBOL(serio_register_port);
++EXPORT_SYMBOL(serio_register_slave_port);
+ EXPORT_SYMBOL(serio_unregister_port);
++EXPORT_SYMBOL(serio_unregister_slave_port);
+ EXPORT_SYMBOL(serio_register_device);
+ EXPORT_SYMBOL(serio_unregister_device);
+ EXPORT_SYMBOL(serio_open);
+@@ -166,6 +168,17 @@
+       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
++ * connect() function.
++ */
++void serio_register_slave_port(struct serio *serio)
++{
++      list_add_tail(&serio->node, &serio_list);
++      serio_find_dev(serio);
++}
++
+ void serio_unregister_port(struct serio *serio)
+ {
+       down(&serio_sem);
+@@ -175,6 +188,18 @@
+       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
++ * disconnect() function.
++ */
++void serio_unregister_slave_port(struct serio *serio)
++{
++      list_del_init(&serio->node);
++      if (serio->dev && serio->dev->disconnect)
++              serio->dev->disconnect(serio);
++}
++
+ void serio_register_device(struct serio_dev *dev)
+ {
+       struct serio *serio;
+@@ -204,9 +229,11 @@
+ /* called from serio_dev->connect/disconnect methods under serio_sem */
+ int serio_open(struct serio *serio, struct serio_dev *dev)
+ {
+-      if (serio->open(serio))
+-              return -1;
+       serio->dev = dev;
++      if (serio->open(serio)) {
++              serio->dev = NULL;
++              return -1;
++      }
+       return 0;
+ }
+@@ -221,8 +248,7 @@
+ {
+       int pid;
+-      pid = kernel_thread(serio_thread, NULL,
+-              CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL);
+       if (!pid) {
+               printk(KERN_WARNING "serio: Failed to start kseriod\n");
+Index: linux-2.6.0-test5/drivers/input/touchscreen/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/input/touchscreen/Kconfig   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/input/touchscreen/Kconfig        2003-09-27 11:38:21.491261216 +0800
+@@ -12,7 +12,8 @@
+ config TOUCHSCREEN_BITSY
+       tristate "Compaq iPAQ H3600 (Bitsy) touchscreen input driver"
+-      depends on SA1100_BITSY && INPUT && INPUT_TOUCHSCREEN && SERIO
++      depends on SA1100_BITSY && INPUT && INPUT_TOUCHSCREEN
++      select SERIO
+       help
+         Say Y here if you have the h3600 (Bitsy) touchscreen.
+@@ -25,7 +26,8 @@
+ config TOUCHSCREEN_GUNZE
+       tristate "Gunze AHL-51S touchscreen"
+-      depends on INPUT && INPUT_TOUCHSCREEN && SERIO
++      depends on INPUT && INPUT_TOUCHSCREEN
++      select SERIO
+       help
+         Say Y here if you have the Gunze AHL-51 touchscreen connected to
+         your system.
+Index: linux-2.6.0-test5/drivers/isdn/hardware/avm/avm_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/avm/avm_cs.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/avm/avm_cs.c       2003-09-27 11:38:21.496260456 +0800
+@@ -431,15 +431,6 @@
+ static void avmcs_release(dev_link_t *link)
+ {
+-    /*
+-       If the device is currently in use, we won't release until it
+-       is actually closed.
+-    */
+-    if (link->open) {
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-
+     b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
+     /* Unlink the device chain */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/capifunc.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.c   2003-09-27 11:38:21.506258936 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * ISDN interface module for Eicon active cards DIVA.
+  * CAPI Interface common functions
+  * 
+- * 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.
+@@ -25,10 +25,11 @@
+ DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;
+ APPL *application = (APPL *) NULL;
+ byte max_appl = MAX_APPL;
++byte max_adapter = 0;
+ static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL;
+ byte UnMapController(byte);
+-char DRIVERRELEASE[32];
++char DRIVERRELEASE_CAPI[32];
+ extern void AutomaticLaw(DIVA_CAPI_ADAPTER *);
+ extern void callback(ENTITY *);
+@@ -45,7 +46,6 @@
+ static void DIRequest(ENTITY * e);
+ static DESCRIPTOR MAdapter;
+ static DESCRIPTOR DAdapter;
+-byte max_adapter = 0;
+ static byte ControllerMap[MAX_DESCRIPTORS + 1];
+@@ -59,16 +59,14 @@
+ extern void DIVA_DIDD_Read(DESCRIPTOR *, int);
+-static void no_printf(unsigned char *, ...);
+-
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ /*
+  * debug
+  */
++static void no_printf(unsigned char *, ...);
+ #include "debuglib.c"
+ void xlog(char *x, ...)
+ {
++#ifndef DIVA_NO_DEBUGLIB
+       va_list ap;
+       if (myDriverDebugHandle.dbgMask & DL_XLOG) {
+               va_start(ap, x);
+@@ -81,6 +79,7 @@
+               }
+               va_end(ap);
+       }
++#endif
+ }
+ /*
+@@ -162,13 +161,14 @@
+               p = cards;
+               while (p) {
+                       if (p->Id == num)
+-                              goto next_id;
++                              break;
+                       p = p->next;
+               }
++              if(!p) {
+               diva_os_leave_spin_lock(&ll_lock, &old_irql,
+                                       "find free id");
+               return (num);
+-            next_id:
++              }
+       }
+       diva_os_leave_spin_lock(&ll_lock, &old_irql, "find free id");
+       return (999);
+@@ -315,10 +315,11 @@
+       /* if DATA_B3_IND, copy data too */
+       if (command == _DATA_B3_I) {
+-              dword data = READ_DWORD(((byte *) & msg.info.data_b3_ind.Data));
++              dword data = READ_DWORD(&msg.info.data_b3_ind.Data);
+               memcpy(write + length, (void *) data, dlength);
+       }
++#ifndef DIVA_NO_DEBUGLIB
+       if (myDriverDebugHandle.dbgMask & DL_XLOG) {
+               switch (command) {
+               default:
+@@ -332,8 +333,8 @@
+                       if (myDriverDebugHandle.dbgMask & DL_BLK) {
+                               xlog("\x00\x02", &msg, 0x81, length);
+                               for (i = 0; i < dlength; i += 256) {
+-                                DBG_BLK((((char *) msg.info.data_b3_ind.
+-                                       Data) + i, ((dlength - i) < 256) ? (dlength - i) : 256))
++                                DBG_BLK((((char *) READ_DWORD(&msg.info.data_b3_ind.Data)) + i,
++                                      ((dlength - i) < 256) ? (dlength - i) : 256))
+                                 if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
+                                         break; /* not more if not explicitely requested */
+                               }
+@@ -341,6 +342,7 @@
+                       break;
+               }
+       }
++#endif
+       /* find the card structure for this controller */
+       if (!(card = find_card_by_ctrl(write[8] & 0x7f))) {
+@@ -719,7 +721,7 @@
+       }
+       /* profile information */
+-      ctrl->profile.nbchannel = card->d.channels;
++      WRITE_WORD(&ctrl->profile.nbchannel, card->d.channels);
+       ctrl->profile.goptions = a->profile.Global_Options;
+       ctrl->profile.support1 = a->profile.B1_Protocols;
+       ctrl->profile.support2 = a->profile.B2_Protocols;
+@@ -745,17 +747,20 @@
+ {
+       APPL *this;
+       word bnum, xnum;
+-      int i = 0, j = 0;
++      int i = 0;
++      unsigned char *p;
+       void *DataNCCI, *DataFlags, *ReceiveBuffer, *xbuffer_used;
+       void **xbuffer_ptr, **xbuffer_internal;
+       diva_os_spin_lock_magic_t old_irql;
++      unsigned int mem_len;
++
+       if (diva_os_in_irq()) {
+               DBG_ERR(("CAPI_REGISTER - in irq context !"))
+               return;
+       }
+-      DBG_TRC(("application register"))
++      DBG_TRC(("application register Id=%d", appl))
+       if (appl > MAX_APPL) {
+               DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))
+@@ -775,97 +780,47 @@
+               return; /* appl already registered */
+       }
+-      if (!try_module_get(ctrl->owner)) {
+-              printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
+-              return;
+-      }
+-
+       /* alloc memory */
+       bnum = rp->level3cnt * rp->datablkcnt;
+       xnum = rp->level3cnt * MAX_DATA_B3;
+-      if (!(DataNCCI = diva_os_malloc(0, bnum * sizeof(word)))) {
+-              DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+-              module_put(ctrl->owner);
+-              return;
+-      }
+-      memset(DataNCCI, 0, bnum * sizeof(word));
+-
+-      if (!(DataFlags = diva_os_malloc(0, bnum * sizeof(word)))) {
+-              DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+-              diva_os_free(0, DataNCCI);
+-              module_put(ctrl->owner);
+-              return;
+-      }
+-      memset(DataFlags, 0, bnum * sizeof(word));
+-
+-      if (!(ReceiveBuffer = diva_os_malloc(0, bnum * rp->datablklen))) {
+-              DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+-              diva_os_free(0, DataNCCI);
+-              diva_os_free(0, DataFlags);
+-              module_put(ctrl->owner);
+-              return;
+-      }
+-      memset(ReceiveBuffer, 0, bnum * rp->datablklen);
+-
+-      if (!(xbuffer_used = (byte *) diva_os_malloc(0, xnum))) {
+-              DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+-              diva_os_free(0, DataNCCI);
+-              diva_os_free(0, DataFlags);
+-              diva_os_free(0, ReceiveBuffer);
+-              module_put(ctrl->owner);
+-              return;
+-      }
+-      memset(xbuffer_used, 0, xnum);
++      mem_len  = bnum * sizeof(word);         /* DataNCCI */
++      mem_len += bnum * sizeof(word);         /* DataFlags */
++      mem_len += bnum * rp->datablklen;       /* ReceiveBuffer */
++      mem_len += xnum;                        /* xbuffer_used */
++      mem_len += xnum * sizeof(void *);       /* xbuffer_ptr */
++      mem_len += xnum * sizeof(void *);       /* xbuffer_internal */
++      mem_len += xnum * rp->datablklen;       /* xbuffer_ptr[xnum] */
+-      if (!(xbuffer_ptr = (void **) diva_os_malloc(0, xnum * sizeof(void *)))) {
++      if (!(p = diva_os_malloc(0, mem_len))) {
+               DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+-              diva_os_free(0, DataNCCI);
+-              diva_os_free(0, DataFlags);
+-              diva_os_free(0, ReceiveBuffer);
+-              diva_os_free(0, xbuffer_used);
+-              module_put(ctrl->owner);
+               return;
+       }
+-      memset(xbuffer_ptr, 0, xnum * sizeof(void *));
+-
+-      if (!(xbuffer_internal = (void **) diva_os_malloc(0, xnum * sizeof(void *)))) {
+-              DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+-              diva_os_free(0, DataNCCI);
+-              diva_os_free(0, DataFlags);
+-              diva_os_free(0, ReceiveBuffer);
+-              diva_os_free(0, xbuffer_used);
+-              diva_os_free(0, xbuffer_ptr);
+-              module_put(ctrl->owner);
+-              return;
+-      }
+-      memset(xbuffer_internal, 0, xnum * sizeof(void *));
++      memset(p, 0, mem_len);
++      DataNCCI = (void *)p;
++      p += bnum * sizeof(word);
++      DataFlags = (void *)p;
++      p += bnum * sizeof(word);
++      ReceiveBuffer = (void *)p;
++      p += bnum * rp->datablklen;
++      xbuffer_used = (void *)p;
++      p += xnum;
++      xbuffer_ptr = (void **)p;
++      p += xnum * sizeof(void *);
++      xbuffer_internal = (void **)p;
++      p += xnum * sizeof(void *);
+       for (i = 0; i < xnum; i++) {
+-              xbuffer_ptr[i] = diva_os_malloc(0, rp->datablklen);
+-              if (!xbuffer_ptr[i]) {
+-                      DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+-                      if (i) {
+-                              for (j = 0; j < i; j++)
+-                                      if (xbuffer_ptr[j])
+-                                              diva_os_free(0, xbuffer_ptr [j]);
+-                      }
+-                      diva_os_free(0, DataNCCI);
+-                      diva_os_free(0, DataFlags);
+-                      diva_os_free(0, ReceiveBuffer);
+-                      diva_os_free(0, xbuffer_used);
+-                      diva_os_free(0, xbuffer_ptr);
+-                      diva_os_free(0, xbuffer_internal);
+-                      module_put(ctrl->owner);
+-                      return;
+-              }
++              xbuffer_ptr[i] = (void *)p;
++              p += rp->datablklen;
+       }
+       DBG_LOG(("CAPI_REGISTER - Id = %d", appl))
+       DBG_LOG(("  MaxLogicalConnections = %d", rp->level3cnt))
+       DBG_LOG(("  MaxBDataBuffers       = %d", rp->datablkcnt))
+       DBG_LOG(("  MaxBDataLength        = %d", rp->datablklen))
++      DBG_LOG(("  Allocated Memory      = %d", mem_len))
+       /* initialize application data */
+       diva_os_enter_spin_lock(&api_lock, &old_irql, "register_appl");
+@@ -875,9 +830,6 @@
+       this->Id = appl;
+-      /* We do not need a list */
+-      /* InitializeListHead(&this->s_function); */
+-
+       for (i = 0; i < max_adapter; i++) {
+               adapter[i].CIP_Mask[appl - 1] = 0;
+       }
+@@ -911,41 +863,24 @@
+ {
+       diva_os_spin_lock_magic_t old_irql;
+       APPL *this = &application[appl - 1];
+-      int i = 0;
++
++      DBG_TRC(("application %d(%d) cleanup", this->Id, appl))
+       if (diva_os_in_irq()) {
+               DBG_ERR(("CAPI_RELEASE - in irq context !"))
+               return;
+       }
+-      if (this->Id) {
+-              DBG_TRC(("application %d cleanup", this->Id))
+-      }
+       diva_os_enter_spin_lock(&api_lock, &old_irql, "release_appl");
+       if (this->Id) {
+               CapiRelease(this->Id);
+               if (this->DataNCCI)
+                       diva_os_free(0, this->DataNCCI);
+-              if (this->DataFlags)
+-                      diva_os_free(0, this->DataFlags);
+-              if (this->ReceiveBuffer)
+-                      diva_os_free(0, this->ReceiveBuffer);
+-              if (this->xbuffer_ptr) {
+-                      for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI); i++) {
+-                              if (this->xbuffer_ptr[i])
+-                                      diva_os_free(0, this->xbuffer_ptr[i]);
+-                      }
+-                      diva_os_free(0, this->xbuffer_ptr);
+-              }
+-              if (this->xbuffer_internal)
+-                      diva_os_free(0, this->xbuffer_internal);
+-              if (this->xbuffer_used)
+-                      diva_os_free(0, this->xbuffer_used);
++              this->DataNCCI = NULL;
+               this->Id = 0;
+       }
+       diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl");
+-      module_put(ctrl->owner);
+ }
+ /*
+@@ -954,7 +889,7 @@
+ static u16 diva_send_message(struct capi_ctr *ctrl,
+                            diva_os_message_buffer_s * dmb)
+ {
+-      int i = 0, j = 0;
++      int i = 0;
+       word ret = 0;
+       diva_os_spin_lock_magic_t old_irql;
+       CAPI_MSG *msg = (CAPI_MSG *) DIVA_MESSAGE_BUFFER_DATA(dmb);
+@@ -971,6 +906,10 @@
+       }
+       DBG_PRV1(("Write - appl = %d, cmd = 0x%x", this->Id, command))
++      if (!this->Id) {
++              return CAPI_ILLAPPNR;
++      }
++
+       /* patch controller number */
+       msg->header.controller = ControllerMap[card->Id]
+           | (msg->header.controller & 0x80);  /* preserve external controller bit */
+@@ -983,13 +922,17 @@
+               break;
+       case _DATA_B3_I | RESPONSE:
++#ifndef DIVA_NO_DEBUGLIB
+               if (myDriverDebugHandle.dbgMask & DL_BLK)
+                       xlog("\x00\x02", msg, 0x80, clength);
++#endif
+               break;
+       case _DATA_B3_R:
++#ifndef DIVA_NO_DEBUGLIB
+               if (myDriverDebugHandle.dbgMask & DL_BLK)
+                       xlog("\x00\x02", msg, 0x80, clength);
++#endif
+               if (clength == 24)
+                       clength = 22;   /* workaround for PPcom bug */
+@@ -1016,8 +959,10 @@
+               memcpy(this->xbuffer_ptr[i], &((__u8 *) msg)[clength],
+                      READ_WORD(&msg->info.data_b3_req.Data_Length));
++#ifndef DIVA_NO_DEBUGLIB
+               if ((myDriverDebugHandle.dbgMask & DL_BLK)
+                   && (myDriverDebugHandle.dbgMask & DL_XLOG)) {
++                      int j;
+                       for (j = 0; j <
+                            READ_WORD(&msg->info.data_b3_req.Data_Length);
+                            j += 256) {
+@@ -1028,6 +973,7 @@
+                                       break;  /* not more if not explicitely requested */
+                       }
+               }
++#endif
+               break;
+       }
+@@ -1091,7 +1037,7 @@
+               } else {
+                       memcpy(&MAdapter, adapter, sizeof(MAdapter));
+                       dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+-                      DbgRegister("CAPI20", DRIVERRELEASE, DBG_DEFAULT);
++                      DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
+               }
+       } else if ((adapter->type > 0) && (adapter->type < 16)) {       /* IDI Adapter */
+               if (removal) {
+@@ -1119,7 +1065,7 @@
+               if (DIDD_Table[x].type == IDI_DIMAINT) {        /* MAINT found */
+                       memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
+                       dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+-                      DbgRegister("CAPI20", DRIVERRELEASE, DBG_DEFAULT);
++                      DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
+                       break;
+               }
+       }
+@@ -1130,7 +1076,7 @@
+                       req.didd_notify.e.Req = 0;
+                       req.didd_notify.e.Rc =
+                           IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+-                      req.didd_notify.info.callback = didd_callback;
++                      req.didd_notify.info.callback = (void *)didd_callback;
+                       req.didd_notify.info.context = 0;
+                       DAdapter.request((ENTITY *) & req);
+                       if (req.didd_notify.e.Rc != 0xff) {
+@@ -1260,4 +1206,7 @@
+       divacapi_remove_cards();
+       remove_main_structs();
++
++      diva_os_destroy_spin_lock(&api_lock, "capifunc");
++      diva_os_destroy_spin_lock(&ll_lock, "capifunc");
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/capifunc.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/capifunc.h   2003-09-27 11:38:21.507258784 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * ISDN interface module for Eicon active cards DIVA.
+  * CAPI Interface common functions
+  * 
+- * 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.
+@@ -21,7 +21,7 @@
+ #define M_COMPANY "Eicon Networks"
+-extern char DRIVERRELEASE[];
++extern char DRIVERRELEASE_CAPI[];
+ typedef struct _diva_card {
+       int Id;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/capimain.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/capimain.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/capimain.c   2003-09-27 11:38:21.509258480 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * ISDN interface module for Eicon active cards DIVA.
+  * CAPI Interface
+  * 
+- * 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.
+@@ -15,10 +15,7 @@
+ #include <linux/init.h>
+ #include <asm/uaccess.h>
+ #include <linux/smp_lock.h>
+-#include <linux/vmalloc.h>
+-#include <linux/sched.h>
+ #include <linux/skbuff.h>
+-#include <linux/delay.h>
+ #include "os_capi.h"
+@@ -29,7 +26,7 @@
+ #include "cp_vers.h"
+ #include "capifunc.h"
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+ static char *DRIVERNAME =
+     "Eicon DIVA - CAPI Interface driver (http://www.melware.net)";
+ static char *DRIVERLNAME = "divacapi";
+@@ -57,47 +54,6 @@
+ }
+ /*
+- * sleep for some milliseconds
+- */
+-void diva_os_sleep(dword mSec)
+-{
+-      unsigned long timeout = HZ * mSec / 1000 + 1;
+-
+-      set_current_state(TASK_UNINTERRUPTIBLE);
+-      schedule_timeout(timeout);
+-}
+-
+-/*
+- * wait for some milliseconds
+- */
+-void diva_os_wait(dword mSec)
+-{
+-      mdelay(mSec);
+-}
+-
+-/*
+- * alloc memory
+- */
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+-      void *ret = NULL;
+-      if (size) {
+-              ret = (void *) vmalloc((unsigned int) size);
+-      }
+-      return (ret);
+-}
+-
+-/*
+- * free memory
+- */
+-void diva_os_free(unsigned long unused, void *ptr)
+-{
+-      if (ptr) {
+-              vfree(ptr);
+-      }
+-}
+-
+-/*
+  * alloc a message buffer
+  */
+ diva_os_message_buffer_s *diva_os_alloc_message_buffer(unsigned long size,
+@@ -160,11 +116,11 @@
+       char tmprev[32];
+       int ret = 0;
+-      sprintf(DRIVERRELEASE, "%d.%d%s", DRRELMAJOR, DRRELMINOR,
++      sprintf(DRIVERRELEASE_CAPI, "%d.%d%s", DRRELMAJOR, DRRELMINOR,
+               DRRELEXTRA);
+       printk(KERN_INFO "%s\n", DRIVERNAME);
+-      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE);
++      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE_CAPI);
+       strcpy(tmprev, main_revision);
+       printk("%s  Build: %s(%s)\n", getrev(tmprev),
+              diva_capi_common_code_build, DIVA_BUILD);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/dadapter.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/dadapter.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/dadapter.c   2003-09-27 11:38:21.513257872 +0800
+@@ -49,8 +49,21 @@
+   Shadow IDI_DIMAINT
+   and 'shadow' debug stuff
+    -------------------------------------------------------------------------- */
+-static void no_printf (unsigned char * format, ...) { }
+-DIVA_DI_PRINTF dprintf = no_printf;
++static void no_printf (unsigned char * format, ...)
++{
++#ifdef EBUG
++      va_list ap;
++      va_start (ap, format);
++      debug((format, ap));
++      va_end (ap);
++#endif
++}
++
++/* -------------------------------------------------------------------------
++  Portable debug Library
++  ------------------------------------------------------------------------- */
++#include "debuglib.c"
++  
+ static DESCRIPTOR  MAdapter =  {IDI_DIMAINT, /* Adapter Type */
+                 0x00,     /* Channels */
+                 0x0000,    /* Features */
+@@ -86,6 +99,7 @@
+   Should be called as last step, if driver does unload
+   -------------------------------------------------------------------------- */
+ void diva_didd_load_time_finit (void) {
++ diva_os_destroy_spin_lock (&didd_spin, "didd");
+ }
+ /* --------------------------------------------------------------------------
+   Called in order to register new adapter in adapter array
+@@ -349,7 +363,4 @@
+                    int length) {
+  diva_didd_read_adapter_array (buffer, length);
+ }
+-/* -------------------------------------------------------------------------
+-  Portable debug Library
+-  ------------------------------------------------------------------------- */
+-#include "debuglib.c"
++
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/debug.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/debug.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/debug.c      2003-09-27 11:38:21.529255440 +0800
+@@ -2,7 +2,6 @@
+ #include "pc.h"
+ #include "di_defs.h"
+ #include "debug_if.h"
+-#include "linux/kernel.h"
+ #include "divasync.h"
+ #include "kst_ifc.h"
+ #include "maintidi.h"
+@@ -96,9 +95,9 @@
+ static byte *queueAllocMsg (MSG_QUEUE *Q, word size) {
+       /* Allocate 'size' bytes at tail of queue which will be filled later
+-   * directly whith callers own message header info and/or message.
++   * directly with callers own message header info and/or message.
+    * An 'alloced' message is marked incomplete by oring the 'Size' field
+-   * whith MSG_INCOMPLETE.
++   * with MSG_INCOMPLETE.
+    * This must be reset via queueCompleteMsg() after the message is filled.
+    * As long as a message is marked incomplete queuePeekMsg() will return
+    * a 'queue empty' condition when it reaches such a message.  */
+@@ -160,7 +159,7 @@
+ }
+ static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) {
+-      /* Show the first valid message in queue BUT DONT free the message.
++      /* Show the first valid message in queue BUT DON'T free the message.
+    * After looking on the message contents it can be freed queueFreeMsg()
+    * or simply remain in message queue.  */
+@@ -195,7 +194,7 @@
+     length:  length of the message queue
+     do_init: perfor queue reset
+-    return:  zero on sucess, -1 on error
++    return:  zero on success, -1 on error
+   */
+ int diva_maint_init (byte* base, unsigned long length, int do_init) {
+   if (dbg_queue || (!base) || (length < (4096*4))) {
+@@ -296,7 +295,7 @@
+ /*
+   INTERFACE:
+-    Lock messafe queue and return the pointer to the first
++    Lock message queue and return the pointer to the first
+     entry.
+   */
+ diva_dbg_entry_head_t* diva_maint_get_message (word* size,
+@@ -725,12 +724,12 @@
+   if (clients[id].hDbg) {
+     *p++ = 1;
+-    *p++ = (byte)clients[id].sec; /* save secounds */
++    *p++ = (byte)clients[id].sec; /* save seconds */
+     *p++ = (byte)(clients[id].sec >>  8);
+     *p++ = (byte)(clients[id].sec >> 16);
+     *p++ = (byte)(clients[id].sec >> 24);
+-    *p++ = (byte)(clients[id].usec/1000); /* save msecounds */
++    *p++ = (byte)(clients[id].usec/1000); /* save mseconds */
+     *p++ = (byte)((clients[id].usec/1000) >>  8);
+     *p++ = (byte)((clients[id].usec/1000) >> 16);
+     *p++ = (byte)((clients[id].usec/1000) >> 24);
+@@ -1079,7 +1078,7 @@
+ }
+ /* ----------------------------------------------------------------
+-     Low level interface for management interace client
++     Low level interface for management interface client
+    ---------------------------------------------------------------- */
+ /*
+   Return handle to client structure
+@@ -1462,7 +1461,7 @@
+     case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:
+       if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {
+         /*
+-          Incoming Statistices
++          Incoming Statistics
+           */
+         if (channel->pInterfaceStat->inc.Calls) {
+           diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
+@@ -1498,7 +1497,7 @@
+         }
+         
+         /*
+-          Outgoing Statistices
++          Outgoing Statistics
+           */
+         if (channel->pInterfaceStat->outg.Calls) {
+           diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/debuglib.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.c   2003-09-27 11:38:21.532254984 +0800
+@@ -23,8 +23,15 @@
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  */
++
+ #include "debuglib.h"
++
++#ifdef DIVA_NO_DEBUGLIB
++static DIVA_DI_PRINTF dprintf;
++#else /* DIVA_NO_DEBUGLIB */
++ 
+ _DbgHandle_ myDriverDebugHandle = { 0 /*!Registered*/, DBG_HANDLE_VERSION };
++DIVA_DI_PRINTF dprintf = no_printf;
+ /*****************************************************************************/
+ #define DBG_FUNC(name) \
+ void  \
+@@ -146,3 +153,4 @@
+  va_end(ap);
+ }
+ /*****************************************************************************/
++#endif /* DIVA_NO_DEBUGLIB */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/debuglib.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/debuglib.h   2003-09-27 11:38:21.535254528 +0800
+@@ -101,6 +101,34 @@
+  * with _KERNEL_DBG_PRINT_
+  */
+ #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 DBG_TEST(func,args) do { } while(0);
++#define DBG_EVL_ID(args) do { } while(0);
++
++#else /* DIVA_NO_DEBUGLIB */
+ /*
+  * define low level macros for formatted & raw debugging
+  */
+@@ -156,6 +184,9 @@
+ { if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL ) \
+  { myDbgPrint_EVL args ; \
+ } }
++
++#endif /* DIVA_NO_DEBUGLIB */
++
+ #define DBG_LOG(args)  DBG_TEST(LOG, args)
+ #define DBG_FTL(args)  DBG_TEST(FTL, args)
+ #define DBG_ERR(args)  DBG_TEST(ERR, args)
+@@ -182,9 +213,16 @@
+ /*
+  * prototypes for debug register/deregister functions in "debuglib.c"
+  */
++#ifdef DIVA_NO_DEBUGLIB
++#define DbgRegister(name,tag, mask) do { } while(0)
++#define DbgDeregister() do { } while(0)
++#define DbgSetLevel(mask) do { } while(0)
++#else
++extern DIVA_DI_PRINTF dprintf;
+ extern int  DbgRegister (char *drvName, char *drvTag, unsigned long dbgMask) ;
+ extern void DbgDeregister (void) ;
+ extern void DbgSetLevel (unsigned long dbgMask) ;
++#endif
+ /*
+  * driver internal structure for debug handling;
+  * in client drivers this structure is maintained in "debuglib.c",
+@@ -274,9 +312,11 @@
+         } CardTrace;
+     } u1;     
+ } _DbgExtendedInfo_;
++#ifndef DIVA_NO_DEBUGLIB
+ /* -------------------------------------------------------------
+     Function used for xlog-style debug
+    ------------------------------------------------------------- */
+ #define XDI_USE_XLOG 1
+ void  xdi_dbg_xlog (char* x, ...);
++#endif /* DIVA_NO_DEBUGLIB */
+ #endif /* __DEBUGLIB_H__ */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/di.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/di.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/di.c 2003-09-27 11:38:21.545253008 +0800
+@@ -112,16 +112,14 @@
+ #ifdef USE_EXTENDED_DEBUGS
+     if ( !this )
+     {
+-      ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+       DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
+-               xdi_xlog_sec++, (int)io->ANum))
++               xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
+       e_no = look_req(a) ;
+       ReadyCount-- ;
+       continue ;
+     }
+     {
+-      ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+-      DBG_TRC((">A%d Id=0x%x Req=0x%x", io->ANum, this->Id, this->Req))
++      DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
+     }
+ #else
+     dbug(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
+@@ -563,8 +561,7 @@
+   int cancel_rc;
+ #ifdef USE_EXTENDED_DEBUGS
+   {
+-    ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+-    DBG_TRC(("<A%d Id=0x%x Rc=0x%x", io->ANum, Id, Rc))
++    DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
+   }
+ #else
+   dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
+@@ -767,8 +764,7 @@
+   byte* cma = 0;
+ #ifdef USE_EXTENDED_DEBUGS
+   {
+-    ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
+-    DBG_TRC(("<A%d Id=0x%x Ind=0x%x", io->ANum, Id, Ind))
++    DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
+   }
+ #else
+   dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch));
+@@ -956,10 +952,10 @@
+                                byte Id, byte Ch, byte Rc, byte cb, byte type) {
+ #if defined(XDI_USE_XLOG)
+   word LogInfo[4];
+-  LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
+-  LogInfo[1] = (word)Id | (word)(Ch << 8);
+-  LogInfo[2] = (word)Rc | (word)(type << 8);
+-  LogInfo[3] = cb;
++  WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
++  WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
++  WRITE_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
++  WRITE_WORD(&LogInfo[3], cb);
+   xdi_xlog ((byte*)&LogInfo[0], 221, sizeof(LogInfo));
+ #endif
+ }
+@@ -980,9 +976,9 @@
+                               byte Ch, byte Req, byte type) {
+ #if defined(XDI_USE_XLOG)
+   word LogInfo[3];
+-  LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
+-  LogInfo[1] = (word)Id | (word)(Ch << 8);
+-  LogInfo[2] = (word)Req | (word)(type << 8);
++  WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
++  WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
++  WRITE_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
+   xdi_xlog ((byte*)&LogInfo[0], 220, sizeof(LogInfo));
+ #endif
+ }
+@@ -1024,10 +1020,10 @@
+                           byte type) {
+ #if defined(XDI_USE_XLOG)
+   word LogInfo[4];
+-  LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
+-  LogInfo[1] = (word)Id | (word)(Ch << 8);
+-  LogInfo[2] = (word)Ind | (word)(type << 8);
+-  LogInfo[3] = (word)rnr | (word)(rnr_valid << 8);
++  WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
++  WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
++  WRITE_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
++  WRITE_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
+   xdi_xlog ((byte*)&LogInfo[0], 222, sizeof(LogInfo));
+ #endif
+ }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diddfunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diddfunc.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diddfunc.c   2003-09-27 11:38:21.547252704 +0800
+@@ -1,11 +1,11 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * DIDD Interface module for Eicon active cards.
+  * 
+  * Functions are in dadapter.c 
+  * 
+- * Copyright 2002 by Armin Schindler (mac@melware.de) 
+- * Copyright 2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2002-2003 by Armin Schindler (mac@melware.de) 
++ * Copyright 2002-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.
+@@ -23,7 +23,7 @@
+ extern void DIVA_DIDD_Read(void *, int);
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_DIDD;
+ static dword notify_handle;
+ static DESCRIPTOR _DAdapter;
+@@ -40,7 +40,7 @@
+               if (removal) {
+                       DbgDeregister();
+               } else {
+-                      DbgRegister("DIDD", DRIVERRELEASE, DBG_DEFAULT);
++                      DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
+               }
+       }
+       return (NULL);
+@@ -65,14 +65,14 @@
+                       req.didd_notify.e.Req = 0;
+                       req.didd_notify.e.Rc =
+                           IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+-                      req.didd_notify.info.callback = didd_callback;
++                      req.didd_notify.info.callback = (void *)didd_callback;
+                       req.didd_notify.info.context = 0;
+                       _DAdapter.request((ENTITY *) & req);
+                       if (req.didd_notify.e.Rc != 0xff)
+                               return (0);
+                       notify_handle = req.didd_notify.info.handle;
+               } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
+-                      DbgRegister("DIDD", DRIVERRELEASE, DBG_DEFAULT);
++                      DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
+               }
+       }
+       return (dadapter);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diva.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva.c       2003-09-27 11:38:21.553251792 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #define CARDTYPE_H_WANT_DATA            1
+ #define CARDTYPE_H_WANT_IDI_DATA        0
+@@ -7,7 +7,6 @@
+ #include "platform.h"
+ #include "debuglib.h"
+-#include "diva_pci.h"
+ #include "cardtype.h"
+ #include "dlist.h"
+ #include "pc.h"
+@@ -15,19 +14,17 @@
+ #include "di.h"
+ #include "io.h"
+ #include "pc_maint.h"
+-
+ #include "xdi_msg.h"
+ #include "xdi_adapter.h"
++#include "diva_pci.h"
+ #include "diva.h"
+ #ifdef CONFIG_ISDN_DIVAS_PRIPCI
+ #include "os_pri.h"
+ #endif
+-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
+-#include "os_4bri.h"
+-#endif
+ #ifdef CONFIG_ISDN_DIVAS_BRIPCI
+ #include "os_bri.h"
++#include "os_4bri.h"
+ #endif
+ PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
+@@ -78,6 +75,11 @@
+ struct pt_regs;
+ /*
++ * include queue functions
++ */
++#include "dlist.c"
++
++/*
+ **  LOCALS
+ */
+ diva_entity_queue_t adapter_queue;
+@@ -109,7 +111,7 @@
+        */
+       {CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI, diva_pri_init_card},
+ #endif
+-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
++#ifdef CONFIG_ISDN_DIVAS_BRIPCI
+       /*
+          4BRI Rev 1 Cards
+        */
+@@ -126,8 +128,6 @@
+       {CARDTYPE_DIVASRV_B_2M_V2_PCI, diva_4bri_init_card},
+       {CARDTYPE_DIVASRV_B_2F_PCI, diva_4bri_init_card},
+       {CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI, diva_4bri_init_card},
+-#endif
+-#ifdef CONFIG_ISDN_DIVAS_BRIPCI
+       /*
+          BRI
+        */
+@@ -193,6 +193,7 @@
+                                       pdiva->controller = i + 1;
+                                       pdiva->xdi_adapter.ANum = pdiva->controller;
+                                       IoAdapters[i] = &pdiva->xdi_adapter;
++                                      diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
+                                       create_adapter_proc(pdiva);     /* add adapter to proc file system */
+                                       DBG_LOG(("add %s:%d",
+@@ -200,6 +201,7 @@
+                                                [CardOrdinal].Name,
+                                                pdiva->controller))
++                                      diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
+                                       pa = pdiva;
+                                       for (j = 1; j < nr; j++) {      /* slave adapters, if any */
+                                               pa = (diva_os_xdi_adapter_t *) diva_q_get_next(&pa->link);
+@@ -207,8 +209,11 @@
+                                                       pa->controller = i + 1 + j;
+                                                       pa->xdi_adapter.ANum = pa->controller;
+                                                       IoAdapters[i + j] = &pa->xdi_adapter;
++                                                      diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
+                                                       DBG_LOG(("add slave adapter (%d)",
+-                                                               pa->controller)) create_adapter_proc(pa);      /* add adapter to proc file system */
++                                                               pa->controller))
++                                                      create_adapter_proc(pa);        /* add adapter to proc file system */
++                                                      diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
+                                               } else {
+                                                       DBG_ERR(("slave adapter problem"))
+                                                       break;
+@@ -463,7 +468,8 @@
+               }
+       } else {
+               DBG_ERR(("A: A(%d) write error (%d)", a->controller,
+-                       length))}
++                       length))
++      }
+       diva_os_free(0, data);
+@@ -564,7 +570,6 @@
+       Requests[31] = DivaIdiRequest31;
+ }
+-/* card:  1-based card number */
+ void diva_xdi_display_adapter_features(int card)
+ {
+       dword features;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divacapi.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divacapi.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divacapi.h   2003-09-27 11:38:21.566249816 +0800
+@@ -643,7 +643,7 @@
+   unsigned parity:2;
+   unsigned spare: 2;
+   unsigned stp:   1;
+-  unsigned ch_len:2;   // 3th octett in CAI
++  unsigned ch_len:2;   /* 3th octett in CAI */
+ };
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_didd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diva_didd.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_didd.c  2003-09-27 11:38:21.569249360 +0800
+@@ -1,11 +1,11 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * DIDD Interface module for Eicon active cards.
+  * 
+  * Functions are in dadapter.c 
+  * 
+- * Copyright 2002 by Armin Schindler (mac@melware.de) 
+- * Copyright 2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2002-2003 by Armin Schindler (mac@melware.de) 
++ * Copyright 2002-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.
+@@ -23,14 +23,13 @@
+ #include "divasync.h"
+ #include "did_vers.h"
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+ static char *DRIVERNAME =
+     "Eicon DIVA - DIDD table (http://www.melware.net)";
+ static char *DRIVERLNAME = "divadidd";
+-char *DRIVERRELEASE = "2.0";
++char *DRIVERRELEASE_DIDD = "2.0";
+-static char *dir_in_proc_net = "isdn";
+ static char *main_proc_dir = "eicon";
+ MODULE_DESCRIPTION("DIDD table driver for diva drivers");
+@@ -48,12 +47,11 @@
+ extern void DIVA_DIDD_Read(void *, int);
+-static struct proc_dir_entry *proc_net_isdn;
+ static struct proc_dir_entry *proc_didd;
+-struct proc_dir_entry *proc_net_isdn_eicon = NULL;
++struct proc_dir_entry *proc_net_eicon = NULL;
+ EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
+-EXPORT_SYMBOL_NOVERS(proc_net_isdn_eicon);
++EXPORT_SYMBOL_NOVERS(proc_net_eicon);
+ static char *getrev(const char *revision)
+ {
+@@ -78,7 +76,7 @@
+       strcpy(tmprev, main_revision);
+       len += sprintf(page + len, "%s\n", DRIVERNAME);
+       len += sprintf(page + len, "name     : %s\n", DRIVERLNAME);
+-      len += sprintf(page + len, "release  : %s\n", DRIVERRELEASE);
++      len += sprintf(page + len, "release  : %s\n", DRIVERRELEASE_DIDD);
+       len += sprintf(page + len, "build    : %s(%s)\n",
+                      diva_didd_common_code_build, DIVA_BUILD);
+       len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
+@@ -93,26 +91,12 @@
+ static int DIVA_INIT_FUNCTION create_proc(void)
+ {
+-      struct proc_dir_entry *pe;
++      proc_net_eicon = create_proc_entry(main_proc_dir, S_IFDIR, proc_net);
+-      for (pe = proc_net->subdir; pe; pe = pe->next) {
+-              if (!memcmp(dir_in_proc_net, pe->name, pe->namelen)) {
+-                      proc_net_isdn = pe;
+-                      break;
+-              }
+-      }
+-      if (!proc_net_isdn) {
+-              proc_net_isdn =
+-                  create_proc_entry(dir_in_proc_net, S_IFDIR, proc_net);
+-      }
+-      proc_net_isdn_eicon =
+-          create_proc_entry(main_proc_dir, S_IFDIR, proc_net_isdn);
+-
+-      if (proc_net_isdn_eicon) {
+-              if (
+-                  (proc_didd =
++      if (proc_net_eicon) {
++              if ((proc_didd =
+                    create_proc_entry(DRIVERLNAME, S_IFREG | S_IRUGO,
+-                                     proc_net_isdn_eicon))) {
++                                     proc_net_eicon))) {
+                       proc_didd->read_proc = proc_read;
+               }
+               return (1);
+@@ -120,14 +104,10 @@
+       return (0);
+ }
+-static void remove_proc(void)
++static void DIVA_EXIT_FUNCTION remove_proc(void)
+ {
+-      remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
+-      remove_proc_entry(main_proc_dir, proc_net_isdn);
+-
+-      if ((proc_net_isdn) && (!proc_net_isdn->subdir)) {
+-              remove_proc_entry(dir_in_proc_net, proc_net);
+-      }
++      remove_proc_entry(DRIVERLNAME, proc_net_eicon);
++      remove_proc_entry(main_proc_dir, proc_net);
+ }
+ static int DIVA_INIT_FUNCTION divadidd_init(void)
+@@ -136,7 +116,7 @@
+       int ret = 0;
+       printk(KERN_INFO "%s\n", DRIVERNAME);
+-      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE);
++      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE_DIDD);
+       strcpy(tmprev, main_revision);
+       printk("%s  Build:%s(%s)\n", getrev(tmprev),
+              diva_didd_common_code_build, DIVA_BUILD);
+@@ -151,7 +131,9 @@
+       if (!diddfunc_init()) {
+               printk(KERN_ERR "%s: failed to connect to DIDD.\n",
+                      DRIVERLNAME);
++#ifdef MODULE
+               remove_proc();
++#endif
+               ret = -EIO;
+               goto out;
+       }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divamnt.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divamnt.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divamnt.c    2003-09-27 11:38:21.573248752 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * Driver for Eicon DIVA Server ISDN cards.
+  * Maint module
+  *
+- * 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.
+@@ -19,7 +19,6 @@
+ #include <linux/poll.h>
+ #include <linux/proc_fs.h>
+ #include <linux/skbuff.h>
+-#include <linux/vmalloc.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include "platform.h"
+@@ -28,16 +27,14 @@
+ #include "di_defs.h"
+ #include "debug_if.h"
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+-static int major = 241;
++static int major;
+ MODULE_DESCRIPTION("Maint driver for Eicon DIVA Server cards");
+ MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
+ MODULE_SUPPORTED_DEVICE("DIVA card driver");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(major, "i");
+-MODULE_PARM_DESC(major, "Major number for /dev/DivasMAINT");
+ int buffer_length = 128;
+ MODULE_PARM(buffer_length, "i");
+@@ -47,7 +44,8 @@
+ static char *DRIVERNAME =
+     "Eicon DIVA - MAINT module (http://www.melware.net)";
+ static char *DRIVERLNAME = "diva_mnt";
+-char *DRIVERRELEASE = "2.0";
++static char *DEVNAME = "DivasMAINT";
++char *DRIVERRELEASE_MNT = "2.0";
+ static wait_queue_head_t msgwaitq;
+ static DECLARE_MUTEX(opened_sem);
+@@ -77,18 +75,8 @@
+ }
+ /*
+- * memory alloc
++ * buffer alloc
+  */
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+-      return (vmalloc(size));
+-}
+-void diva_os_free(unsigned long flags, void *ptr)
+-{
+-      if (ptr) {
+-              vfree(ptr);
+-      }
+-}
+ void *diva_os_malloc_tbuffer(unsigned long flags, unsigned long size)
+ {
+       return (kmalloc(size, GFP_KERNEL));
+@@ -101,17 +89,6 @@
+ }
+ /*
+- * sleep msec
+- */
+-void diva_os_sleep(dword mSec)
+-{
+-      unsigned long timeout = HZ * mSec / 1000 + 1;
+-
+-      set_current_state(TASK_UNINTERRUPTIBLE);
+-      schedule_timeout(timeout);
+-}
+-
+-/*
+  * kernel/user space copy functions
+  */
+ int diva_os_copy_to_user(void *os_handle, void *dst, const void *src,
+@@ -158,7 +135,7 @@
+  * /proc entries
+  */
+-extern struct proc_dir_entry *proc_net_isdn_eicon;
++extern struct proc_dir_entry *proc_net_eicon;
+ static struct proc_dir_entry *maint_proc_entry = NULL;
+ /*
+@@ -363,7 +340,7 @@
+ {
+       maint_proc_entry =
+           create_proc_entry("maint", S_IFREG | S_IRUGO | S_IWUSR,
+-                            proc_net_isdn_eicon);
++                            proc_net_eicon);
+       if (!maint_proc_entry)
+               return (0);
+@@ -376,7 +353,7 @@
+ static void remove_maint_proc(void)
+ {
+       if (maint_proc_entry) {
+-              remove_proc_entry("maint", proc_net_isdn_eicon);
++              remove_proc_entry("maint", proc_net_eicon);
+               maint_proc_entry = NULL;
+       }
+ }
+@@ -408,20 +385,20 @@
+ static void divas_maint_unregister_chrdev(void)
+ {
+-      devfs_remove("DivasMAINT");
+-      unregister_chrdev(major, "DivasMAINT");
++      devfs_remove(DEVNAME);
++      unregister_chrdev(major, DEVNAME);
+ }
+ static int DIVA_INIT_FUNCTION divas_maint_register_chrdev(void)
+ {
+-      if (register_chrdev(major, "DivasMAINT", &divas_maint_fops))
++      if ((major = register_chrdev(0, DEVNAME, &divas_maint_fops)) < 0)
+       {
+               printk(KERN_ERR "%s: failed to create /dev entry.\n",
+                      DRIVERLNAME);
+               return (0);
+       }
++      devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
+-      devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "DivasMAINT");
+       return (1);
+ }
+@@ -446,10 +423,9 @@
+       init_waitqueue_head(&msgwaitq);
+       printk(KERN_INFO "%s\n", DRIVERNAME);
+-      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE);
++      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE_MNT);
+       strcpy(tmprev, main_revision);
+-      printk("%s  Build: %s  Major: %d\n", getrev(tmprev), DIVA_BUILD,
+-             major);
++      printk("%s  Build: %s \n", getrev(tmprev), DIVA_BUILD);
+       if (!divas_maint_register_chrdev()) {
+               ret = -EIO;
+@@ -472,9 +448,9 @@
+               goto out;
+       }
+-      printk(KERN_INFO "%s: trace buffer = %p - %d kBytes, %s \n",
+-             DRIVERLNAME, buffer, buffer_length,
+-             (diva_dbg_mem == 0) ? "internal" : "external");
++      printk(KERN_INFO "%s: trace buffer = %p - %d kBytes, %s (Major: %d)\n",
++             DRIVERLNAME, buffer, (buffer_length / 1024),
++             (diva_dbg_mem == 0) ? "internal" : "external", major);
+       out:
+       return (ret);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_pci.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/diva_pci.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/diva_pci.h   2003-09-27 11:38:21.575248448 +0800
+@@ -1,9 +1,12 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #ifndef __DIVA_PCI_INTERFACE_H__
+ #define __DIVA_PCI_INTERFACE_H__
+-void *divasa_remap_pci_bar(unsigned long bar, unsigned long area_length);
++void *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a,
++                         int id,
++                         unsigned long bar,
++                         unsigned long area_length);
+ void divasa_unmap_pci_bar(void *bar);
+ unsigned long divasa_get_pci_irq(unsigned char bus,
+                                unsigned char func, void *pci_dev_handle);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasfunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasfunc.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasfunc.c  2003-09-27 11:38:21.577248144 +0800
+@@ -1,9 +1,9 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * Low level driver for Eicon DIVA Server ISDN cards.
+  *
+- * 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.
+@@ -21,6 +21,8 @@
+ #define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)
+ #define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)
++static int debugmask;
++
+ extern void DIVA_DIDD_Read(void *, int);
+ extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
+@@ -28,7 +30,7 @@
+ #define MAX_DESCRIPTORS  32
+ extern void diva_run_trap_script(PISDN_ADAPTER IoAdapter, dword ANum);
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_DIVAS;
+ static dword notify_handle;
+ static DESCRIPTOR DAdapter;
+@@ -42,8 +44,6 @@
+       /* dummy debug function */
+ }
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ #include "debuglib.c"
+ /*
+@@ -117,10 +117,11 @@
+  */
+ static void start_dbg(void)
+ {
+-      DbgRegister("DIVAS", DRIVERRELEASE, DBG_DEFAULT);
++      DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
+       DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s]-%s-%s)",
+                DIVA_BUILD, diva_xdi_common_code_build, __DATE__,
+-               __TIME__))}
++               __TIME__))
++}
+ /*
+  * stop debug
+@@ -174,7 +175,7 @@
+                       req.didd_notify.e.Req = 0;
+                       req.didd_notify.e.Rc =
+                           IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+-                      req.didd_notify.info.callback = didd_callback;
++                      req.didd_notify.info.callback = (void *)didd_callback;
+                       req.didd_notify.info.context = 0;
+                       DAdapter.request((ENTITY *) & req);
+                       if (req.didd_notify.e.Rc != 0xff) {
+@@ -214,13 +215,19 @@
+ /*
+  * init
+  */
+-int DIVA_INIT_FUNCTION divasfunc_init(void)
++int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask)
+ {
++      char *version;
++
++      debugmask = dbgmask;
++      
+       if (!connect_didd()) {
+               DBG_ERR(("divasfunc: failed to connect to DIDD."))
+               return (0);
+       }
++      version = diva_xdi_common_code_build;
++
+       divasa_xdi_driver_entry();
+       return (1);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasi.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasi.c     2003-09-27 11:38:21.582247384 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * Driver for Eicon DIVA Server ISDN cards.
+  * User Mode IDI Interface 
+  *
+- * 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.
+@@ -19,7 +19,6 @@
+ #include <linux/poll.h>
+ #include <linux/proc_fs.h>
+ #include <linux/skbuff.h>
+-#include <linux/vmalloc.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include "platform.h"
+@@ -28,27 +27,27 @@
+ #include "um_xdi.h"
+ #include "um_idi.h"
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+-static int major = 242;
++static int major;
+ MODULE_DESCRIPTION("User IDI Interface for Eicon ISDN cards");
+ MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
+ MODULE_SUPPORTED_DEVICE("DIVA card driver");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(major, "i");
+-MODULE_PARM_DESC(major, "Major number for /dev/DivasIDI");
+ typedef struct _diva_um_idi_os_context {
+       wait_queue_head_t read_wait;
+       wait_queue_head_t close_wait;
+       struct timer_list diva_timer_id;
+       int aborted;
++      int adapter_nr;
+ } diva_um_idi_os_context_t;
+ static char *DRIVERNAME = "Eicon DIVA - User IDI (http://www.melware.net)";
+ static char *DRIVERLNAME = "diva_idi";
+-char *DRIVERRELEASE = "2.0";
++static char *DEVNAME = "DivasIDI";
++char *DRIVERRELEASE_IDI = "2.0";
+ extern int idifunc_init(void);
+ extern void idifunc_finit(void);
+@@ -83,32 +82,9 @@
+ static void diva_um_timer_function(unsigned long data);
+ /*
+- * malloc
+- */
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+-      void *ret = NULL;
+-
+-      if (size) {
+-              ret = (void *) vmalloc((unsigned int) size);
+-      }
+-      return (ret);
+-}
+-
+-/*
+- * free
+- */
+-void diva_os_free(unsigned long unused, void *ptr)
+-{
+-      if (ptr) {
+-              vfree(ptr);
+-      }
+-}
+-
+-/*
+  * proc entry
+  */
+-extern struct proc_dir_entry *proc_net_isdn_eicon;
++extern struct proc_dir_entry *proc_net_eicon;
+ static struct proc_dir_entry *um_idi_proc_entry = NULL;
+ static int
+@@ -120,10 +96,11 @@
+       len += sprintf(page + len, "%s\n", DRIVERNAME);
+       len += sprintf(page + len, "name     : %s\n", DRIVERLNAME);
+-      len += sprintf(page + len, "release  : %s\n", DRIVERRELEASE);
++      len += sprintf(page + len, "release  : %s\n", DRIVERRELEASE_IDI);
+       strcpy(tmprev, main_revision);
+       len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
+       len += sprintf(page + len, "build    : %s\n", DIVA_BUILD);
++      len += sprintf(page + len, "major    : %d\n", major);
+       if (off + count >= len)
+               *eof = 1;
+@@ -137,7 +114,7 @@
+ {
+       um_idi_proc_entry = create_proc_entry(DRIVERLNAME,
+                                             S_IFREG | S_IRUGO | S_IWUSR,
+-                                            proc_net_isdn_eicon);
++                                            proc_net_eicon);
+       if (!um_idi_proc_entry)
+               return (0);
+@@ -150,7 +127,7 @@
+ static void remove_um_idi_proc(void)
+ {
+       if (um_idi_proc_entry) {
+-              remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
++              remove_proc_entry(DRIVERLNAME, proc_net_eicon);
+               um_idi_proc_entry = NULL;
+       }
+ }
+@@ -167,20 +144,20 @@
+ static void divas_idi_unregister_chrdev(void)
+ {
+-      devfs_remove("DivasIDI");
+-      unregister_chrdev(major, "DivasIDI");
++      devfs_remove(DEVNAME);
++      unregister_chrdev(major, DEVNAME);
+ }
+ static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void)
+ {
+-      if (register_chrdev(major, "DivasIDI", &divas_idi_fops))
++      if ((major = register_chrdev(0, DEVNAME, &divas_idi_fops)) < 0)
+       {
+               printk(KERN_ERR "%s: failed to create /dev entry.\n",
+                      DRIVERLNAME);
+               return (0);
+       }
++      devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
+-      devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "DivasIDI");
+       return (1);
+ }
+@@ -193,10 +170,9 @@
+       int ret = 0;
+       printk(KERN_INFO "%s\n", DRIVERNAME);
+-      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE);
++      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE_IDI);
+       strcpy(tmprev, main_revision);
+-      printk("%s  Build: %s Major: %d\n", getrev(tmprev), DIVA_BUILD,
+-             major);
++      printk("%s  Build: %s\n", getrev(tmprev), DIVA_BUILD);
+       if (!divas_idi_register_chrdev()) {
+               ret = -EIO;
+@@ -219,6 +195,7 @@
+               ret = -EIO;
+               goto out;
+       }
++      printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
+       out:
+       return (ret);
+@@ -330,6 +307,7 @@
+       p_os->diva_timer_id.function = (void *) diva_um_timer_function;
+       p_os->diva_timer_id.data = (unsigned long) p_os;
+       p_os->aborted = 0;
++      p_os->adapter_nr = adapter_nr;
+       return (1);
+ }
+@@ -432,7 +410,8 @@
+ static int um_idi_release(struct inode *inode, struct file *file)
+ {
+-      unsigned int adapter_nr = iminor(inode);
++      diva_um_idi_os_context_t *p_os;
++      unsigned int adapter_nr;
+       int ret = 0;
+       if (!(file->private_data)) {
+@@ -440,6 +419,14 @@
+               goto out;
+       }
++      if (!(p_os =
++              (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) {
++              ret = -ENODEV;
++              goto out;
++      }
++
++      adapter_nr = p_os->adapter_nr;
++
+       if ((ret = remove_entity(file->private_data))) {
+               goto out;
+       }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasmain.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasmain.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasmain.c  2003-09-27 11:38:21.589246320 +0800
+@@ -1,9 +1,9 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * Low level driver for Eicon DIVA Server ISDN cards.
+  *
+- * 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.
+@@ -16,14 +16,12 @@
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/unistd.h>
+-#include <linux/vmalloc.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ #include <linux/ioport.h>
+ #include <linux/workqueue.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/smp_lock.h>
+ #include <linux/interrupt.h>
+ #include <linux/poll.h>
+@@ -37,36 +35,39 @@
+ #include "di_defs.h"
+ #include "divasync.h"
+ #include "diva.h"
+-#include "diva_pci.h"
+ #include "di.h"
+ #include "io.h"
+ #include "xdi_msg.h"
+ #include "xdi_adapter.h"
+ #include "xdi_vers.h"
+ #include "diva_dma.h"
++#include "diva_pci.h"
+-static char *main_revision = "$Revision: 1.1.4.1 $";
++static char *main_revision = "$Revision: 1.1.4.1 $";
+-int errno = 0;
+-static int major = 240;
++static int major;
++
++static int dbgmask;
+ MODULE_DESCRIPTION("Kernel driver for Eicon DIVA Server cards");
+ MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(major, "i");
+-MODULE_PARM_DESC(major, "Major number for /dev/Divas");
++
++MODULE_PARM(dbgmask, "i");
++MODULE_PARM_DESC(dbgmask, "initial debug mask");
+ static char *DRIVERNAME =
+     "Eicon DIVA Server driver (http://www.melware.net)";
+ static char *DRIVERLNAME = "divas";
+-char *DRIVERRELEASE = "2.0";
++static char *DEVNAME = "Divas";
++char *DRIVERRELEASE_DIVAS = "2.0";
+ extern irqreturn_t diva_os_irq_wrapper(int irq, void *context,
+                               struct pt_regs *regs);
+ extern int create_divas_proc(void);
+ extern void remove_divas_proc(void);
+ extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf);
+-extern int divasfunc_init(void);
++extern int divasfunc_init(int dbgmask);
+ extern void divasfunc_exit(void);
+ typedef struct _diva_os_thread_dpc {
+@@ -185,19 +186,6 @@
+       return rev;
+ }
+-void diva_os_sleep(dword mSec)
+-{
+-      unsigned long timeout = HZ * mSec / 1000 + 1;
+-
+-      set_current_state(TASK_UNINTERRUPTIBLE);
+-      schedule_timeout(timeout);
+-}
+-
+-void diva_os_wait(dword mSec)
+-{
+-      mdelay(mSec);
+-}
+-
+ void diva_log_info(unsigned char *format, ...)
+ {
+       va_list args;
+@@ -215,29 +203,8 @@
+       char tmprev[32];
+       strcpy(tmprev, main_revision);
+-      sprintf(p, "%s: %s(%s) %s(%s)\n", DRIVERLNAME, DRIVERRELEASE,
+-              getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD);
+-}
+-
+-/*********************************************************
+- ** malloc / free
+- *********************************************************/
+-
+-void *diva_os_malloc(unsigned long flags, unsigned long size)
+-{
+-      void *ret = NULL;
+-
+-      if (size) {
+-              ret = (void *) vmalloc((unsigned int) size);
+-      }
+-      return (ret);
+-}
+-
+-void diva_os_free(unsigned long unused, void *ptr)
+-{
+-      if (ptr) {
+-              vfree(ptr);
+-      }
++      sprintf(p, "%s: %s(%s) %s(%s) major=%d\n", DRIVERLNAME, DRIVERRELEASE_DIVAS,
++              getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD, major);
+ }
+ /* --------------------------------------------------------------------------
+@@ -282,6 +249,7 @@
+           (diva_os_thread_dpc_t *) psoft_isr->object;
+       if (context && !context->card_failed) {
++              printk(KERN_ERR "%s: adapter %d trapped !\n", DRIVERLNAME, ANum + 1);
+               context->card_failed = ANum + 1;
+               schedule_work(&context->trap_script_task);
+       }
+@@ -505,8 +473,8 @@
+  *********************************************************/
+ int
+-diva_os_register_io_port(int on, unsigned long port, unsigned long length,
+-                       const char *name)
++diva_os_register_io_port(void *adapter, int on, unsigned long port,
++                       unsigned long length, const char *name, int id)
+ {
+       if (on) {
+               if (!request_region(port, length, name)) {
+@@ -519,7 +487,7 @@
+       return (0);
+ }
+-void *divasa_remap_pci_bar(unsigned long bar, unsigned long area_length)
++void *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a, int id, unsigned long bar, unsigned long area_length)
+ {
+       void *ret;
+@@ -772,20 +740,20 @@
+ static void divas_unregister_chrdev(void)
+ {
+-      devfs_remove("Divas");
+-      unregister_chrdev(major, "Divas");
++      devfs_remove(DEVNAME);
++      unregister_chrdev(major, DEVNAME);
+ }
+ static int DIVA_INIT_FUNCTION divas_register_chrdev(void)
+ {
+-      if (register_chrdev(major, "Divas", &divas_fops))
++      if ((major = register_chrdev(0, DEVNAME, &divas_fops)) < 0)
+       {
+               printk(KERN_ERR "%s: failed to create /dev entry.\n",
+                      DRIVERLNAME);
+               return (0);
+       }
++      devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
+-      devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "Divas");
+       return (1);
+ }
+@@ -877,23 +845,20 @@
+       int ret = 0;
+       printk(KERN_INFO "%s\n", DRIVERNAME);
+-      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE);
++      printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE_DIVAS);
+       strcpy(tmprev, main_revision);
+-      printk("%s  Build: %s(%s) Major: %d\n", getrev(tmprev),
+-             diva_xdi_common_code_build, DIVA_BUILD, major);
++      printk("%s  Build: %s(%s)\n", getrev(tmprev),
++             diva_xdi_common_code_build, DIVA_BUILD);
+       printk(KERN_INFO "%s: support for: ", DRIVERLNAME);
+ #ifdef CONFIG_ISDN_DIVAS_BRIPCI
+       printk("BRI/PCI ");
+ #endif
+-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
+-      printk("4BRI/PCI ");
+-#endif
+ #ifdef CONFIG_ISDN_DIVAS_PRIPCI
+       printk("PRI/PCI ");
+ #endif
+-      printk("\n");
++      printk("adapters\n");
+-      if (!divasfunc_init()) {
++      if (!divasfunc_init(dbgmask)) {
+               printk(KERN_ERR "%s: failed to connect to DIDD.\n",
+                      DRIVERLNAME);
+               ret = -EIO;
+@@ -901,15 +866,19 @@
+       }
+       if (!divas_register_chrdev()) {
++#ifdef MODULE
+               divasfunc_exit();
++#endif
+               ret = -EIO;
+               goto out;
+       }
+       if (!create_divas_proc()) {
++#ifdef MODULE
+               remove_divas_proc();
+               divas_unregister_chrdev();
+               divasfunc_exit();
++#endif
+               printk(KERN_ERR "%s: failed to create proc entry.\n",
+                      DRIVERLNAME);
+               ret = -EIO;
+@@ -917,13 +886,16 @@
+       }
+       if ((ret = pci_module_init(&diva_pci_driver))) {
++#ifdef MODULE
+               remove_divas_proc();
+               divas_unregister_chrdev();
+               divasfunc_exit();
++#endif
+               printk(KERN_ERR "%s: failed to init pci driver.\n",
+                      DRIVERLNAME);
+               goto out;
+       }
++      printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
+       out:
+       return (ret);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/divasproc.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/divasproc.c  2003-09-27 11:38:21.592245864 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * Low level driver for Eicon DIVA Server ISDN cards.
+  * /proc functions
+  *
+- * 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.
+@@ -15,7 +15,6 @@
+ #include <linux/kernel.h>
+ #include <linux/poll.h>
+ #include <linux/proc_fs.h>
+-#include <linux/interrupt.h>
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -23,7 +22,6 @@
+ #undef ID_MASK
+ #undef N_DATA
+ #include "pc.h"
+-#include "diva_pci.h"
+ #include "di_defs.h"
+ #include "divasync.h"
+ #include "di.h"
+@@ -31,6 +29,7 @@
+ #include "xdi_msg.h"
+ #include "xdi_adapter.h"
+ #include "diva.h"
++#include "diva_pci.h"
+ extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
+@@ -52,7 +51,7 @@
+ ** "divas" entry
+ */
+-extern struct proc_dir_entry *proc_net_isdn_eicon;
++extern struct proc_dir_entry *proc_net_eicon;
+ static struct proc_dir_entry *divas_proc_entry = NULL;
+ static ssize_t
+@@ -131,7 +130,7 @@
+ {
+       divas_proc_entry = create_proc_entry(divas_proc_name,
+                                            S_IFREG | S_IRUGO,
+-                                           proc_net_isdn_eicon);
++                                           proc_net_eicon);
+       if (!divas_proc_entry)
+               return (0);
+@@ -144,7 +143,7 @@
+ void remove_divas_proc(void)
+ {
+       if (divas_proc_entry) {
+-              remove_proc_entry(divas_proc_name, proc_net_isdn_eicon);
++              remove_proc_entry(divas_proc_name, proc_net_eicon);
+               divas_proc_entry = NULL;
+       }
+ }
+@@ -333,7 +332,8 @@
+               }
+       }
+       if ((!a->xdi_adapter.port) &&
+-          ((!a->xdi_adapter.ram) || (!a->xdi_adapter.reset)
++          ((!a->xdi_adapter.ram) ||
++          (!a->xdi_adapter.reset)
+            || (!a->xdi_adapter.cfg))) {
+               if (!IoAdapter->irq_info.irq_nr) {
+                       p = "slave";
+@@ -369,20 +369,14 @@
+       struct proc_dir_entry *de, *pe;
+       char tmp[16];
+-      if (in_interrupt()) {
+-              printk(KERN_ERR
+-                     "divasproc: create_proc in_interrupt, not creating\n");
+-              return (1);
+-      }
+-
+       sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
+-      if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_isdn_eicon)))
++      if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_eicon)))
+               return (0);
+       a->proc_adapter_dir = (void *) de;
+       if (!(pe =
+-           create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR,
+-                             de))) return (0);
++           create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR, de)))
++              return (0);
+       a->proc_info = (void *) pe;
+       pe->write_proc = info_write;
+       pe->read_proc = info_read;
+@@ -429,7 +423,7 @@
+                                         (struct proc_dir_entry *) a->proc_adapter_dir);
+               }
+               sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
+-              remove_proc_entry(tmp, proc_net_isdn_eicon);
++              remove_proc_entry(tmp, proc_net_eicon);
+               DBG_TRC(("proc entry %s%d removed", adapter_dir_name,
+                        a->controller));
+       }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/dlist.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.c      2003-09-27 11:38:21.594245560 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #include "platform.h"
+ #include "dlist.h"
+@@ -7,7 +7,7 @@
+ **  Initialize linked list
+ */
+-void diva_q_init(diva_entity_queue_t * q)
++static void diva_q_init(diva_entity_queue_t * q)
+ {
+       memset(q, 0x00, sizeof(*q));
+ }
+@@ -15,7 +15,7 @@
+ /*
+ **  Remove element from linked list
+ */
+-void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what)
++static void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what)
+ {
+       if (!what->prev) {
+               if ((q->head = what->next)) {
+@@ -36,7 +36,7 @@
+ /*
+ **  Add element to the tail of linked list
+ */
+-void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what)
++static void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what)
+ {
+       what->next = 0;
+       if (!q->head) {
+@@ -49,7 +49,7 @@
+       }
+ }
+-diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
++static diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
+                               const void *what, diva_q_cmp_fn_t cmp_fn)
+ {
+       diva_entity_link_t *diva_current = q->head;
+@@ -64,35 +64,13 @@
+       return (diva_current);
+ }
+-diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q)
++static diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q)
+ {
+       return (q->head);
+ }
+-diva_entity_link_t *diva_q_get_tail(diva_entity_queue_t * q)
+-{
+-      return (q->tail);
+-}
+-
+-diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what)
++static diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what)
+ {
+       return ((what) ? what->next : 0);
+ }
+-diva_entity_link_t *diva_q_get_prev(diva_entity_link_t * what)
+-{
+-      return ((what) ? what->prev : 0);
+-}
+-
+-int diva_q_get_nr_of_entries(const diva_entity_queue_t * q)
+-{
+-      int i = 0;
+-      const diva_entity_link_t *diva_current = q->head;
+-
+-      while (diva_current) {
+-              i++;
+-              diva_current = diva_current->next;
+-      }
+-
+-      return (i);
+-}
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/dlist.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/dlist.h      2003-09-27 11:38:21.595245408 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #ifndef __DIVA_LINK_H__
+ #define __DIVA_LINK_H__
+@@ -17,16 +17,4 @@
+ typedef int (*diva_q_cmp_fn_t) (const void *what,
+                               const diva_entity_link_t *);
+-void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what);
+-void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what);
+-diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
+-                              const void *what, diva_q_cmp_fn_t cmp_fn);
+-
+-diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q);
+-diva_entity_link_t *diva_q_get_tail(diva_entity_queue_t * q);
+-diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what);
+-diva_entity_link_t *diva_q_get_prev(diva_entity_link_t * what);
+-int diva_q_get_nr_of_entries(const diva_entity_queue_t * q);
+-void diva_q_init(diva_entity_queue_t * q);
+-
+ #endif
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/i4lididrv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/i4lididrv.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/i4lididrv.c  2003-09-27 11:38:21.605243888 +0800
+@@ -293,7 +293,7 @@
+ {
+   int pid = 0;
+-  pid = kernel_thread(divad_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++  pid = kernel_thread(divad_thread, NULL, CLONE_KERNEL);
+   if (pid >= 0) {
+        divad_pid = pid;
+   }
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/idifunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/idifunc.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/idifunc.c    2003-09-27 11:38:21.607243584 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * Driver for Eicon DIVA Server ISDN cards.
+  * User Mode IDI Interface 
+  *
+- * 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.
+@@ -19,7 +19,7 @@
+ #define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)
+ #define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_IDI;
+ extern void DIVA_DIDD_Read(void *, int);
+ extern int diva_user_mode_idi_create_adapter(const DESCRIPTOR *, int);
+@@ -36,8 +36,6 @@
+       /* dummy debug function */
+ }
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ #include "debuglib.c"
+ /*
+@@ -202,7 +200,7 @@
+               } else {
+                       memcpy(&MAdapter, adapter, sizeof(MAdapter));
+                       dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+-                      DbgRegister("User IDI", DRIVERRELEASE, DBG_DEFAULT);
++                      DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
+               }
+       } else if ((adapter->type > 0) && (adapter->type < 16)) {       /* IDI Adapter */
+               if (removal) {
+@@ -233,7 +231,7 @@
+                       req.didd_notify.e.Req = 0;
+                       req.didd_notify.e.Rc =
+                           IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+-                      req.didd_notify.info.callback = didd_callback;
++                      req.didd_notify.info.callback = (void *)didd_callback;
+                       req.didd_notify.info.context = 0;
+                       DAdapter.request((ENTITY *) & req);
+                       if (req.didd_notify.e.Rc != 0xff) {
+@@ -244,7 +242,7 @@
+               } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
+                       memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
+                       dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+-                      DbgRegister("User IDI", DRIVERRELEASE, DBG_DEFAULT);
++                      DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
+               } else if ((DIDD_Table[x].type > 0)
+                          && (DIDD_Table[x].type < 16)) {      /* IDI Adapter found */
+                       um_new_card(&DIDD_Table[x]);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/io.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.c 2003-09-27 11:38:21.615242368 +0800
+@@ -72,10 +72,10 @@
+   */
+ static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ+1] = {
+  (DIVA_XDI_EXTENDED_FEATURES_VALID       |
+-  DIVA_XDI_EXTENDED_FEATURE_CMA          |
+   DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR    |
+   DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS    |
+ #if defined(DIVA_IDI_RX_DMA)
++  DIVA_XDI_EXTENDED_FEATURE_CMA          |
+   DIVA_XDI_EXTENDED_FEATURE_RX_DMA       |
+ #endif
+   DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC),
+@@ -156,7 +156,8 @@
+ dump_trap_frame (PISDN_ADAPTER IoAdapter, byte *exceptionFrame)
+ {
+  MP_XCPTC *xcept = (MP_XCPTC *)exceptionFrame ;
+- dword    *regs  = &xcept->regs[0] ;
++ dword    *regs;
++ regs  = &xcept->regs[0] ;
+  DBG_FTL(("%s: ***************** CPU TRAPPED *****************",
+           &IoAdapter->Name[0]))
+  DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
+@@ -567,26 +568,38 @@
+ /*------------------------------------------------------------------*/
+ byte mem_in (ADAPTER *a, void *addr)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- return (*Base) ;
++ byte val;
++ volatile byte* Base;
++
++ Base = (volatile byte *)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ val = *(Base + (unsigned long)addr);
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
++ return (val);
+ }
+ word mem_inw (ADAPTER *a, void *addr)
+ {
+- word* Base = (word*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- return (READ_WORD(Base)) ;
++ word val;
++ volatile byte* Base;
++ 
++ Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ val = READ_WORD((Base + (unsigned long)addr));
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
++ return (val);
+ }
+ void mem_in_dw (ADAPTER *a, void *addr, dword* data, int dwords)
+ {
+- volatile dword* Base = (dword*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+  while (dwords--) {
+-  *data++ = READ_DWORD(Base);
+-  Base++;
++  *data++ = READ_DWORD((Base + (unsigned long)addr));
++  addr+=4;
+  }
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_in_buffer (ADAPTER *a, void *addr, void *buffer, word length)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- memcpy (buffer, Base, length) ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ memcpy (buffer, (void *)(Base + (unsigned long)addr), length);
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_look_ahead (ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
+ {
+@@ -598,99 +611,130 @@
+ }
+ void mem_out (ADAPTER *a, void *addr, byte data)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- *Base = data ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ *(Base + (unsigned long)addr) = data ;
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_outw (ADAPTER *a, void *addr, word data)
+ {
+- word* Base = (word*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- WRITE_WORD(Base, data);
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ WRITE_WORD((Base + (unsigned long)addr), data);
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_out_dw (ADAPTER *a, void *addr, const dword* data, int dwords)
+ {
+- volatile dword* Base = (dword*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+  while (dwords--) {
+-      WRITE_DWORD(Base, *data);
+-  Base++;
++      WRITE_DWORD((Base + (unsigned long)addr), *data);
++      addr+=4;
+       data++;
+  }
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_out_buffer (ADAPTER *a, void *addr, void *buffer, word length)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- memcpy (Base, buffer, length) ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ memcpy ((void *)(Base + (unsigned long)addr), buffer, length) ;
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ void mem_inc (ADAPTER *a, void *addr)
+ {
+- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+- byte  x = *Base ;
+- *Base = x + 1 ;
++ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
++ byte  x = *(Base + (unsigned long)addr);
++ *(Base + (unsigned long)addr) = x + 1 ;
++ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ }
+ /*------------------------------------------------------------------*/
+ /* ram access functions for io-mapped cards                         */
+ /*------------------------------------------------------------------*/
+ byte io_in(ADAPTER * a, void * adr)
+ {
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  return inpp(((PISDN_ADAPTER)a->io)->port);
++  byte val;
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++  outppw(Port + 4, (word)(unsigned long)adr);
++  val = inpp(Port);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++  return(val);
+ }
+ word io_inw(ADAPTER * a, void * adr)
+ {
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  return inppw(((PISDN_ADAPTER)a->io)->port);
++  word val;
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++  outppw(Port + 4, (word)(unsigned long)adr);
++  val = inppw(Port);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++  return(val);
+ }
+ void io_in_buffer(ADAPTER * a, void * adr, void * buffer, word len)
+ {
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+  byte* P = (byte*)buffer;
+   if ((long)adr & 1) {
+-    outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-    *P = inpp(((PISDN_ADAPTER)a->io)->port);
++    outppw(Port+4, (word)(unsigned long)adr);
++    *P = inpp(Port);
+     P++;
+     adr = ((byte *) adr) + 1;
+     len--;
+-    if (!len) return;
++    if (!len) {
++      DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++      return;
+   }
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  inppw_buffer (((PISDN_ADAPTER)a->io)->port, P, len+1);
++  }
++  outppw(Port+4, (word)(unsigned long)adr);
++  inppw_buffer (Port, P, len+1);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e)
+ {
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)RBuffer);
+-  ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(((PISDN_ADAPTER)a->io)->port);
+-  inppw_buffer (((PISDN_ADAPTER)a->io)->port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++  outppw(Port+4, (word)(unsigned long)RBuffer);
++  ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port);
++  inppw_buffer (Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
+   e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_out(ADAPTER * a, void * adr, byte data)
+ {
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  outpp(((PISDN_ADAPTER)a->io)->port, data);
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++  outppw(Port+4, (word)(unsigned long)adr);
++  outpp(Port, data);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_outw(ADAPTER * a, void * adr, word data)
+ {
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  outppw(((PISDN_ADAPTER)a->io)->port, data);
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++  outppw(Port+4, (word)(unsigned long)adr);
++  outppw(Port, data);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_out_buffer(ADAPTER * a, void * adr, void * buffer, word len)
+ {
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+  byte* P = (byte*)buffer;
+   if ((long)adr & 1) {
+-    outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-    outpp(((PISDN_ADAPTER)a->io)->port, *P);
++    outppw(Port+4, (word)(unsigned long)adr);
++    outpp(Port, *P);
+     P++;
+     adr = ((byte *) adr) + 1;
+     len--;
+-    if (!len) return;
++    if (!len) {
++      DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
++      return;
++    }
+   }
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  outppw_buffer (((PISDN_ADAPTER)a->io)->port, P, len+1);
++  outppw(Port+4, (word)(unsigned long)adr);
++  outppw_buffer (Port, P, len+1);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ void io_inc(ADAPTER * a, void * adr)
+ {
+   byte x;
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  x = inpp(((PISDN_ADAPTER)a->io)->port);
+-  outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
+-  outpp(((PISDN_ADAPTER)a->io)->port, x+1);
++  byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
++  outppw(Port+4, (word)(unsigned long)adr);
++  x = inpp(Port);
++  outppw(Port+4, (word)(unsigned long)adr);
++  outpp(Port, x+1);
++  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ }
+ /*------------------------------------------------------------------*/
+ /* OS specific functions related to queuing of entities             */
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/io.h    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/io.h 2003-09-27 11:38:21.619241760 +0800
+@@ -40,14 +40,6 @@
+  PISDN_ADAPTER QuadroAdapter[4] ;
+ } ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY ;
+ /* --------------------------------------------------------------------------
+-  Special OS memory support structures
+-  -------------------------------------------------------------------------- */
+-#define MAX_MAPPED_ENTRIES 8
+-typedef struct {
+- void  * Address;
+- dword    Length;
+-} ADAPTER_MEMORY ;
+-/* --------------------------------------------------------------------------
+   Configuration of XDI clients carried by XDI
+   -------------------------------------------------------------------------- */
+ #define DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON      0x01
+@@ -71,7 +63,6 @@
+  /*
+   remember mapped memory areas
+  */
+- ADAPTER_MEMORY     MappedMemory[MAX_MAPPED_ENTRIES] ;
+  CARD_PROPERTIES     Properties ;
+  dword               cardType ;
+  dword               protocol_id ;       /* configured protocol identifier */
+@@ -97,6 +88,8 @@
+  dword               MemoryBase ;
+  dword               MemorySize ;
+  byte       *Address ;
++ byte                *Config ;
++ byte                *Control ;
+  byte       *reset ;
+  byte       *port ;
+  byte       *ram ;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/Kconfig      2003-09-27 11:38:21.620241608 +0800
+@@ -12,7 +12,7 @@
+ config ISDN_DIVAS
+       tristate "Support Eicon DIVA Server cards"
+-      depends on CAPI_EICON && PROC_FS && PCI && m
++      depends on CAPI_EICON && PROC_FS && PCI
+       help
+         Say Y here if you have an Eicon Networks DIVA Server PCI ISDN card.
+         In order to use this card, additional firmware is necessary, which
+@@ -24,12 +24,6 @@
+       help
+         Enable support for DIVA Server BRI-PCI.
+-config ISDN_DIVAS_4BRIPCI
+-      bool "DIVA Server 4BRI/PCI support"
+-      depends on ISDN_DIVAS
+-      help
+-        Enable support for DIVA Server 4BRI-PCI.
+-
+ config ISDN_DIVAS_PRIPCI
+       bool "DIVA Server PRI/PCI support"
+       depends on ISDN_DIVAS
+@@ -43,17 +37,17 @@
+         You need this to provide the CAPI interface
+         for DIVA Server cards.
+-config ISDN_DIVAS_MAINT
+-      tristate "DIVA Maint driver support"
+-      depends on ISDN_DIVAS
+-      help
+-        Enable Divas Maintainance driver.
+-
+ config ISDN_DIVAS_USERIDI
+       tristate "DIVA User-IDI interface support"
+       depends on ISDN_DIVAS
+       help
+         Enable support for user-mode IDI interface.
++config ISDN_DIVAS_MAINT
++      tristate "DIVA Maint driver support"
++      depends on ISDN_DIVAS && m
++      help
++        Enable Divas Maintainance driver.
++
+ endmenu
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/Makefile        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/Makefile     2003-09-27 11:38:21.622241304 +0800
+@@ -10,9 +10,8 @@
+ # Multipart objects. 
+ divas-y                                       := divasmain.o divasfunc.o di.o io.o istream.o \
+-                                         diva.o dlist.o divasproc.o diva_dma.o
+-divas-$(CONFIG_ISDN_DIVAS_BRIPCI)     += os_bri.o  s_bri.o
+-divas-$(CONFIG_ISDN_DIVAS_4BRIPCI)    += os_4bri.o s_4bri.o
++                                         diva.o divasproc.o diva_dma.o
++divas-$(CONFIG_ISDN_DIVAS_BRIPCI)     += os_bri.o  s_bri.o os_4bri.o s_4bri.o
+ divas-$(CONFIG_ISDN_DIVAS_PRIPCI)     += os_pri.o  s_pri.o
+ divacapi-y                            := capimain.o capifunc.o message.o capidtmf.o
+@@ -21,4 +20,4 @@
+ diva_mnt-y                            := divamnt.o mntfunc.o debug.o maintidi.o
+-diva_idi-y                            := divasi.o idifunc.o um_idi.o dqueue.o dlist.o
++diva_idi-y                            := divasi.o idifunc.o um_idi.o dqueue.o
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/message.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/message.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/message.c    2003-09-27 11:38:21.738223672 +0800
+@@ -3590,7 +3590,7 @@
+         {
+           if (plci->channels)
+           {
+-            for (ncci = 1; ncci < MAX_NCCI+1; i++)
++            for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
+             {
+               if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
+               {
+@@ -6612,7 +6612,7 @@
+           ||(*data == DSP_UDATA_INDICATION_CTS_ON)) )
+       {
+         word conn_opt, ncpi_opt = 0x00;
+-//      HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data);
++/*      HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
+         if (*data == DSP_UDATA_INDICATION_DCD_ON)
+           plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED;
+@@ -7813,15 +7813,15 @@
+     }
+   }
+-  if(READ_WORD(bp_parms[0].info)==2 ||                         // V.110 async
+-     READ_WORD(bp_parms[0].info)==3 )                          // V.110 sync
++  if(READ_WORD(bp_parms[0].info)==2 ||                         /* V.110 async */
++     READ_WORD(bp_parms[0].info)==3 )                          /* V.110 sync */
+   {
+     if(bp_parms[3].length){
+       dbug(1,dprintf("V.110,%d",READ_WORD(&bp_parms[3].info[1])));
+-      switch(READ_WORD(&bp_parms[3].info[1])){                 // Rate
++      switch(READ_WORD(&bp_parms[3].info[1])){                 /* Rate */
+         case 0:
+         case 56000:
+-          if(READ_WORD(bp_parms[0].info)==3){                  //V.110 sync 56k
++          if(READ_WORD(bp_parms[0].info)==3){                  /* V.110 sync 56k */
+             dbug(1,dprintf("56k sync HSCX"));
+             cai[1] = 8;
+             cai[2] = 0;
+@@ -7859,7 +7859,7 @@
+           return _B1_PARM_NOT_SUPPORTED;
+       }
+       cai[3] = 0;
+-      if (cai[1] == 13)                                        // v.110 async
++      if (cai[1] == 13)                                        /* v.110 async */
+       {
+         if (bp_parms[3].length >= 8)
+         {
+@@ -7906,7 +7906,7 @@
+   }
+   WRITE_WORD(&cai[5],plci->appl->MaxDataLength);
+   dbug(1,dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
+-//HexDump ("CAI", sizeof(cai), &cai[0]);
++/* HexDump ("CAI", sizeof(cai), &cai[0]); */
+   add_p(plci, CAI, cai);
+   return 0;
+@@ -8681,7 +8681,7 @@
+                DLC_MODEMPROT_DISABLE_COMPRESSION;
+   }
+   dlc[0] = (byte)(i - 1);
+-//HexDump ("DLC", sizeof(dlc), &dlc[0]);
++/* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
+   add_p(plci, DLC, dlc);
+   return (0);
+ }
+@@ -8739,7 +8739,7 @@
+ {
+   ENTITY   * e;
+   word l;
+-//  word i;
++/*  word i; */
+   if(!plci) return;
+   if(plci->adapter->adapter_disabled) return;
+@@ -8856,7 +8856,7 @@
+         }
+         else if (plci->send_disc == ncci)
+         {
+-          //dprintf("N_DISC");
++          /* dprintf("N_DISC"); */
+           plci->NData[0].PLength = 0;
+           plci->NL.ReqCh = a->ncci_ch[ncci];
+           plci->NL.Req = plci->nl_req = N_DISC;
+@@ -9059,15 +9059,15 @@
+       for(k=0;k<=flen;k++,j++)
+       {
+         facility[j]=fty_i[i][k];
+-//      dbug(1,dprintf("%x ",facility[j]));
++/*      dbug(1,dprintf("%x ",facility[j])); */
+       }
+     }
+     facility[0] = len;
+     add_i[3] = facility;
+   }
+-//  dbug(1,dprintf("FacArrLen=%d ",len));
++/*  dbug(1,dprintf("FacArrLen=%d ",len)); */
+   len = add_i[0][0]+add_i[1][0]+add_i[2][0]+add_i[3][0];
+-  len += 4;                          // calculate length of all
++  len += 4;                          /* calculate length of all */
+   return(len);
+ }
+@@ -9083,8 +9083,8 @@
+   channel = chi[chi[0]]&0x3;
+   dbug(1,dprintf("ExtDevON(Ch=0x%x)",channel));
+   voice_chi[2] = (channel) ? channel : 1;
+-  add_p(plci,FTY,"\x02\x01\x07");             // B On, default on 1
+-  add_p(plci,ESC,voice_chi);                  // Channel
++  add_p(plci,FTY,"\x02\x01\x07");             /* B On, default on 1 */
++  add_p(plci,ESC,voice_chi);                  /* Channel */
+   sig_req(plci,TEL_CTRL,0);
+   send_req(plci);
+   if(a->AdvSignalPLCI)
+@@ -9096,7 +9096,7 @@
+ void VoiceChannelOff(PLCI   *plci)
+ {
+   dbug(1,dprintf("ExtDevOFF"));
+-  add_p(plci,FTY,"\x02\x01\x08");             // B Off
++  add_p(plci,FTY,"\x02\x01\x08");             /* B Off */
+   sig_req(plci,TEL_CTRL,0);
+   send_req(plci);
+   if(plci->adapter->AdvSignalPLCI)
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/mntfunc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/mntfunc.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/mntfunc.c    2003-09-27 11:38:21.741223216 +0800
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * Driver for Eicon DIVA Server ISDN cards.
+  * Maint module
+  *
+- * 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.
+@@ -17,7 +17,7 @@
+ #include "di_defs.h"
+ #include "debug_if.h"
+-extern char *DRIVERRELEASE;
++extern char *DRIVERRELEASE_MNT;
+ #define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)
+ #define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)
+@@ -45,8 +45,6 @@
+       /* dummy debug function */
+ }
+-DIVA_DI_PRINTF dprintf = no_printf;
+-
+ #include "debuglib.c"
+ /*
+@@ -73,7 +71,7 @@
+               } else {
+                       memcpy(&MAdapter, adapter, sizeof(MAdapter));
+                       dprintf = (DIVA_DI_PRINTF) MAdapter.request;
+-                      DbgRegister("MAINT", DRIVERRELEASE, DBG_DEFAULT);
++                      DbgRegister("MAINT", DRIVERRELEASE_MNT, DBG_DEFAULT);
+               }
+       } else if ((adapter->type > 0) && (adapter->type < 16)) {
+               if (removal) {
+@@ -104,7 +102,7 @@
+                       req.didd_notify.e.Req = 0;
+                       req.didd_notify.e.Rc =
+                           IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+-                      req.didd_notify.info.callback = didd_callback;
++                      req.didd_notify.info.callback = (void *)didd_callback;
+                       req.didd_notify.info.context = 0;
+                       DAdapter.request((ENTITY *) & req);
+                       if (req.didd_notify.e.Rc != 0xff)
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_4bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/os_4bri.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_4bri.c    2003-09-27 11:38:21.749222000 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -99,6 +99,40 @@
+       return (0);
+ }
++static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
++{
++      dword offset = a->resources.pci.qoffset;
++      dword c_offset = offset * a->xdi_adapter.ControllerNumber;
++
++      a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 2;
++      a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
++      a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
++      a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 0;
++      a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 3;
++      a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;
++
++      /*
++         Set up hardware related pointers
++       */
++      a->xdi_adapter.Address = a->resources.pci.addr[2];      /* BAR2 SDRAM  */
++      a->xdi_adapter.Address += c_offset;
++
++      a->xdi_adapter.Control = a->resources.pci.addr[2];      /* BAR2 SDRAM  */
++
++      a->xdi_adapter.ram = a->resources.pci.addr[2];  /* BAR2 SDRAM  */
++      a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
++      
++      a->xdi_adapter.reset = a->resources.pci.addr[0];        /* BAR0 CONFIG */
++      /*
++         ctlReg contains the register address for the MIPS CPU reset control
++       */
++      a->xdi_adapter.ctlReg = a->resources.pci.addr[3];       /* BAR3 CNTRL  */
++      /*
++         prom contains the register address for FPGA and EEPROM programming
++       */
++      a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
++}
++
+ /*
+ **  BAR0 - MEM - 0x100    - CONFIG MEM
+ **  BAR1 - I/O - 0x100    - UNUSED
+@@ -110,11 +144,11 @@
+ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
+ {
+       int bar, i;
++      byte *p;
+       PADAPTER_LIST_ENTRY quadro_list;
+       diva_os_xdi_adapter_t *diva_current;
+       diva_os_xdi_adapter_t *adapter_list[4];
+       PISDN_ADAPTER Slave;
+-      dword offset;
+       unsigned long bar_length[sizeof(_4bri_bar_length) /
+                                sizeof(_4bri_bar_length[0])];
+       int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
+@@ -142,7 +176,7 @@
+          have to map any BAR before we can access it
+        */
+       if (!_4bri_get_serial_number(a)) {
+-              DBG_ERR(("A: 4BRI can't ger Serial Number"))
++              DBG_ERR(("A: 4BRI can't get Serial Number"))
+               diva_4bri_cleanup_adapter(a);
+               return (-1);
+       }
+@@ -190,7 +224,7 @@
+       for (bar = 0; bar < 4; bar++) {
+               if (bar != 1) { /* ignore I/O */
+                       a->resources.pci.addr[bar] =
+-                          divasa_remap_pci_bar(a->resources.pci.bar[bar],
++                          divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
+                                                bar_length[bar]);
+                       if (!a->resources.pci.addr[bar]) {
+                               DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
+@@ -205,14 +239,15 @@
+        */
+       sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
+-      if (diva_os_register_io_port(1, a->resources.pci.bar[1],
+-                                   bar_length[1], &a->port_name[0])) {
++      if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
++                                   bar_length[1], &a->port_name[0], 1)) {
+               DBG_ERR(("A: 4BRI: can't register bar[1]"))
+               diva_4bri_cleanup_adapter(a);
+               return (-1);
+       }
+-      a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
++      a->resources.pci.addr[1] =
++              (void *) (unsigned long) a->resources.pci.bar[1];
+       /*
+          Set cleanup pointer for base adapter only, so slave adapter
+@@ -265,8 +300,8 @@
+           (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
+       if (!(a->slave_list = quadro_list)) {
+               for (i = 0; i < (tasks - 1); i++) {
+-                      diva_os_free(0, a->slave_adapters[bar]);
+-                      a->slave_adapters[bar] = 0;
++                      diva_os_free(0, a->slave_adapters[i]);
++                      a->slave_adapters[i] = 0;
+               }
+               diva_4bri_cleanup_adapter(a);
+               return (-1);
+@@ -359,60 +394,39 @@
+               prepare_qBri_functions(&a->xdi_adapter);
+       }
++      for (i = 0; i < tasks; i++) {
++              diva_current = adapter_list[i];
++              if (i)
++                      memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
++              diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor); 
++      }
++
+       /*
+          Set up hardware related pointers
+        */
+       a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0];  /* BAR0 CONFIG */
+       a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1]; /* BAR1        */
+-      a->xdi_adapter.Address = a->resources.pci.addr[2];      /* BAR2 SDRAM  */
+-      a->xdi_adapter.ctlReg =
+-          (void *) (unsigned long) a->resources.pci.bar[3];   /* BAR3 CNTRL  */
+-
+-      a->xdi_adapter.reset = a->resources.pci.addr[0];        /* BAR0 CONFIG */
+-      a->xdi_adapter.ram = a->resources.pci.addr[2];  /* BAR2 SDRAM  */
+-      /*
+-         ctlReg contains the register address for the MIPS CPU reset control
+-       */
+-      a->xdi_adapter.ctlReg = a->resources.pci.addr[3];       /* BAR3 CNTRL  */
+-      /*
+-         prom contains the register address for FPGA and EEPROM programming
+-       */
+-      a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
+-      /*
+-         reset contains the base address for the PLX 9054 register set
+-       */
+-      a->xdi_adapter.reset[PLX9054_INTCSR] = 0x00;    /* disable PCI interrupts */
++      a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3];       /* BAR3 CNTRL  */
+-      /*
+-         Replicate addresses to all instances, set shared memory
+-         address for all instances
+-       */
+       for (i = 0; i < tasks; i++) {
++              diva_current = adapter_list[i];
++              diva_4bri_set_addresses(diva_current);
+               Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
+-              offset =
+-                  Slave->ControllerNumber *
+-                  (a->xdi_adapter.MemorySize >> factor);
+-              Slave->Address = &a->xdi_adapter.Address[offset];
+-              Slave->ram = &a->xdi_adapter.ram[offset];
+-              Slave->reset = a->xdi_adapter.reset;
+-              Slave->ctlReg = a->xdi_adapter.ctlReg;
+-              Slave->prom = a->xdi_adapter.prom;
+-              Slave->reset = a->xdi_adapter.reset;
++              Slave->MultiMaster = &a->xdi_adapter;
+               Slave->sdram_bar = a->xdi_adapter.sdram_bar;
+-      }
+-      for (i = 0; i < tasks; i++) {
+-              Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
+-              Slave->ram +=
+-                  ((a->xdi_adapter.MemorySize >> factor) -
+-                   MQ_SHARED_RAM_SIZE);
+-      }
+-      for (i = 1; i < tasks; i++) {
+-              Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
+-              Slave->serialNo =
+-                  ((dword) (Slave->ControllerNumber << 24)) | a->
+-                  xdi_adapter.serialNo;
++              if (i) {
++                      Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
++                                      a->xdi_adapter.serialNo;
+               Slave->cardType = a->xdi_adapter.cardType;
+       }
++      }
++
++      /*
++         reset contains the base address for the PLX 9054 register set
++       */
++      p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++      p[PLX9054_INTCSR] = 0x00;       /* disable PCI interrupts */
++      DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+       /*
+          Set IRQ handler
+@@ -484,8 +498,7 @@
+               if (bar != 1) {
+                       if (a->resources.pci.bar[bar]
+                           && a->resources.pci.addr[bar]) {
+-                              divasa_unmap_pci_bar(a->resources.pci.
+-                                                   addr[bar]);
++                              divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
+                               a->resources.pci.bar[bar] = 0;
+                               a->resources.pci.addr[bar] = 0;
+                       }
+@@ -496,12 +509,12 @@
+          Unregister I/O
+        */
+       if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
+-              diva_os_register_io_port(0, a->resources.pci.bar[1],
++              diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
+                                        _4bri_is_rev_2_card(a->
+                                                            CardOrdinal) ?
+                                        _4bri_v2_bar_length[1] :
+                                        _4bri_bar_length[1],
+-                                       &a->port_name[0]);
++                                       &a->port_name[0], 1);
+               a->resources.pci.bar[1] = 0;
+               a->resources.pci.addr[1] = 0;
+       }
+@@ -776,23 +789,18 @@
+                                                          a->xdi_mbox.
+                                                          data_length);
+                                       if (a->xdi_mbox.data) {
+-                                              byte *src =
+-                                                  a->xdi_adapter.Address;
+-                                              byte *dst =
+-                                                  a->xdi_mbox.data;
+-                                              dword len =
+-                                                  a->xdi_mbox.
+-                                                  data_length;
+-
+-                                              src +=
+-                                                  cmd->command_data.
+-                                                  read_sdram.offset;
++                                              byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
++                                              byte *src = p;
++                                              byte *dst = a->xdi_mbox.data;
++                                              dword len = a->xdi_mbox.data_length;
++
++                                              src += cmd->command_data.read_sdram.offset;
+                                               while (len--) {
+                                                       *dst++ = *src++;
+                                               }
+-                                              a->xdi_mbox.status =
+-                                                  DIVA_XDI_MBOX_BUSY;
++                                              DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
++                                              a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
+                                               ret = 0;
+                                       }
+                               }
+@@ -903,10 +911,12 @@
+                           dword address,
+                           const byte * data, dword length, dword limit)
+ {
+-      byte *mem = IoAdapter->Address;
++      byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
++      byte *mem = p;
+       if (((address + length) >= limit) || !mem) {
+-              DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
++              DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
++              DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
+                        IoAdapter->ANum, address + length))
+               return (-1);
+       }
+@@ -916,6 +926,7 @@
+               *mem++ = *data++;
+       }
++      DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
+       return (0);
+ }
+@@ -926,16 +937,18 @@
+       volatile word *signature;
+       int started = 0;
+       int i;
++      byte *p;
+       /*
+          start adapter
+        */
+       start_qBri_hardware(IoAdapter);
++      p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+       /*
+          wait for signature in shared memory (max. 3 seconds)
+        */
+-      signature = (volatile word *) (&IoAdapter->ram[0x1E]);
++      signature = (volatile word *) (&p[0x1E]);
+       for (i = 0; i < 300; ++i) {
+               diva_os_wait(10);
+@@ -958,10 +971,12 @@
+               DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
+                        IoAdapter->Properties.Name,
+                        READ_WORD(&signature[0])))
++              DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+               (*(IoAdapter->trapFnc)) (IoAdapter);
+               IoAdapter->stop(IoAdapter);
+               return (-1);
+       }
++      DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+       for (i = 0; i < IoAdapter->tasks; i++) {
+               IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
+@@ -997,13 +1012,16 @@
+ #ifdef        SUPPORT_INTERRUPT_TEST_ON_4BRI
+       int i;
+       ADAPTER *a = &IoAdapter->a;
++      byte *p;
+       IoAdapter->IrqCount = 0;
+       if (IoAdapter->ControllerNumber > 0)
+               return (-1);
+-      IoAdapter->reset[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++      p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++      p[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++      DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+       /*
+          interrupt test
+        */
+@@ -1015,20 +1033,23 @@
+       return ((IoAdapter->IrqCount > 0) ? 0 : -1);
+ #else
+       dword volatile *qBriIrq;
++      byte *p;
+       /*
+          Reset on-board interrupt register
+        */
+       IoAdapter->IrqCount = 0;
+-      qBriIrq =
+-          (dword volatile *) (&IoAdapter->
+-                              ctlReg[_4bri_is_rev_2_card
++      p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      qBriIrq = (dword volatile *) (&p[_4bri_is_rev_2_card
+                                      (IoAdapter->
+                                       cardType) ? (MQ2_BREG_IRQ_TEST)
+                                      : (MQ_BREG_IRQ_TEST)]);
+       WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+-      IoAdapter->reset[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++      p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++      p[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
++      DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+       diva_os_wait(100);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/os_bri.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_bri.c     2003-09-27 11:38:21.755221088 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -46,6 +46,27 @@
+                                 dword start_address, dword features);
+ static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a);
++static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a)
++{
++      a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
++      a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
++      a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
++      a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
++      a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
++      a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
++      
++      a->xdi_adapter.ram = a->resources.pci.addr[0];
++      a->xdi_adapter.cfg = a->resources.pci.addr[1];
++      a->xdi_adapter.Address = a->resources.pci.addr[2];
++
++      a->xdi_adapter.reset = a->xdi_adapter.cfg;
++      a->xdi_adapter.port = a->xdi_adapter.Address;
++
++      a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
++
++      a->xdi_adapter.reset += 0x4C;   /* PLX 9050 !! */
++}
++
+ /*
+ **  BAR0 - MEM Addr  - 0x80  - NOT USED
+ **  BAR1 - I/O Addr  - 0x80
+@@ -58,6 +79,7 @@
+       word cmd = 0, cmd_org;
+       byte Bus, Slot;
+       void *hdev;
++      byte *p;
+       /*
+          Set properties
+@@ -123,7 +145,7 @@
+              Map and register resources
+            */
+           if (!(a->resources.pci.addr[0] =
+-               divasa_remap_pci_bar(a->resources.pci.bar[0],
++               divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
+                                     bri_bar_length[0]))) {
+               DBG_ERR(("A: BRI, can't map BAR[0]"))
+               diva_bri_cleanup_adapter(a);
+@@ -133,8 +155,8 @@
+       sprintf(&a->port_name[0], "BRI %02x:%02x",
+               a->resources.pci.bus, a->resources.pci.func);
+-      if (diva_os_register_io_port(1, a->resources.pci.bar[1],
+-                                   bri_bar_length[1], &a->port_name[0])) {
++      if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
++                                   bri_bar_length[1], &a->port_name[0], 1)) {
+               DBG_ERR(("A: BRI, can't register BAR[1]"))
+               diva_bri_cleanup_adapter(a);
+               return (-1);
+@@ -142,8 +164,8 @@
+       a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
+       a->resources.pci.length[1] = bri_bar_length[1];
+-      if (diva_os_register_io_port(1, a->resources.pci.bar[2],
+-                                   bar2_length, &a->port_name[0])) {
++      if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
++                                   bar2_length, &a->port_name[0], 2)) {
+               DBG_ERR(("A: BRI, can't register BAR[2]"))
+               diva_bri_cleanup_adapter(a);
+               return (-1);
+@@ -152,6 +174,11 @@
+       a->resources.pci.length[2] = bar2_length;
+       /*
++         Set all memory areas
++       */
++      diva_bri_set_addresses(a);
++
++      /*
+          Get Serial Number
+        */
+       a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
+@@ -210,15 +237,9 @@
+       a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
+       a->interface.cmd_proc = diva_bri_cmd_card_proc;
+-      a->xdi_adapter.cfg = a->resources.pci.addr[1];
+-      a->xdi_adapter.Address = a->resources.pci.addr[2];
+-
+-      a->xdi_adapter.reset = a->xdi_adapter.cfg;
+-      a->xdi_adapter.port = a->xdi_adapter.Address;
+-
+-      a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
+-      a->xdi_adapter.reset += 0x4C;   /* PLX 9050 !! */
+-      outpp(a->xdi_adapter.reset, 0x41);
++      p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++      outpp(p, 0x41);
++      DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+       prepare_maestra_functions(&a->xdi_adapter);
+@@ -268,11 +289,11 @@
+       for (i = 1; i < 3; i++) {
+               if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
+-                      diva_os_register_io_port(0,
++                      diva_os_register_io_port(a, 0,
+                                                a->resources.pci.bar[i],
+                                                a->resources.pci.
+                                                length[i],
+-                                               &a->port_name[0]);
++                                               &a->port_name[0], i);
+                       a->resources.pci.addr[i] = 0;
+                       a->resources.pci.bar[i] = 0;
+               }
+@@ -314,18 +335,20 @@
+       byte *confIO;
+       word serHi, serLo, *confMem;
+-      confIO = (byte *) a->resources.pci.addr[1];
++      confIO = (byte *) DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
+       serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
+       serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
+       serNo = ((dword) serHi << 16) | (dword) serLo;
++      DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);
+       if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
+               DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
+-              confMem = (word *) a->resources.pci.addr[0];
++              confMem = (word *) DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
+               serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
+               serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
+               serNo = (((dword) serHi) << 16) | ((dword) serLo);
++              DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
+       }
+       DBG_LOG(("Serial Number=%ld", serNo))
+@@ -342,9 +365,9 @@
+       int i;
+       for (i = 1; i < 3; i++) {
+-              diva_os_register_io_port(0, a->resources.pci.bar[i],
++              diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
+                                        a->resources.pci.length[i],
+-                                       &a->port_name[0]);
++                                       &a->port_name[0], i);
+               a->resources.pci.addr[i] = 0;
+       }
+@@ -352,9 +375,9 @@
+               (long) a->xdi_adapter.serialNo);
+       for (i = 1; i < 3; i++) {
+-              if (diva_os_register_io_port(1, a->resources.pci.bar[i],
++              if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
+                                            a->resources.pci.length[i],
+-                                           &a->port_name[0])) {
++                                           &a->port_name[0], i)) {
+                       DBG_ERR(("A: failed to reregister BAR[%d]", i))
+                       return (-1);
+               }
+@@ -493,6 +516,7 @@
+ {
+       byte *addrHi, *addrLo, *ioaddr;
+       dword i;
++      byte *Port;
+       if (!IoAdapter->port) {
+               return (-1);
+@@ -501,13 +525,13 @@
+               DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
+                        IoAdapter->ANum)) return (-1);
+       }
+-      addrHi =
+-          IoAdapter->port +
+-          ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+-      addrLo = IoAdapter->port + ADDR;
+-      ioaddr = IoAdapter->port + DATA;
+       (*(IoAdapter->rstFnc)) (IoAdapter);
+       diva_os_wait(100);
++      Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++      addrHi = Port +
++          ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++      addrLo = Port + ADDR;
++      ioaddr = Port + DATA;
+       /*
+          recover
+        */
+@@ -540,6 +564,8 @@
+       outppw(addrLo, (word) 0);
+       outppw(ioaddr, (word) 0);
++      DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
++
+       /*
+          Forget all outstanding entities
+        */
+@@ -578,16 +604,17 @@
+                          dword address, const byte * data, dword length)
+ {
+       byte *addrHi, *addrLo, *ioaddr;
++      byte *Port;
+       if (!IoAdapter->port) {
+               return (-1);
+       }
+-      addrHi =
+-          IoAdapter->port +
++      Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++      addrHi = Port +
+           ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+-      addrLo = IoAdapter->port + ADDR;
+-      ioaddr = IoAdapter->port + DATA;
++      addrLo = Port + ADDR;
++      ioaddr = Port + DATA;
+       while (length--) {
+               outpp(addrHi, (word) (address >> 16));
+@@ -596,6 +623,7 @@
+               address++;
+       }
++      DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+       return (0);
+ }
+@@ -603,6 +631,7 @@
+ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
+                      dword start_address, dword features)
+ {
++      byte *Port;
+       dword i, test;
+       byte *addrHi, *addrLo, *ioaddr;
+       int started = 0;
+@@ -621,11 +650,11 @@
+       sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
+       DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
+-          addrHi =
+-          IoAdapter->port +
++      Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++      addrHi = Port +
+           ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+-      addrLo = IoAdapter->port + ADDR;
+-      ioaddr = IoAdapter->port + DATA;
++      addrLo = Port + ADDR;
++      ioaddr = Port + DATA;
+       outpp(addrHi,
+             (byte) (
+@@ -633,12 +662,20 @@
+                      BRI_SHARED_RAM_SIZE) >> 16));
+       outppw(addrLo, 0x1e);
+       outppw(ioaddr, 0x00);
++      DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+       /*
+          start the protocol code
+        */
+-      outpp(IoAdapter->ctlReg, 0x08);
++      Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      outpp(Port, 0x08);
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
++      Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++      addrHi = Port +
++          ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++      addrLo = Port + ADDR;
++      ioaddr = Port + DATA;
+       /*
+          wait for signature (max. 3 seconds)
+        */
+@@ -659,6 +696,7 @@
+                       break;
+               }
+       }
++      DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+       if (!started) {
+               DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
+@@ -677,7 +715,9 @@
+       a->ReadyInt = 1;
+       if (IoAdapter->reset) {
+-              outpp(IoAdapter->reset, 0x41);
++              Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++              outpp(Port, 0x41);
++              DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
+       }
+       a->ram_out(a, &PR_RAM->ReadyInt, 1);
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_pri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/os_pri.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/os_pri.c     2003-09-27 11:38:21.763219872 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #include "platform.h"
+ #include "debuglib.h"
+@@ -57,6 +57,34 @@
+       return (0);
+ }
++static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a)
++{
++      a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
++      a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
++      a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
++      a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
++      a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
++      a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
++      a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
++      
++      a->xdi_adapter.Address = a->resources.pci.addr[0];
++      a->xdi_adapter.Control = a->resources.pci.addr[2];
++      a->xdi_adapter.Config = a->resources.pci.addr[4];
++
++      a->xdi_adapter.ram = a->resources.pci.addr[0];
++      a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
++
++      a->xdi_adapter.reset = a->resources.pci.addr[2];
++      a->xdi_adapter.reset += MP_RESET;
++
++      a->xdi_adapter.cfg = a->resources.pci.addr[4];
++      a->xdi_adapter.cfg += MP_IRQ_RESET;
++
++      a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
++
++      a->xdi_adapter.prom = a->resources.pci.addr[3];
++}
++
+ /*
+ **  BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
+ **  BAR1 - DEVICES,                           0x1000
+@@ -117,7 +145,7 @@
+        */
+       for (bar = 0; bar < 5; bar++) {
+               a->resources.pci.addr[bar] =
+-                  divasa_remap_pci_bar(a->resources.pci.bar[bar],
++                  divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
+                                        bar_length[bar]);
+               if (!a->resources.pci.addr[bar]) {
+                       DBG_ERR(("A: A(%d), can't map bar[%d]",
+@@ -128,6 +156,11 @@
+       }
+       /*
++         Set all memory areas
++       */
++      diva_pri_set_addresses(a);
++
++      /*
+          Get Serial Number of this adapter
+        */
+       if (pri_get_serial_number(a)) {
+@@ -194,23 +227,6 @@
+               prepare_pri_functions(&a->xdi_adapter);
+       }
+-      /*
+-         Set all memory areas
+-       */
+-      a->xdi_adapter.Address = a->resources.pci.addr[0];
+-      a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
+-      a->xdi_adapter.ram = a->resources.pci.addr[0];
+-      a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
+-
+-      a->xdi_adapter.reset = a->resources.pci.addr[2];
+-      a->xdi_adapter.reset += MP_RESET;
+-
+-      a->xdi_adapter.prom =
+-          (byte *) (unsigned long) a->resources.pci.bar[3];
+-
+-      a->xdi_adapter.cfg = a->resources.pci.addr[4];
+-      a->xdi_adapter.cfg += MP_IRQ_RESET;
+-
+       a->dsp_mask = diva_pri_detect_dsps(a);
+       /*
+@@ -317,7 +333,7 @@
+ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
+ {
+       dword i;
+-      struct mp_load *boot = (struct mp_load *) IoAdapter->Address;
++      struct mp_load *boot;
+       if (!IoAdapter->Address || !IoAdapter->reset) {
+               return (-1);
+@@ -328,12 +344,20 @@
+               return (-1);
+       }
++      boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+       WRITE_DWORD(&boot->err, 0);
++      DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
++
+       IoAdapter->rstFnc(IoAdapter);
++
+       diva_os_wait(10);
++
++      boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+       i = READ_DWORD(&boot->live);
++
+       diva_os_wait(10);
+       if (i == READ_DWORD(&boot->live)) {
++              DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+               DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
+                        IoAdapter->ANum, IoAdapter->serialNo))
+               return (-1);
+@@ -342,8 +366,10 @@
+               DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
+                        IoAdapter->ANum, IoAdapter->serialNo,
+                        READ_DWORD(&boot->err)))
++              DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+               return (-1);
+       }
++      DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+       /*
+          Forget all outstanding entities
+@@ -383,9 +409,11 @@
+                          dword address,
+                          const byte * data, dword length, dword limit)
+ {
+-      byte *mem = IoAdapter->Address;
++      byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
++      byte *mem = p;
+       if (((address + length) >= limit) || !mem) {
++              DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
+               DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
+                        IoAdapter->ANum, address + length))
+               return (-1);
+@@ -396,6 +424,7 @@
+               *mem++ = *data++;
+       }
++      DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
+       return (0);
+ }
+@@ -405,15 +434,18 @@
+ {
+       dword i;
+       int started = 0;
+-      struct mp_load *boot = (struct mp_load *) IoAdapter->Address;
++      byte *p;
++      struct mp_load *boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+       ADAPTER *a = &IoAdapter->a;
+       if (IoAdapter->Initialized) {
++              DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+               DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
+                        IoAdapter->ANum))
+               return (-1);
+       }
+       if (!boot) {
++              DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+               DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
+                        IoAdapter->serialNo))
+               return (-1);
+@@ -437,17 +469,22 @@
+       }
+       if (!started) {
+-              dword TrapId = READ_DWORD(&IoAdapter->Address[0x80]);
+-              dword debug = READ_DWORD(&IoAdapter->Address[0x1c]);
++              byte *p = (byte *)boot;
++              dword TrapId;
++              dword debug;
++              TrapId = READ_DWORD(&p[0x80]);
++              debug = READ_DWORD(&p[0x1c]);
+               DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
+                        IoAdapter->ANum, READ_DWORD(&boot->signature),
+                        TrapId, debug))
++              DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+               if (IoAdapter->trapFnc) {
+                       (*(IoAdapter->trapFnc)) (IoAdapter);
+               }
+               IoAdapter->stop(IoAdapter);
+               return (-1);
+       }
++      DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+       IoAdapter->Initialized = TRUE;
+@@ -455,8 +492,9 @@
+          Check Interrupt
+        */
+       IoAdapter->IrqCount = 0;
+-      WRITE_DWORD(((dword volatile *) IoAdapter->cfg),
+-                  (dword) ~ 0x03E00000);
++      p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
++      WRITE_DWORD(((dword volatile *) p), (dword) ~ 0x03E00000);
++      DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
+       a->ReadyInt = 1;
+       a->ram_out(a, &PR_RAM->ReadyInt, 1);
+@@ -658,7 +696,8 @@
+                   diva_os_malloc(0, a->xdi_mbox.data_length);
+               if (a->xdi_mbox.data) {
+                       dword *data = (dword *) a->xdi_mbox.data;
+-                      if (!a->xdi_adapter.ram || !a->xdi_adapter.reset ||
++                      if (!a->xdi_adapter.ram ||
++                              !a->xdi_adapter.reset ||
+                           !a->xdi_adapter.cfg) {
+                               *data = 3;
+                       } else if (a->xdi_adapter.trapped) {
+@@ -691,23 +730,18 @@
+                                                          a->xdi_mbox.
+                                                          data_length);
+                                       if (a->xdi_mbox.data) {
+-                                              byte *src =
+-                                                  a->xdi_adapter.Address;
+-                                              byte *dst =
+-                                                  a->xdi_mbox.data;
+-                                              dword len =
+-                                                  a->xdi_mbox.
+-                                                  data_length;
+-
+-                                              src +=
+-                                                  cmd->command_data.
+-                                                  read_sdram.offset;
++                                              byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
++                                              byte *src = p;
++                                              byte *dst = a->xdi_mbox.data;
++                                              dword len = a->xdi_mbox.data_length;
++
++                                              src += cmd->command_data.read_sdram.offset;
+                                               while (len--) {
+                                                       *dst++ = *src++;
+                                               }
+-                                              a->xdi_mbox.status =
+-                                                  DIVA_XDI_MBOX_BUSY;
++                                              a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
++                                              DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
+                                               ret = 0;
+                                       }
+                               }
+@@ -731,27 +765,33 @@
+       byte data[64];
+       int i;
+       dword len = sizeof(data);
+-      volatile byte *config = (byte *) a->resources.pci.addr[4];
+-      volatile byte *flash = (byte *) a->resources.pci.addr[3];
++      volatile byte *config;
++      volatile byte *flash;
+ /*
+  *  First set some GT6401x config registers before accessing the BOOT-ROM
+  */
++      config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+       if (!(config[0xc3c] & 0x08)) {
+               config[0xc3c] |= 0x08;  /* Base Address enable register */
+       }
+       config[LOW_BOOTCS_DREG] = 0x00;
+       config[HI_BOOTCS_DREG] = 0xFF;
++      DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+ /*
+  *  Read only the last 64 bytes of manufacturing data
+  */
+       memset(data, '\0', len);
++      flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
+       for (i = 0; i < len; i++) {
+               data[i] = flash[0x8000 - len + i];
+       }
++      DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
++      config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+       config[LOW_BOOTCS_DREG] = 0xFC; /* Disable FLASH EPROM access */
+       config[HI_BOOTCS_DREG] = 0xFF;
++      DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+       if (memcmp(&data[48], "DIVAserverPR", 12)) {
+ #if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND) /* { */
+@@ -791,22 +831,26 @@
+               /*
+                  Try to read Flash again
+                */
+-              config = (byte *) a->resources.pci.addr[4];
+-              flash = (byte *) a->resources.pci.addr[3];
+               len = sizeof(data);
++              config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+               if (!(config[0xc3c] & 0x08)) {
+                       config[0xc3c] |= 0x08;  /* Base Address enable register */
+               }
+               config[LOW_BOOTCS_DREG] = 0x00;
+               config[HI_BOOTCS_DREG] = 0xFF;
++              DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+               memset(data, '\0', len);
++              flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
+               for (i = 0; i < len; i++) {
+                       data[i] = flash[0x8000 - len + i];
+               }
++              DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
++              config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+               config[LOW_BOOTCS_DREG] = 0xFC;
+               config[HI_BOOTCS_DREG] = 0xFF;
++              DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+               if (memcmp(&data[48], "DIVAserverPR", 12)) {
+                       DBG_ERR(("A: failed to read serial number"))
+@@ -907,7 +951,8 @@
+ */
+ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
+ {
+-      byte *base = a->resources.pci.addr[2];
++      byte *base;
++      byte *p;
+       dword ret = 0;
+       dword row_offset[7] = {
+               0x00000000,
+@@ -921,14 +966,17 @@
+       byte *dsp_addr_port, *dsp_data_port, row_state;
+       int dsp_row = 0, dsp_index, dsp_num;
+-      if (!base || !a->xdi_adapter.reset) {
++      if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
+               return (0);
+       }
+-      *(volatile byte *) (a->xdi_adapter.reset) =
+-          _MP_RISC_RESET | _MP_DSP_RESET;
++      p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++      *(volatile byte *) p = _MP_RISC_RESET | _MP_DSP_RESET;
++      DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+       diva_os_wait(5);
++      base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
++
+       for (dsp_num = 0; dsp_num < 30; dsp_num++) {
+               dsp_row = dsp_num / 7 + 1;
+               dsp_index = dsp_num % 7;
+@@ -947,9 +995,11 @@
+                       ret |= (1 << dsp_num);
+               }
+       }
++      DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
+-      *(volatile byte *) (a->xdi_adapter.reset) =
+-          _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
++      p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
++      *(volatile byte *) p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
++      DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
+       diva_os_wait(5);
+       /*
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/platform.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/platform.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/platform.h   2003-09-27 11:38:21.770218808 +0800
+@@ -1,9 +1,9 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  *
+  * platform.h
+  * 
+  *
+- * Copyright 2000-2002  by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003  by Armin Schindler (mac@melware.de)
+  * Copyright 2000  Eicon Networks 
+  *
+  * This software may be used and distributed according to the terms
+@@ -23,20 +23,27 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
++#include <linux/sched.h>
+ #include <linux/skbuff.h>
++#include <linux/vmalloc.h>
+ #include <linux/proc_fs.h>
+ #include <linux/interrupt.h>
+ #include <linux/smp_lock.h>
++#include <linux/delay.h>
+ #include <asm/types.h>
+ #include <asm/io.h>
+ #include "cardtype.h"
++/* activate debuglib for modules only */
++#ifndef MODULE
++#define DIVA_NO_DEBUGLIB
++#endif
++
+ #define DIVA_INIT_FUNCTION  __init
+ #define DIVA_EXIT_FUNCTION  __exit
+ #define DIVA_USER_MODE_CARD_CONFIG 1
+-#define XDI_USE_XLOG 1
+ #define       USE_EXTENDED_DEBUGS 1
+ #define MAX_ADAPTER     32
+@@ -46,11 +53,6 @@
+ #define MEMORY_SPACE_TYPE  0
+ #define PORT_SPACE_TYPE    1
+-#include "debuglib.h"
+-
+-#define dtrc(p) DBG_PRV0(p)
+-#define dbug(a,p) DBG_PRV1(p)
+-
+ #include <linux/string.h>
+@@ -106,6 +108,36 @@
+ #define _cdecl
+ #endif
++#define MEM_TYPE_RAM          0
++#define MEM_TYPE_PORT         1
++#define MEM_TYPE_PROM         2
++#define MEM_TYPE_CTLREG               3
++#define MEM_TYPE_RESET                4
++#define MEM_TYPE_CFG          5
++#define MEM_TYPE_ADDRESS      6
++#define MEM_TYPE_CONFIG               7
++#define MEM_TYPE_CONTROL      8
++
++#define DIVA_OS_MEM_ATTACH_RAM(a)     ((a)->ram)
++#define DIVA_OS_MEM_ATTACH_PORT(a)    ((a)->port)
++#define DIVA_OS_MEM_ATTACH_PROM(a)    ((a)->prom)
++#define DIVA_OS_MEM_ATTACH_CTLREG(a)  ((a)->ctlReg)
++#define DIVA_OS_MEM_ATTACH_RESET(a)   ((a)->reset)
++#define DIVA_OS_MEM_ATTACH_CFG(a)     ((a)->cfg)
++#define DIVA_OS_MEM_ATTACH_ADDRESS(a) ((a)->Address)
++#define DIVA_OS_MEM_ATTACH_CONFIG(a)  ((a)->Config)
++#define DIVA_OS_MEM_ATTACH_CONTROL(a) ((a)->Control)
++
++#define DIVA_OS_MEM_DETACH_RAM(a, x)  do { } while(0)
++#define DIVA_OS_MEM_DETACH_PORT(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_PROM(a, x) do { } while(0)
++#define DIVA_OS_MEM_DETACH_CTLREG(a, x)       do { } while(0)
++#define DIVA_OS_MEM_DETACH_RESET(a, x)        do { } while(0)
++#define DIVA_OS_MEM_DETACH_CFG(a, x)  do { } while(0)
++#define DIVA_OS_MEM_DETACH_ADDRESS(a, x)      do { } while(0)
++#define DIVA_OS_MEM_DETACH_CONFIG(a, x)       do { } while(0)
++#define DIVA_OS_MEM_DETACH_CONTROL(a, x)      do { } while(0)
++
+ #if !defined(DIM)
+ #define DIM(array)  (sizeof (array)/sizeof ((array)[0]))
+ #endif
+@@ -124,7 +156,11 @@
+ typedef struct _ISDN_ADAPTER* PISDN_ADAPTER;
+ typedef void (* DIVA_DI_PRINTF) (unsigned char *, ...);
+-extern DIVA_DI_PRINTF dprintf;
++#include "debuglib.h"
++
++#define dtrc(p) DBG_PRV0(p)
++#define dbug(a,p) DBG_PRV1(p)
++
+ typedef struct e_info_s E_INFO ;
+@@ -146,8 +182,21 @@
+ /*
+ ** memory allocation
+ */
+-void* diva_os_malloc (unsigned long flags, unsigned long size);
+-void  diva_os_free   (unsigned long flags, void* ptr);
++static __inline__ void* diva_os_malloc (unsigned long flags, unsigned long size)
++{
++      void *ret = NULL;
++
++      if (size) {
++              ret = (void *) vmalloc((unsigned int) size);
++      }
++      return (ret);
++}
++static __inline__ void  diva_os_free   (unsigned long flags, void* ptr)
++{
++      if (ptr) {
++              vfree(ptr);
++      }
++}
+ /*
+ ** use skbuffs for message buffer
+@@ -161,8 +210,17 @@
+ /*
+ ** mSeconds waiting
+ */
+-void diva_os_sleep(dword mSec);
+-void diva_os_wait(dword mSec);
++static __inline__ void diva_os_sleep(dword mSec)
++{
++      unsigned long timeout = HZ * mSec / 1000 + 1;
++
++      set_current_state(TASK_UNINTERRUPTIBLE);
++      schedule_timeout(timeout);
++}
++static __inline__ void diva_os_wait(dword mSec)
++{
++      mdelay(mSec);
++}
+ /*
+ **  PCI Configuration space access
+@@ -173,8 +231,8 @@
+ /*
+ **  I/O Port utilities
+ */
+-int diva_os_register_io_port (int register, unsigned long port, unsigned long length, const char* name);
+-
++int diva_os_register_io_port (void *adapter, int register, unsigned long port,
++                              unsigned long length, const char* name, int id);
+ /*
+ **  I/O port access abstraction
+ */
+@@ -199,14 +257,6 @@
+ #define diva_os_in_irq() in_irq()
+ /*
+-** module locking
+-*/
+-/* 
+-#define DIVA_LOCK_MODULE MOD_INC_USE_COUNT
+-#define DIVA_UNLOCK_MODULE MOD_DEC_USE_COUNT
+-*/
+-
+-/*
+ **  Spin Lock framework
+ */
+ typedef long diva_os_spin_lock_magic_t;
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_4bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/s_4bri.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_4bri.c     2003-09-27 11:38:21.779217440 +0800
+@@ -55,8 +55,8 @@
+  *    check for trapped MIPS 46xx CPU, dump exception frame
+  */
++      base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
+       offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor) ;
+-      base   = IoAdapter->ram - offset - ((IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE) ;
+       TrapID = READ_DWORD(&base[0x80]) ;
+@@ -75,8 +75,10 @@
+       if ( (regs[0] >= offset)
+         && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1) )
+       {
+-              if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
++              if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
++                      DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
+                       return ;
++              }
+               size = offset + (IoAdapter->MemorySize >> factor) - regs[0] ;
+               if ( size > MAX_XLOG_SIZE )
+@@ -89,7 +91,7 @@
+               diva_os_free (0, Xlog) ;
+               IoAdapter->trapped = 2 ;
+       }
+-
++      DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
+ }
+ /* --------------------------------------------------------------------------
+@@ -97,10 +99,10 @@
+        -------------------------------------------------------------------------- */
+ static void reset_qBri_hardware (PISDN_ADAPTER IoAdapter) {
+       word volatile *qBriReset ;
+-      dword  volatile *qBriCntrl ;
++      byte  volatile *qBriCntrl ;
++      byte  volatile *p ;
+-      qBriReset = (word volatile *)IoAdapter->prom ;
+-      qBriCntrl = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]);
++      qBriReset = (word volatile *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
+       WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET) ;
+       diva_os_wait (1) ;
+       WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET) ;
+@@ -109,34 +111,40 @@
+       diva_os_wait (1) ;
+       WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM) ;
+       diva_os_wait (1);
++      DIVA_OS_MEM_DETACH_PROM(IoAdapter, qBriReset);
+-      WRITE_DWORD(qBriCntrl, 0) ;
++      qBriCntrl = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      p = &qBriCntrl[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
++      WRITE_DWORD(p, 0) ;
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, qBriCntrl);
+       DBG_TRC(("resetted board @ reset addr 0x%08lx", qBriReset))
+-      DBG_TRC(("resetted board @ cntrl addr 0x%08lx", qBriCntrl))
+-
++      DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p))
+ }
+ /* --------------------------------------------------------------------------
+               Start Card CPU
+        -------------------------------------------------------------------------- */
+ void start_qBri_hardware (PISDN_ADAPTER IoAdapter) {
+-      dword volatile *qBriReset ;
++      byte volatile *qBriReset ;
++      byte volatile *p ;
+-      qBriReset = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]);
++      p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      qBriReset = &p[(DIVA_4BRI_REVISION(IoAdapter)) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
+       WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK) ;
+       diva_os_wait (2) ;
+       WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK) ;
+       diva_os_wait (10) ;
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+       DBG_TRC(("started processor @ addr 0x%08lx", qBriReset))
+-
+ }
+ /* --------------------------------------------------------------------------
+               Stop Card CPU
+        -------------------------------------------------------------------------- */
+ static void stop_qBri_hardware (PISDN_ADAPTER IoAdapter) {
++      byte volatile *p ;
+       dword volatile *qBriReset ;
+       dword volatile *qBriIrq ;
+       dword volatile *qBriIsacDspReset ;
+@@ -147,16 +155,24 @@
+       if ( IoAdapter->ControllerNumber > 0 )
+               return ;
+- qBriReset = (dword volatile *)(&IoAdapter->ctlReg[reset_offset]) ;
+- qBriIrq   = (dword volatile *)(&IoAdapter->ctlReg[irq_offset]) ;
+- qBriIsacDspReset = (dword volatile *)(&IoAdapter->ctlReg[hw_offset]);
++      p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      qBriReset = (dword volatile *)&p[reset_offset];
++      qBriIsacDspReset = (dword volatile *)&p[hw_offset];
+ /*
+  *    clear interrupt line (reset Local Interrupt Test Register)
+  */
+       WRITE_DWORD(qBriReset, 0) ;
+       WRITE_DWORD(qBriIsacDspReset, 0) ;
+-      IoAdapter->reset[PLX9054_INTCSR] = 0x00 ;       /* disable PCI interrupts */
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
++      
++      p = (byte volatile *)DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++      p[PLX9054_INTCSR] = 0x00 ;      /* disable PCI interrupts */
++      DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++      
++      p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      qBriIrq   = (dword volatile *)&p[irq_offset];
+       WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+       DBG_TRC(("stopped processor @ addr 0x%08lx", qBriReset))
+@@ -260,7 +276,7 @@
+       int            bit ;
+       byte           *File ;
+       dword          code, FileLength ;
+-      word volatile *addr = (word volatile *)IoAdapter->prom ;
++      word volatile *addr = (word volatile *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
+       word           val, baseval = FPGA_CS | FPGA_PROG ;
+@@ -291,8 +307,10 @@
+               File = qBri_check_FPGAsrc (IoAdapter, "ds4bri.bit",
+                                          &FileLength, &code) ;
+       }
+-      if ( !File )
++      if ( !File ) {
++              DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
+               return (0) ;
++      }
+ /*
+  *    prepare download, pulse PROGRAM pin down.
+  */
+@@ -306,6 +324,7 @@
+       {
+               DBG_FTL(("FPGA download: acknowledge for FPGA memory clear missing"))
+               xdiFreeFile (File) ;
++              DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
+               return (0) ;
+       }
+ /*
+@@ -329,6 +348,8 @@
+       diva_os_wait (100) ;
+       val = READ_WORD(addr) ;
++      DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
++
+       if ( !(val & FPGA_BUSY) )
+       {
+               DBG_FTL(("FPGA download: chip remains in busy state (0x%04x)", val))
+@@ -343,12 +364,10 @@
+               Download protocol code to the adapter
+        -------------------------------------------------------------------------- */
+-#define       DOWNLOAD_ADDR(IoAdapter) (&IoAdapter->ram[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)])
+-
+-
+ static int qBri_protocol_load (PISDN_ADAPTER BaseIoAdapter, PISDN_ADAPTER IoAdapter) {
+       PISDN_ADAPTER HighIoAdapter;
++      byte *p;
+       dword  FileLength ;
+       dword *sharedRam, *File;
+       dword  Addr, ProtOffset, SharedRamOffset, i;
+@@ -436,7 +455,8 @@
+               return (0) ;
+       }
+       IoAdapter->downloadAddr = 0 ;
+-      sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
++      p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++      sharedRam = (dword *)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
+       memcpy (sharedRam, File, FileLength) ;
+       DBG_TRC(("Download addr 0x%08x len %ld - virtual 0x%08x",
+@@ -449,10 +469,12 @@
+               DBG_FTL(("File=0x%x, sharedRam=0x%x", File, sharedRam))
+               DBG_BLK(( (char *)File, 256))
+               DBG_BLK(( (char *)sharedRam, 256))
++              DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+               xdiFreeFile (File) ;
+               return (0) ;
+       }
++      DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+       xdiFreeFile (File) ;
+       return (1) ;
+@@ -466,6 +488,7 @@
+       PISDN_ADAPTER IoAdapter;
+       word        i ;
+       dword       *sharedRam ;
++      byte *p;
+       i = 0 ;
+@@ -485,12 +508,14 @@
+                        IoAdapter->downloadAddr + length))
+               return (-1) ;
+       }
+-      sharedRam = (dword*)(&BaseIoAdapter->ram[IoAdapter->downloadAddr &
+-                                               (IoAdapter->MemorySize - 1)]) ;
+-
++      p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
++      sharedRam = (dword*)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
+-      if ( fp->sysFileRead (fp, sharedRam, length) != length )
++      if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
++              DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+               return (-1) ;
++      }
++      DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+       IoAdapter->downloadAddr += length ;
+       IoAdapter->downloadAddr  = (IoAdapter->downloadAddr + 3) & (~3) ;
+@@ -509,6 +534,7 @@
+       word                 download_count, i ;
+       dword               *sharedRam ;
+       dword                FileLength ;
++      byte *p;
+       if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) ) {
+               DBG_FTL(("qBri_telindus_load: %s not found!", DSP_TELINDUS_FILE))
+@@ -553,8 +579,8 @@
+        *      store # of download files extracted from the archive and download table
+        */
+               HighIoAdapter->downloadAddr = HighIoAdapter->DspCodeBaseAddr ;
+-              sharedRam = (dword *)(&BaseIoAdapter->ram[HighIoAdapter->downloadAddr &
+-                                                        (IoAdapter->MemorySize - 1)]) ;
++              p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
++              sharedRam = (dword *)&p[HighIoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
+               WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
+               memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
+@@ -563,6 +589,7 @@
+       if ( memcmp (&sharedRam[1], &download_table, download_count) ) {
+               DBG_FTL(("%s: Dsp Memory test failed!", IoAdapter->Properties.Name))
+       }
++      DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+       return (FileLength) ;
+ }
+@@ -588,6 +615,7 @@
+       dword phys_start_addr;
+       dword end_addr;
+       byte* sharedRam = 0;
++      byte *p;
+   if (task) {
+               if (!(fp = OsOpenFile (task))) {
+@@ -657,18 +685,22 @@
+               }
+               fp->sysFileSeek (fp, 0, OS_SEEK_SET);
+-              sharedRam = &BaseIoAdapter->ram[phys_start_addr];
++              p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
++              sharedRam = &p[phys_start_addr];
+               if ((dword)fp->sysFileRead (fp, sharedRam, FileLength) != FileLength) {
++                      DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+                       OsCloseFile (fp) ;
+                       DBG_ERR(("Can't read image [%s]", task))
+                       return (0);
+               }
++              DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+               OsCloseFile (fp) ;
+   }
++      p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
+       if (!link_addr) {
+-              link_addr = &BaseIoAdapter->ram[OFFS_DSP_CODE_BASE_ADDR];
++              link_addr = &p[OFFS_DSP_CODE_BASE_ADDR];
+       }
+       DBG_TRC(("Write task [%s] link %08lx at %08lx",
+@@ -681,6 +713,8 @@
+       link_addr[2] = (byte)((start_addr >> 16) & 0xff);
+       link_addr[3] = (byte)((start_addr >> 24) & 0xff);
++      DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
++
+       return (task ? &sharedRam[DIVA_MIPS_TASK_IMAGE_LINK_OFFS] : 0);
+ }
+@@ -691,6 +725,7 @@
+       dword         i, offset, controller ;
+       word         *signature ;
+       int           factor = (IoAdapter->tasks == 1) ? 1 : 2;
++      byte *p;
+       PISDN_ADAPTER Slave ;
+@@ -751,7 +786,8 @@
+               Slave->reset   = IoAdapter->reset ;
+               Slave->ctlReg  = IoAdapter->ctlReg ;
+               Slave->prom    = IoAdapter->prom ;
+-              Slave->reset   = IoAdapter->reset ;
++              Slave->Config  = IoAdapter->Config ;
++              Slave->Control = IoAdapter->Control ;
+               if ( !qBri_protocol_load (IoAdapter, Slave) )
+                       return (0) ;
+@@ -782,9 +818,11 @@
+       {
+               Slave = IoAdapter->QuadroList->QuadroAdapter[i] ;
+               Slave->ram += (IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE ;
++              p = DIVA_OS_MEM_ATTACH_RAM(Slave);
+               DBG_TRC(("Configure instance %d shared memory @ 0x%08lx",
+-                       Slave->ControllerNumber, Slave->ram))
+-              memset (Slave->ram, '\0', 256) ;
++                       Slave->ControllerNumber, p))
++              memset (p, '\0', 256) ;
++              DIVA_OS_MEM_DETACH_RAM(Slave, p);
+               diva_configure_protocol (Slave);
+       }
+@@ -792,7 +830,8 @@
+  *    start adapter
+  */
+       start_qBri_hardware (IoAdapter) ;
+-      signature = (word *)(&IoAdapter->ram[0x1E]) ;
++      p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++      signature = (word *)(&p[0x1E]) ;
+ /*
+  *    wait for signature in shared memory (max. 3 seconds)
+  */
+@@ -802,12 +841,14 @@
+               if ( signature[0] == 0x4447 )
+               {
++                      DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+                       DBG_TRC(("Protocol startup time %d.%02d seconds",
+                                (i / 100), (i % 100) ))
+                       return (1) ;
+               }
+       }
++      DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+       DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
+                IoAdapter->Properties.Name, signature[0] >> 16))
+       qBri_cpu_trapped (IoAdapter) ;
+@@ -829,16 +870,23 @@
+       word                    i ;
+       int                     serviced = 0 ;
++      byte *p;
++      p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+-      if ( !(IoAdapter->reset[PLX9054_INTCSR] & 0x80) )
++      if ( !(p[PLX9054_INTCSR] & 0x80) ) {
++              DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+               return (0) ;
++      }
++      DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ /*
+  *    clear interrupt line (reset Local Interrupt Test Register)
+  */
+-      qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
++      p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      qBriIrq = (dword volatile *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
+       WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+       for ( i = 0 ; i < IoAdapter->tasks; ++i )
+       {
+@@ -861,15 +909,21 @@
+        -------------------------------------------------------------------------- */
+ static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) {
+       dword volatile *qBriIrq ;
++      byte *p;
+       if ( IoAdapter->ControllerNumber > 0 )
+               return ;
+-      qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
+ /*
+  *    clear interrupt line (reset Local Interrupt Test Register)
+  */
+-      IoAdapter->reset[PLX9054_INTCSR] = 0x00 ;       /* disable PCI interrupts */
++      p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++      p[PLX9054_INTCSR] = 0x00 ;      /* disable PCI interrupts */
++      DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++
++      p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++      qBriIrq = (dword volatile *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
+       WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
++      DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+ /* --------------------------------------------------------------------------
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_bri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/s_bri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_bri.c      2003-09-27 11:38:21.785216528 +0800
+@@ -45,15 +45,16 @@
+  word *Xlog ;
+  dword   regs[4], i, size ;
+  Xdesc   xlogDesc ;
++ byte *Port;
+ /*
+  * first read pointers and trap frame
+  */
+  if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
+   return ;
+- addrHi =   IoAdapter->port
+-   + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
+- addrLo = IoAdapter->port + ADDR ;
+- ioaddr = IoAdapter->port + DATA ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi =   Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+  outpp (addrHi,  0) ;
+  outppw (addrLo, 0) ;
+  for ( i = 0 ; i < 0x100 ; Xlog[i++] = inppw(ioaddr) ) ;
+@@ -95,21 +96,28 @@
+  outpp  (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + IoAdapter->MemorySize -
+                                             BRI_SHARED_RAM_SIZE)) >> 16)) ;
+  outppw (addrLo, 0x00) ;
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ }
+ /* ---------------------------------------------------------------------
+    Reset hardware
+   --------------------------------------------------------------------- */
+ static void reset_bri_hardware (PISDN_ADAPTER IoAdapter) {
+- outpp (IoAdapter->ctlReg, 0x00) ;
++ byte *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x00) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+ /* ---------------------------------------------------------------------
+    Halt system
+   --------------------------------------------------------------------- */
+ static void stop_bri_hardware (PISDN_ADAPTER IoAdapter) {
+- if (IoAdapter->reset) {
+-  outpp (IoAdapter->reset, 0x00) ; /* disable interrupts ! */
+- }
+- outpp (IoAdapter->ctlReg, 0x00) ;    /* clear int, halt cpu */
++ byte *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ if (p) {
++  outpp (p, 0x00) ; /* disable interrupts ! */
++ }
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x00) ;    /* clear int, halt cpu */
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+ #if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
+ /* ---------------------------------------------------------------------
+@@ -121,6 +129,7 @@
+  byte*  addrHi, *addrLo, *ioaddr ;
+  char   *FileName = &IoAdapter->Protocol[0] ;
+  dword   Addr, i ;
++ byte *Port;
+  /* -------------------------------------------------------------------
+    Try to load protocol code. 'File' points to memory location
+    that does contain entire protocol code
+@@ -173,10 +182,10 @@
+   DBG_FTL(("Protocol code '%s' too big (%ld)", FileName, FileLength))
+   return (0) ;
+  }
+- addrHi =   IoAdapter->port
+-        + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
+- addrLo = IoAdapter->port + ADDR ;
+- ioaddr = IoAdapter->port + DATA ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi =   Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+ /*
+  * set start address for download (use autoincrement mode !)
+  */
+@@ -204,12 +213,14 @@
+   test = inppw (ioaddr) ;
+   if ( test != File[i/2] )
+   {
++   DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+    DBG_FTL(("%s: Memory test failed! (%d - 0x%04X/0x%04X)",
+             IoAdapter->Properties.Name, i, test, File[i/2]))
+    xdiFreeFile (File);
+    return (0) ;
+   }
+  }
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+  xdiFreeFile (File);
+  return (FileLength) ;
+ }
+@@ -290,6 +301,7 @@
+  t_dsp_portable_desc  download_table[DSP_MAX_DOWNLOAD_COUNT] ;
+  word                 download_count ;
+  dword                FileLength ;
++ byte *Port;
+  if (!pinfo) {
+   DBG_ERR (("A: out of memory s_bri at %d", __LINE__))
+   return (0);
+@@ -299,11 +311,11 @@
+   return (0) ;
+  }
+  FileLength     = fp->sysFileSize ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+  pinfo->IoAdapter = IoAdapter ;
+- pinfo->AddrLo    = IoAdapter->port + ADDR ;
+- pinfo->AddrHi    = IoAdapter->port +\
+-     (IoAdapter->Properties.Bus == BUS_PCI ? M_PCI_ADDRH : ADDRH);
+- pinfo->Data = (word*)(IoAdapter->port + DATA) ;
++ pinfo->AddrLo    = Port + ADDR ;
++ pinfo->AddrHi    = Port + (IoAdapter->Properties.Bus == BUS_PCI ? M_PCI_ADDRH : ADDRH);
++ pinfo->Data = (word*)(Port + DATA) ;
+  pinfo->DownloadPos = (IoAdapter->DspCodeBaseAddr +\
+            sizeof(dword) + sizeof(download_table) + 3) & (~3) ;
+  fp->sysLoadDesc = (void *)pinfo;
+@@ -317,6 +329,7 @@
+                         &download_count, NULL, &download_table[0]) ;
+  if ( error )
+  {
++  DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+   DBG_FTL(("download file error: %s", error))
+   OsCloseFile (fp) ;
+   diva_os_free (0, pinfo);
+@@ -335,23 +348,25 @@
+  * copy download table to board
+  */
+  outppw_buffer (pinfo->Data, &download_table[0], sizeof(download_table)) ;
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+  diva_os_free (0, pinfo);
+  return (FileLength) ;
+ }
+ /******************************************************************************/
+ static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
+  dword   i ;
+- byte*  addrHi, *addrLo, *ioaddr ;
++ byte*  addrHi, *addrLo, *ioaddr, *p ;
+  dword   test ;
++ byte *Port;
+  if ( IoAdapter->Properties.Card != CARD_MAE )
+  {
+   return (FALSE) ;
+  }
+- addrHi =   IoAdapter->port \
+-    + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+- addrLo = IoAdapter->port + ADDR ;
+- ioaddr = IoAdapter->port + DATA ;
+  reset_bri_hardware (IoAdapter) ;
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi =   Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+  diva_os_wait (100);
+ /*
+  * recover
+@@ -366,6 +381,7 @@
+           IoAdapter->MemorySize - BRI_SHARED_RAM_SIZE)) >> 16)) ;
+  outppw (addrLo, 0) ;
+  for ( i = 0 ; i < 0x8000 ; outppw (ioaddr, 0), ++i ) ;
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+  diva_os_wait (100) ;
+ /*
+  * download protocol and dsp files
+@@ -396,6 +412,11 @@
+    return (FALSE) ;
+   break ;
+  }
++
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi =   Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+ /*
+  * clear signature
+  */
+@@ -408,13 +429,20 @@
+  * copy parameters
+  */
+  diva_configure_protocol (IoAdapter);
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+ /*
+  * start the protocol code
+  */
+- outpp (IoAdapter->ctlReg, 0x08) ;
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x08) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ /*
+  * wait for signature (max. 3 seconds)
+  */
++ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
++ addrHi =   Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
++ addrLo = Port + ADDR ;
++ ioaddr = Port + DATA ;
+  for ( i = 0 ; i < 300 ; ++i )
+  {
+   diva_os_wait (10) ;
+@@ -424,11 +452,13 @@
+   test = (dword)inppw (ioaddr) ;
+   if ( test == 0x4447 )
+   {
++   DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+    DBG_TRC(("Protocol startup time %d.%02d seconds",
+             (i / 100), (i % 100) ))
+    return (TRUE) ;
+   }
+  }
++ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+  DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
+           IoAdapter->Properties.Name, test))
+  bri_cpu_trapped (IoAdapter) ;
+@@ -441,12 +471,18 @@
+ #endif /* } */
+ /******************************************************************************/
+ static int bri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
+- if ( !(inpp (IoAdapter->ctlReg) & 0x01) )
++ byte *p;
++
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ if ( !(inpp (p) & 0x01) ) {
++  DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+   return (0) ;
++ }
+  /*
+   clear interrupt line
+   */
+- outpp (IoAdapter->ctlReg, 0x08) ;
++ outpp (p, 0x08) ;
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+  IoAdapter->IrqCount++ ;
+  if ( IoAdapter->Initialized ) {
+   diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
+@@ -457,11 +493,16 @@
+   Disable IRQ in the card hardware
+   -------------------------------------------------------------------------- */
+ static void disable_bri_interrupt (PISDN_ADAPTER IoAdapter) {
+- if ( IoAdapter->reset )
+- {
+-  outpp (IoAdapter->reset, 0x00) ; /* disable interrupts ! */
+- }
+- outpp (IoAdapter->ctlReg, 0x00) ; /* clear int, halt cpu */
++ byte *p;
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ if ( p )
++ {
++  outpp (p, 0x00) ; /* disable interrupts ! */
++ }
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
++ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
++ outpp (p, 0x00) ; /* clear int, halt cpu */
++ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+ }
+ /* -------------------------------------------------------------------------
+   Fill card entry points
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_pri.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/s_pri.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/s_pri.c      2003-09-27 11:38:21.791215616 +0800
+@@ -54,7 +54,7 @@
+ /*
+  * check for trapped MIPS 46xx CPU, dump exception frame
+  */
+- base   = IoAdapter->ram - MP_SHARED_RAM_OFFSET ;
++ base   = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+  TrapID = READ_DWORD(&base[0x80]) ;
+  if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) )
+  {
+@@ -68,8 +68,10 @@
+  regs[0] &= IoAdapter->MemorySize - 1 ;
+  if ( (regs[0] < IoAdapter->MemorySize - 1) )
+  {
+-  if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
++  if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
++   DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
+    return ;
++  }
+   size = IoAdapter->MemorySize - regs[0] ;
+   if ( size > MAX_XLOG_SIZE )
+    size = MAX_XLOG_SIZE ;
+@@ -81,24 +83,29 @@
+   diva_os_free (0, Xlog) ;
+   IoAdapter->trapped = 2 ;
+  }
++ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
+ }
+ /* -------------------------------------------------------------------------
+   Hardware reset of PRI card
+   ------------------------------------------------------------------------- */
+ static void reset_pri_hardware (PISDN_ADAPTER IoAdapter) {
+- *IoAdapter->reset = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
++ byte *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
+  diva_os_wait (50) ;
+- *IoAdapter->reset = 0x00 ;
++ *p = 0x00 ;
+  diva_os_wait (50) ;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ }
+ /* -------------------------------------------------------------------------
+   Stop Card Hardware
+   ------------------------------------------------------------------------- */
+ static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) {
+  dword i;
+- dword volatile *cfgReg = (dword volatile *)IoAdapter->cfg ;
++ byte *p;
++ dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+  cfgReg[3] = 0x00000000 ;
+  cfgReg[1] = 0x00000000 ;
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+  IoAdapter->a.ram_out (&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU) ;
+  i = 0 ;
+  while ( (i < 100) && (IoAdapter->a.ram_in (&IoAdapter->a, &RAM->SWReg) != 0) )
+@@ -107,21 +114,25 @@
+   i++ ;
+  }
+  DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
++ cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+  WRITE_DWORD(&cfgReg[0],((dword)(~0x03E00000)));
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+  diva_os_wait (1) ;
+- *IoAdapter->reset = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++ *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
++ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ }
+ #if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
+ /* -------------------------------------------------------------------------
+   Load protocol code to the PRI Card
+   ------------------------------------------------------------------------- */
+-#define DOWNLOAD_ADDR(IoAdapter) \
+- (&IoAdapter->ram[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)])
++#define DOWNLOAD_ADDR(IoAdapter) (IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1))
+ static int pri_protocol_load (PISDN_ADAPTER IoAdapter) {
+  dword  FileLength ;
+  dword *File ;
+  dword *sharedRam ;
+  dword  Addr ;
++ byte *p;
+  if (!(File = (dword *)xdiLoadArchive (IoAdapter, &FileLength, 0))) {
+   return (0) ;
+  }
+@@ -172,14 +183,17 @@
+   return (0) ;
+  }
+  IoAdapter->downloadAddr = MP_UNCACHED_ADDR (MP_PROTOCOL_OFFSET) ;
+- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
+  memcpy (sharedRam, File, FileLength) ;
+  if ( memcmp (sharedRam, File, FileLength) )
+  {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+   DBG_FTL(("%s: Memory test failed!", IoAdapter->Properties.Name))
+   xdiFreeFile (File);
+   return (0) ;
+  }
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+  xdiFreeFile (File);
+  return (1) ;
+ }
+@@ -228,8 +242,8 @@
+ static dword
+ diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
+ {
+-  /* byte* base = a->resources.pci.addr[2]; */
+-  byte* base = IoAdapter->reset - MP_RESET ;
++  byte* base;
++  byte* p;
+   dword ret = 0, DspCount = 0 ;
+   dword row_offset[] = {
+     0x00000000,
+@@ -242,14 +256,18 @@
+   byte *dsp_addr_port, *dsp_data_port, row_state;
+   int dsp_row = 0, dsp_index, dsp_num;
+  IoAdapter->InitialDspInfo &= 0xffff ;
+- /* if (!base || !a->xdi_adapter.reset) */
+-  if (!base || !IoAdapter->reset)
++ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++  if (!p)
+   {
++    DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+     return (0);
+   }
+-  /* *(volatile byte*)(a->xdi_adapter.reset) = _MP_RISC_RESET | _MP_DSP_RESET; */
+-  *(volatile byte*)(IoAdapter->reset) = _MP_RISC_RESET | _MP_DSP_RESET;
++  *(volatile byte*)(p) = _MP_RISC_RESET | _MP_DSP_RESET;
++  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+   diva_os_wait (5) ;
++
++  base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
++  
+   for (dsp_num = 0; dsp_num < 30; dsp_num++) {
+     dsp_row   = dsp_num / 7 + 1;
+     dsp_index = dsp_num % 7;
+@@ -264,8 +282,10 @@
+    DspCount++ ;
+     }
+   }
+-  /* *(volatile byte*)(a->xdi_adapter.reset) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2; */
+-  *(volatile byte*)(IoAdapter->reset) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
++  DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
++
++  p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
++  *(volatile byte*)(p) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
+   diva_os_wait (50) ;
+   /*
+     Verify modules
+@@ -301,7 +321,8 @@
+     ((ret >> (3*7)) & 0x7F) ? "Y" : "N"))
+   DBG_LOG(("+-----------------------+"))
+   DBG_LOG(("DSP's(present-absent):%08x-%08x", ret, ~ret & 0x3fffffff))
+-  *(volatile byte*)(IoAdapter->reset) = 0 ;
++  *(volatile byte*)(p) = 0 ;
++  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+   diva_os_wait (50) ;
+  IoAdapter->InitialDspInfo |= DspCount << 16 ;
+   return (ret);
+@@ -312,6 +333,7 @@
+ static long pri_download_buffer (OsFileHandle *fp, long length, void **addr) {
+  PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)fp->sysLoadDesc ;
+  dword        *sharedRam ;
++ byte *p;
+  *addr = (void *)IoAdapter->downloadAddr ;
+  if ( ((dword) length) > IoAdapter->DspCodeBaseAddr +
+                          IoAdapter->MaxDspCodeSize - IoAdapter->downloadAddr )
+@@ -321,11 +343,15 @@
+            IoAdapter->downloadAddr + length))
+   return (-1) ;
+  }
+- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
+- if ( fp->sysFileRead (fp, sharedRam, length) != length )
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
++ if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+   return (-1) ;
++ }
+  IoAdapter->downloadAddr += length ;
+  IoAdapter->downloadAddr  = (IoAdapter->downloadAddr + 3) & (~3) ;
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+  return (0) ;
+ }
+ /* -------------------------------------------------------------------------
+@@ -338,6 +364,7 @@
+  word                 download_count ;
+  dword               *sharedRam ;
+  dword                FileLength ;
++ byte *p;
+  if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) )
+   return (0) ;
+  IoAdapter->downloadAddr = (IoAdapter->DspCodeBaseAddr
+@@ -363,9 +390,11 @@
+  * store # of separate download files extracted from archive
+  */
+  IoAdapter->downloadAddr = IoAdapter->DspCodeBaseAddr ;
+- sharedRam    = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
++ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
+  WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
+  memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+  return (FileLength) ;
+ }
+ /* -------------------------------------------------------------------------
+@@ -374,14 +403,17 @@
+ #define MIN_DSPS 0x30000000
+ static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
+  dword           i ;
+- struct mp_load *boot = (struct mp_load *)IoAdapter->ram ;
+- if ( IoAdapter->Properties.Card != CARD_MAEP )
++ struct mp_load *boot = (struct mp_load *)DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
++ if ( IoAdapter->Properties.Card != CARD_MAEP ) {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+   return (0) ;
++ }
+  boot->err = 0 ;
+ #if 0
+  IoAdapter->rstFnc (IoAdapter) ;
+ #else
+  if ( MIN_DSPS != (MIN_DSPS & diva_pri_detect_dsps(IoAdapter)) ) { /* makes reset */
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+   DBG_FTL(("%s: DSP error!", IoAdapter->Properties.Name))
+   return (0) ;
+  }
+@@ -394,28 +426,36 @@
+  diva_os_wait (10) ;
+  if ( i == boot->live )
+  {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+   DBG_FTL(("%s: CPU is not alive!", IoAdapter->Properties.Name))
+   return (0) ;
+  }
+  if ( boot->err )
+  {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+   DBG_FTL(("%s: Board Selftest failed!", IoAdapter->Properties.Name))
+   return (0) ;
+  }
+ /*
+  * download protocol and dsp files
+  */
+- if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) )
++ if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) ) {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+   return (0) ;
+- if ( !pri_protocol_load (IoAdapter) )
++ }
++ if ( !pri_protocol_load (IoAdapter) ) {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+   return (0) ;
+- if ( !pri_telindus_load (IoAdapter) )
++ }
++ if ( !pri_telindus_load (IoAdapter) ) {
++  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+   return (0) ;
++ }
+ /*
+  * copy configuration parameters
+  */
+  IoAdapter->ram += MP_SHARED_RAM_OFFSET ;
+- memset (IoAdapter->ram, '\0', 256) ;
++ memset (boot + MP_SHARED_RAM_OFFSET, '\0', 256) ;
+  diva_configure_protocol (IoAdapter);
+ /*
+  * start adapter
+@@ -430,11 +470,13 @@
+   diva_os_wait (10) ;
+   if ( (boot->signature >> 16) == 0x4447 )
+   {
++   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+    DBG_TRC(("Protocol startup time %d.%02d seconds",
+             (i / 100), (i % 100) ))
+    return (1) ;
+   }
+  }
++ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
+  DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
+           IoAdapter->Properties.Name, boot->signature >> 16))
+  pri_cpu_trapped (IoAdapter) ;
+@@ -449,12 +491,16 @@
+   PRI Adapter interrupt Service Routine
+    -------------------------------------------------------------------------- */
+ static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
+- if ( !((READ_DWORD((dword *)IoAdapter->cfg)) & 0x80000000) )
++ byte *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
++ if ( !((READ_DWORD((dword *)cfg)) & 0x80000000) ) {
++  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
+   return (0) ;
++ }
+  /*
+   clear interrupt line
+   */
+- WRITE_DWORD(((dword *)IoAdapter->cfg), (dword)~0x03E00000) ;
++ WRITE_DWORD(((dword *)cfg), (dword)~0x03E00000) ;
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
+  IoAdapter->IrqCount++ ;
+  if ( IoAdapter->Initialized )
+  {
+@@ -466,10 +512,11 @@
+   Disable interrupt in the card hardware
+   ------------------------------------------------------------------------- */
+ static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) {
+- dword volatile *cfgReg = (dword volatile *)IoAdapter->cfg ;
++ dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ;
+  cfgReg[3] = 0x00000000 ;
+  cfgReg[1] = 0x00000000 ;
+  WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ;
++ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+ }
+ /* -------------------------------------------------------------------------
+   Install entry points for PRI Adapter
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/um_idi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/um_idi.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/um_idi.c     2003-09-27 11:38:21.799214400 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #include "platform.h"
+ #include "di_defs.h"
+@@ -37,6 +37,11 @@
+ static int process_idi_ind(divas_um_idi_entity_t * e, byte ind);
+ static int write_return_code(divas_um_idi_entity_t * e, byte rc);
++/*
++ * include queue functions
++ */
++#include "dlist.c"
++
+ /* --------------------------------------------------------------------------
+               MAIN
+    -------------------------------------------------------------------------- */
+@@ -171,7 +176,15 @@
+    ------------------------------------------------------------------------ */
+ int diva_um_idi_nr_of_adapters(void)
+ {
+-      return (diva_q_get_nr_of_entries(&adapter_q));
++      int i = 0;
++      const diva_entity_queue_t * q = &adapter_q;
++      const diva_entity_link_t *diva_current = q->head;
++
++      while (diva_current) {
++              i++;
++              diva_current = diva_current->next;
++      }
++      return(i);
+ }
+ /* ------------------------------------------------------------------------
+Index: linux-2.6.0-test5/drivers/isdn/hardware/eicon/xdi_adapter.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hardware/eicon/xdi_adapter.h   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hardware/eicon/xdi_adapter.h        2003-09-27 11:38:21.800214248 +0800
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
++/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $ */
+ #ifndef __DIVA_OS_XDI_ADAPTER_H__
+ #define __DIVA_OS_XDI_ADAPTER_H__
+@@ -14,7 +14,8 @@
+       dword bar[8];           /* contains context of appropriate BAR Register */
+       void *addr[8];          /* same bar, but mapped into memory */
+       dword length[8];        /* bar length */
+-
++      int mem_type_id[10];
++      unsigned int qoffset;
+       byte irq;
+ } divas_pci_card_resources_t;
+Index: linux-2.6.0-test5/drivers/isdn/hisax/avma1_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/avma1_cs.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/avma1_cs.c    2003-09-27 11:38:21.804213640 +0800
+@@ -438,17 +438,6 @@
+     DEBUG(0, "avma1cs_release(0x%p)\n", link);
+-    /*
+-       If the device is currently in use, we won't release until it
+-       is actually closed.
+-    */
+-    if (link->open) {
+-      DEBUG(1, "avma1_cs: release postponed, '%s' still open\n",
+-            link->dev->dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-
+     /* no unregister function with hisax */
+     HiSax_closecard(local->node.minor);
+@@ -463,7 +452,6 @@
+     
+     if (link->state & DEV_STALE_LINK)
+       avma1cs_detach(link);
+-    
+ } /* avma1cs_release */
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/isdn/hisax/config.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/config.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/config.c      2003-09-27 11:38:21.818211512 +0800
+@@ -2113,7 +2113,7 @@
+ #include <linux/pci.h>
+-static struct pci_device_id hisax_pci_tbl[] __initdata = {
++static struct pci_device_id hisax_pci_tbl[] = {
+ #ifdef CONFIG_HISAX_FRITZPCI
+       {PCI_VENDOR_ID_AVM,      PCI_DEVICE_ID_AVM_A1,           PCI_ANY_ID, PCI_ANY_ID},
+ #endif
+Index: linux-2.6.0-test5/drivers/isdn/hisax/elsa_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/elsa_cs.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/elsa_cs.c     2003-09-27 11:38:21.824210600 +0800
+@@ -442,18 +442,6 @@
+     DEBUG(0, "elsa_cs_release(0x%p)\n", link);
+-    /*
+-       If the device is currently in use, we won't release until it
+-       is actually closed, because until then, we can't be sure that
+-       no one will try to access the device or its data structures.
+-    */
+-    if (link->open) {
+-        DEBUG(1, "elsa_cs: release postponed, '%s' "
+-                   "still open\n", link->dev->dev_name);
+-        link->state |= DEV_STALE_CONFIG;
+-        return;
+-    }
+-
+     /* Unlink the device chain */
+     link->dev = NULL;
+Index: linux-2.6.0-test5/drivers/isdn/hisax/sedlbauer_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hisax/sedlbauer_cs.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hisax/sedlbauer_cs.c        2003-09-27 11:38:21.830209688 +0800
+@@ -535,18 +535,6 @@
+ {
+     DEBUG(0, "sedlbauer_release(0x%p)\n", link);
+-    /*
+-       If the device is currently in use, we won't release until it
+-       is actually closed, because until then, we can't be sure that
+-       no one will try to access the device or its data structures.
+-    */
+-    if (link->open) {
+-      DEBUG(1, "sedlbauer_cs: release postponed, '%s' still open\n",
+-            link->dev->dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-
+     /* Unlink the device chain */
+     link->dev = NULL;
+Index: linux-2.6.0-test5/drivers/isdn/hysdn/hysdn_init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/hysdn/hysdn_init.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/hysdn/hysdn_init.c  2003-09-27 11:38:21.834209080 +0800
+@@ -21,7 +21,7 @@
+ #include "hysdn_defs.h"
+-static struct pci_device_id hysdn_pci_tbl[] __initdata = {
++static struct pci_device_id hysdn_pci_tbl[] = {
+       {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO},
+       {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2},
+       {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO},
+Index: linux-2.6.0-test5/drivers/isdn/i4l/isdn_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/isdn/i4l/isdn_tty.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/isdn/i4l/isdn_tty.c      2003-09-27 11:38:21.858205432 +0800
+@@ -1989,7 +1989,8 @@
+       memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
+       memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
+       if ((get_isdn_dev())->profd)
+-              kill_pg_info(SIGIO, SEND_SIG_PRIV, (get_isdn_dev())->profd->pgrp);
++              kill_pg_info(SIGIO, SEND_SIG_PRIV,
++                      process_group((get_isdn_dev())->profd));
+ }
+ static struct tty_operations modem_ops = {
+Index: linux-2.6.0-test5/drivers/macintosh/adb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/macintosh/adb.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/macintosh/adb.c  2003-09-27 11:38:21.864204520 +0800
+@@ -266,8 +266,7 @@
+ static void
+ __adb_probe_task(void *data)
+ {
+-      adb_probe_task_pid = kernel_thread(adb_probe_task, NULL,
+-              SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL);
+ }
+ static DECLARE_WORK(adb_reset_work, __adb_probe_task, NULL);
+Index: linux-2.6.0-test5/drivers/macintosh/mediabay.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/macintosh/mediabay.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/macintosh/mediabay.c     2003-09-27 11:38:21.871203456 +0800
+@@ -694,8 +694,7 @@
+       /* Startup kernel thread */
+       if (i == 0)
+-              kernel_thread(media_bay_task, NULL,
+-                            CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++              kernel_thread(media_bay_task, NULL, CLONE_KERNEL);
+       return 0;
+Index: linux-2.6.0-test5/drivers/md/dm.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm.c  2003-09-27 11:38:21.876202696 +0800
+@@ -79,7 +79,7 @@
+       int r;
+       /* allocate a slab for the dm_ios */
+-      _io_cache = kmem_cache_create("dm io",
++      _io_cache = kmem_cache_create("dm_io",
+                                     sizeof(struct dm_io), 0, 0, NULL, NULL);
+       if (!_io_cache)
+               return -ENOMEM;
+Index: linux-2.6.0-test5/drivers/md/dm-ioctl-v1.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm-ioctl-v1.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm-ioctl-v1.c 2003-09-27 11:38:21.882201784 +0800
+@@ -459,7 +459,7 @@
+       if (!bdev)
+               return -ENXIO;
+-      param->dev = bdev->bd_dev;
++      param->dev = old_encode_dev(bdev->bd_dev);
+       param->open_count = bdev->bd_openers;
+       bdput(bdev);
+@@ -577,7 +577,7 @@
+       }
+       if (param->flags & DM_PERSISTENT_DEV_FLAG)
+-              r = dm_create_with_minor(MINOR(param->dev), &md);
++              r = dm_create_with_minor(MINOR(old_decode_dev(param->dev)), &md);
+       else
+               r = dm_create(&md);
+@@ -816,7 +816,7 @@
+       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;
++              deps->dev[count++] = old_encode_dev(dd->bdev->bd_dev);
+       }
+       dm_table_put(table);
+       dm_put(md);
+Index: linux-2.6.0-test5/drivers/md/dm-ioctl-v4.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm-ioctl-v4.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm-ioctl-v4.c 2003-09-27 11:38:21.890200568 +0800
+@@ -401,7 +401,7 @@
+                               old_nl->next = (uint32_t) ((void *) nl -
+                                                          (void *) old_nl);
+                       disk = dm_disk(hc->md);
+-                      nl->dev = MKDEV(disk->major, disk->first_minor);
++                      nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
+                       nl->next = 0;
+                       strcpy(nl->name, hc->name);
+@@ -445,7 +445,7 @@
+       if (!bdev)
+               return -ENXIO;
+-      param->dev = MKDEV(disk->major, disk->first_minor);
++      param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
+       /*
+        * Yes, this will be out of date by the time it gets back
+@@ -481,7 +481,7 @@
+               return r;
+       if (param->flags & DM_PERSISTENT_DEV_FLAG)
+-              r = dm_create_with_minor(MINOR(param->dev), &md);
++              r = dm_create_with_minor(MINOR(huge_decode_dev(param->dev)), &md);
+       else
+               r = dm_create(&md);
+@@ -886,7 +886,7 @@
+       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;
++              deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev);
+       }
+       param->data_size = param->data_start + needed;
+Index: linux-2.6.0-test5/drivers/md/dm-table.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/dm-table.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/dm-table.c    2003-09-27 11:38:21.895199808 +0800
+@@ -426,6 +426,8 @@
+       if (sscanf(path, "%u:%u", &major, &minor) == 2) {
+               /* Extract the major/minor numbers */
+               dev = MKDEV(major, minor);
++              if (MAJOR(dev) != major || MINOR(dev) != minor)
++                      return -EOVERFLOW;
+       } else {
+               /* convert the path to a device */
+               if ((r = lookup_device(path, &dev)))
+Index: linux-2.6.0-test5/drivers/md/md.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/md/md.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/md/md.c  2003-09-27 11:38:21.917196464 +0800
+@@ -1450,7 +1450,7 @@
+ static struct kobject *md_probe(dev_t dev, int *part, void *data)
+ {
+       static DECLARE_MUTEX(disks_sem);
+-      int unit = MINOR(dev);
++      int unit = *part;
+       mddev_t *mddev = mddev_find(unit);
+       struct gendisk *disk;
+@@ -1607,9 +1607,6 @@
+       mddev->pers = pers[pnum];
+       spin_unlock(&pers_lock);
+-      blk_queue_make_request(mddev->queue, mddev->pers->make_request);
+-      mddev->queue->queuedata = mddev;
+-
+       err = mddev->pers->run(mddev);
+       if (err) {
+               printk(KERN_ERR "md: pers->run() failed ...\n");
+@@ -1627,6 +1624,10 @@
+       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+       md_wakeup_thread(mddev->thread);
+       set_capacity(disk, mddev->array_size<<1);
++
++      blk_queue_make_request(mddev->queue, mddev->pers->make_request);
++      mddev->queue->queuedata = mddev;
++
+       return 0;
+ }
+@@ -1698,12 +1699,8 @@
+               } else {
+                       if (mddev->ro)
+                               set_disk_ro(disk, 0);
+-                      if (mddev->pers->stop(mddev)) {
+-                              err = -EBUSY;
+-                              if (mddev->ro)
+-                                      set_disk_ro(disk, 1);
+-                              goto out;
+-                      }
++                      blk_queue_make_request(mddev->queue, md_fail_request);
++                      mddev->pers->stop(mddev);
+                       module_put(mddev->pers->owner);
+                       mddev->pers = NULL;
+                       if (mddev->ro)
+@@ -1877,16 +1874,15 @@
+       list_add(&start_rdev->same_set, &pending_raid_disks);
+       for (i = 0; i < MD_SB_DISKS; i++) {
+-              mdp_disk_t *desc;
+-              dev_t dev;
+-
+-              desc = sb->disks + i;
+-              dev = MKDEV(desc->major, desc->minor);
++              mdp_disk_t *desc = sb->disks + i;
++              dev_t dev = MKDEV(desc->major, desc->minor);
+               if (!dev)
+                       continue;
+               if (dev == startdev)
+                       continue;
++              if (MAJOR(dev) != desc->major || MINOR(dev) != desc->minor)
++                      continue;
+               rdev = md_import_device(dev, 0, 0);
+               if (IS_ERR(rdev)) {
+                       printk(KERN_WARNING "md: could not import %s,"
+@@ -2009,8 +2005,11 @@
+ {
+       char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
+       mdk_rdev_t *rdev;
+-      dev_t dev;
+-      dev = MKDEV(info->major,info->minor);
++      dev_t dev = MKDEV(info->major,info->minor);
++
++      if (info->major != MAJOR(dev) || info->minor != MINOR(dev))
++              return -EOVERFLOW;
++
+       if (!mddev->raid_disks) {
+               int err;
+               /* expecting a device which has a superblock */
+@@ -2136,7 +2135,7 @@
+       rdev = find_rdev(mddev, dev);
+       if (!rdev) {
+-              MD_BUG();
++              /* MD_BUG(); */ /* like hell - it's not a driver bug */
+               return -ENXIO;
+       }
+@@ -2409,7 +2408,7 @@
+               /* START_ARRAY doesn't need to lock the array as autostart_array
+                * does the locking, and it could even be a different array
+                */
+-              err = autostart_array(arg);
++              err = autostart_array(new_decode_dev(arg));
+               if (err) {
+                       printk(KERN_WARNING "md: autostart %s failed!\n",
+                               __bdevname(arg, b));
+@@ -2546,18 +2545,18 @@
+                       goto done_unlock;
+               }
+               case HOT_GENERATE_ERROR:
+-                      err = hot_generate_error(mddev, arg);
++                      err = hot_generate_error(mddev, new_decode_dev(arg));
+                       goto done_unlock;
+               case HOT_REMOVE_DISK:
+-                      err = hot_remove_disk(mddev, arg);
++                      err = hot_remove_disk(mddev, new_decode_dev(arg));
+                       goto done_unlock;
+               case HOT_ADD_DISK:
+-                      err = hot_add_disk(mddev, arg);
++                      err = hot_add_disk(mddev, new_decode_dev(arg));
+                       goto done_unlock;
+               case SET_DISK_FAULTY:
+-                      err = set_disk_faulty(mddev, arg);
++                      err = set_disk_faulty(mddev, new_decode_dev(arg));
+                       goto done_unlock;
+               case RUN_ARRAY:
+Index: linux-2.6.0-test5/drivers/mtd/maps/sa1100-flash.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/mtd/maps/sa1100-flash.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/mtd/maps/sa1100-flash.c  2003-09-27 11:38:21.925195248 +0800
+@@ -654,28 +654,21 @@
+       }, {
+               .name           = "SIMpad kernel",
+               .size           = 0x00100000,
+-              .offset         = 0x00080000,
+-      }, {
+-#ifdef CONFIG_JFFS2_FS
+-              .name           = "SIMpad root jffs2",
+-              .size           = MTDPART_SIZ_FULL,
+-              .offset         = 0x00180000,
+-#else
+-              .name           = "SIMpad initrd",
+-              .size           = 0x00300000,
+-              .offset         = 0x00180000,
++              .offset         = MTDPART_OFS_APPEND,
+       }, {
++#ifdef CONFIG_ROOT_CRAMFS
+               .name           = "SIMpad root cramfs",
+-              .size           = 0x00300000,
+-              .offset         = 0x00480000,
+-      }, {
+-              .name           = "SIMpad usr cramfs",
+-              .size           = 0x005c0000,
+-              .offset         = 0x00780000,
++              .size           =0x00D80000,
++              .offset         = MTDPART_OFS_APPEND
++
+       }, {
+-              .name           = "SIMpad usr local",
++              .name           = "SIMpad local jffs2",
++              .size           = MTDPART_SIZ_FULL,
++              .offset         = MTDPART_OFS_APPEND
++#else
++              .name           = "SIMpad root jffs2",
+               .size           = MTDPART_SIZ_FULL,
+-              .offset         = 0x00d40000,
++              .offset         = MTDPART_OFS_APPEND
+ #endif
+       }
+ };
+@@ -1244,8 +1237,10 @@
+       }
+       if (machine_is_simpad()) {
+               info[0].base = SA1100_CS0_PHYS;
+-              info[0].size = SZ_32M;
+-              nr = 1;
++              info[0].size = SZ_16M;
++              info[1].base = SA1100_CS1_PHYS;
++              info[1].size = SZ_16M;
++              nr = 2;
+       }
+       if (machine_is_stork()) {
+               info[0].base = SA1100_CS0_PHYS;
+Index: linux-2.6.0-test5/drivers/mtd/mtd_blkdevs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/mtd/mtd_blkdevs.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/mtd/mtd_blkdevs.c        2003-09-27 11:38:21.929194640 +0800
+@@ -397,8 +397,7 @@
+       tr->blkcore_priv->rq->queuedata = tr;
+-      ret = kernel_thread(mtd_blktrans_thread, tr, 
+-                          CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
++      ret = kernel_thread(mtd_blktrans_thread, tr, CLONE_KERNEL);
+       if (ret < 0) {
+               blk_cleanup_queue(tr->blkcore_priv->rq);
+               unregister_blkdev(tr->major, tr->name);
+Index: linux-2.6.0-test5/drivers/net/3c501.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c501.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c501.c      2003-09-27 11:38:21.936193576 +0800
+@@ -123,6 +123,7 @@
+ #include <linux/config.h>     /* for CONFIG_IP_MULTICAST */
+ #include <linux/spinlock.h>
+ #include <linux/ethtool.h>
++#include <linux/delay.h>
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+@@ -241,7 +242,7 @@
+       if (dev->irq < 2)
+       {
+-              unsigned long irq_mask, delay;
++              unsigned long irq_mask;
+               irq_mask = probe_irq_on();
+               inb(RX_STATUS);         /* Clear pending interrupts. */
+@@ -250,8 +251,7 @@
+               outb(0x00, AX_CMD);
+-              delay = jiffies + HZ/50;
+-              while (time_before(jiffies, delay)) ;
++              mdelay(20);
+               autoirq = probe_irq_off(irq_mask);
+               if (autoirq == 0)
+Index: linux-2.6.0-test5/drivers/net/3c505.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c505.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c505.c      2003-09-27 11:38:21.950191448 +0800
+@@ -298,17 +298,13 @@
+               set_hsf(dev, HSF_PCB_NAK);
+       }
+       outb_control(adapter->hcr_val | ATTN | DIR, dev);
+-      timeout = jiffies + 1*HZ/100;
+-      while (time_before_eq(jiffies, timeout));
++      mdelay(10);
+       outb_control(adapter->hcr_val & ~ATTN, dev);
+-      timeout = jiffies + 1*HZ/100;
+-      while (time_before_eq(jiffies, timeout));
++      mdelay(10);
+       outb_control(adapter->hcr_val | FLSH, dev);
+-      timeout = jiffies + 1*HZ/100;
+-      while (time_before_eq(jiffies, timeout));
++      mdelay(10);
+       outb_control(adapter->hcr_val & ~FLSH, dev);
+-      timeout = jiffies + 1*HZ/100;
+-      while (time_before_eq(jiffies, timeout));
++      mdelay(10);
+       outb_control(orig_hcr, dev);
+       if (!start_receive(dev, &adapter->tx_pcb))
+Index: linux-2.6.0-test5/drivers/net/3c515.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c515.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c515.c      2003-09-27 11:38:21.970188408 +0800
+@@ -59,7 +59,6 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/isapnp.h>
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
+Index: linux-2.6.0-test5/drivers/net/3c59x.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/3c59x.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/3c59x.c      2003-09-27 11:38:23.696925904 +0800
+@@ -1063,6 +1063,22 @@
+       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 @@
+       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);
+Index: linux-2.6.0-test5/drivers/net/ac3200.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ac3200.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ac3200.c     2003-09-27 11:38:23.896895504 +0800
+@@ -25,6 +25,7 @@
+       "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/acenic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/acenic.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/acenic.c     2003-09-27 11:38:24.038873920 +0800
+@@ -1757,7 +1757,8 @@
+        * Wait for the firmware to spin up - max 3 seconds.
+        */
+       myjif = jiffies + 3 * HZ;
+-      while (time_before(jiffies, myjif) && !ap->fw_running);
++      while (time_before(jiffies, myjif) && !ap->fw_running)
++              cpu_relax();
+       if (!ap->fw_running) {
+               printk(KERN_ERR "%s: Firmware NOT running!\n", dev->name);
+Index: linux-2.6.0-test5/drivers/net/arm/ether00.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/arm/ether00.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/arm/ether00.c        2003-09-27 11:38:24.188851120 +0800
+@@ -19,7 +19,7 @@
+  */
+ /* includes */
+-
++#include <linux/config.h>
+ #include <linux/pci.h>
+ #include <linux/netdevice.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_3ad.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_3ad.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_3ad.c   2003-09-27 11:38:24.267839112 +0800
+@@ -37,6 +37,16 @@
+  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+  *    - Renamed bond_3ad_link_status_changed() to
+  *      bond_3ad_handle_link_change() for compatibility with TLB.
++ *
++ * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
++ *    - Fix long fail over time when releasing last slave of an active
++ *      aggregator - send LACPDU on unbind of slave to tell partner this
++ *      port is no longer aggregatable.
++ *
++ * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
++ *    - Send LACPDU as highest priority packet to further fix the above
++ *      problem on very high Tx traffic load where packets may get dropped
++ *      by the slave.
+  */
+ #include <linux/skbuff.h>
+@@ -45,6 +55,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/ethtool.h>
+ #include <linux/if_bonding.h>
++#include <linux/pkt_sched.h>
+ #include "bonding.h"
+ #include "bond_3ad.h"
+@@ -905,6 +916,7 @@
+       skb->mac.raw = skb->data;
+       skb->nh.raw = skb->data + ETH_HLEN;
+       skb->protocol = PKT_TYPE_LACPDU;
++      skb->priority = TC_PRIO_CONTROL;
+       lacpdu_header = (struct lacpdu_header *)skb_put(skb, length);
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_3ad.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_3ad.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_3ad.h   2003-09-27 11:38:24.334828928 +0800
+@@ -165,7 +165,7 @@
+       //  = 0x02  (marker response information)
+       u8 marker_length;        //  = 0x16
+       u16 requester_port;      //   The number assigned to the port by the requester
+-      struct mac_addr requester_system;      //   The requester\92s system id
++      struct mac_addr requester_system;      //   The requester's system id
+       u32 requester_transaction_id;   //   The transaction id allocated by the requester,
+       u16 pad;                 //  = 0
+       u8 tlv_type_terminator;      //  = 0x00
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_alb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_alb.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_alb.c   2003-09-27 11:38:24.397819352 +0800
+@@ -17,10 +17,22 @@
+  *
+  * The full GNU General Public License is included in this distribution in the
+  * file called LICENSE.
++ *
++ *
++ * Changes:
++ *
++ * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Fixed signed/unsigned calculation errors that caused load sharing
++ *      to collapse to one slave under very heavy UDP Tx stress.
++ *
++ * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
++ *    - Add support for setting bond's MAC address with special
++ *      handling required for ALB/TLB.
+  */
+ #include <linux/skbuff.h>
+ #include <linux/netdevice.h>
++#include <linux/etherdevice.h>
+ #include <linux/pkt_sched.h>
+ #include <linux/spinlock.h>
+ #include <linux/slab.h>
+@@ -246,7 +258,7 @@
+ {
+       struct slave *slave;
+       struct slave *least_loaded;
+-      u32 curr_gap, max_gap;
++      s64 curr_gap, max_gap;
+       /* Find the first enabled slave */
+       slave = bond_get_first_slave(bond);
+@@ -262,15 +274,15 @@
+       }
+       least_loaded = slave;
+-      max_gap = (slave->speed * 1000000) -
+-                (SLAVE_TLB_INFO(slave).load * 8);
++      max_gap = (s64)(slave->speed * 1000000) -
++                      (s64)(SLAVE_TLB_INFO(slave).load * 8);
+       /* Find the slave with the largest gap */
+       slave = bond_get_next_slave(bond, slave);
+       while (slave) {
+               if (SLAVE_IS_OK(slave)) {
+-                      curr_gap = (slave->speed * 1000000) -
+-                                 (SLAVE_TLB_INFO(slave).load * 8);
++                      curr_gap = (s64)(slave->speed * 1000000) -
++                                      (s64)(SLAVE_TLB_INFO(slave).load * 8);
+                       if (max_gap < curr_gap) {
+                               least_loaded = slave;
+                               max_gap = curr_gap;
+@@ -936,10 +948,11 @@
+ }
+ /* hw is a boolean parameter that determines whether we should try and
+- * set the hw address of the hw as well as the hw address of the net_device
++ * set the hw address of the device as well as the hw address of the
++ * net_device
+  */
+ static int
+-alb_set_mac_addr(struct slave *slave, u8 addr[], int hw)
++alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
+ {
+       struct net_device *dev = NULL;
+       struct sockaddr s_addr;
+@@ -947,16 +960,16 @@
+       dev = slave->dev;
+       if (!hw) {
+-              memcpy(dev->dev_addr, addr, ETH_ALEN);
++              memcpy(dev->dev_addr, addr, dev->addr_len);
+               return 0;
+       }
+       /* for rlb each slave must have a unique hw mac addresses so that */
+       /* each slave will receive packets destined to a different mac */
+-      memcpy(s_addr.sa_data, addr, ETH_ALEN);
++      memcpy(s_addr.sa_data, addr, dev->addr_len);
+       s_addr.sa_family = dev->type;
+       if (dev->set_mac_address(dev, &s_addr)) {
+-              printk(KERN_DEBUG "bonding: Error: alb_set_mac_addr:"
++              printk(KERN_DEBUG "bonding: Error: alb_set_slave_mac_addr:"
+                                 " dev->set_mac_address of dev %s failed!"
+                                 " ALB mode requires that the base driver"
+                                 " support setting the hw address also when"
+@@ -980,8 +993,8 @@
+       slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
+       memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
+-      alb_set_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
+-      alb_set_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
++      alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
++      alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
+       /* fasten the change in the switch */
+       if (SLAVE_IS_OK(slave1)) {
+@@ -1146,8 +1159,8 @@
+       }
+       if (tmp_slave1) {
+-              alb_set_mac_addr(slave, tmp_slave1->perm_hwaddr,
+-                               bond->alb_info.rlb_enabled);
++              alb_set_slave_mac_addr(slave, tmp_slave1->perm_hwaddr,
++                                     bond->alb_info.rlb_enabled);
+               printk(KERN_WARNING "bonding: Warning: the hw address "
+                      "of slave %s is in use by the bond; "
+@@ -1165,6 +1178,67 @@
+       return 0;
+ }
++/**
++ * alb_set_mac_address
++ * @bond:
++ * @addr:
++ *
++ * In TLB mode all slaves are configured to the bond's hw address, but set
++ * their dev_addr field to different addresses (based on their permanent hw
++ * addresses).
++ *
++ * For each slave, this function sets the interface to the new address and then
++ * changes its dev_addr field to its previous value.
++ * 
++ * Unwinding assumes bond's mac address has not yet changed.
++ */
++static inline int
++alb_set_mac_address(struct bonding *bond, void *addr)
++{
++      struct sockaddr sa;
++      struct slave *slave;
++      char tmp_addr[ETH_ALEN];
++      int error;
++
++      if (bond->alb_info.rlb_enabled) {
++              return 0;
++      }
++
++      slave = bond_get_first_slave(bond);
++      for (; slave; slave = bond_get_next_slave(bond, slave)) {
++              if (slave->dev->set_mac_address == NULL) {
++                      error = -EOPNOTSUPP;
++                      goto unwind;
++              }
++
++              /* save net_device's current hw address */
++              memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
++
++              error = slave->dev->set_mac_address(slave->dev, addr);
++
++              /* restore net_device's hw address */
++              memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
++
++              if (error) {
++                      goto unwind;
++              }
++      }
++
++      return 0;
++
++unwind:
++      memcpy(sa.sa_data, bond->device->dev_addr, bond->device->addr_len);
++      sa.sa_family = bond->device->type;
++      slave = bond_get_first_slave(bond);
++      for (; slave; slave = bond_get_next_slave(bond, slave)) {
++              memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
++              slave->dev->set_mac_address(slave->dev, &sa);
++              memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
++      }
++
++      return error;
++}
++
+ /************************ exported alb funcions ************************/
+ int
+@@ -1255,16 +1329,15 @@
+               hash_size = 16;
+               break;
+-#ifdef FIXME
+       case ETH_P_IPX:
+-              if (skb->nh.ipxh->ipx_checksum !=
++              if (ipx_hdr(skb)->ipx_checksum !=
+                   __constant_htons(IPX_NO_CHECKSUM)) {
+                       /* something is wrong with this packet */
+                       do_tx_balance = 0;
+                       break;
+               }
+-              if (skb->nh.ipxh->ipx_type !=
++              if (ipx_hdr(skb)->ipx_type !=
+                   __constant_htons(IPX_TYPE_NCP)) {
+                       /* The only protocol worth balancing in
+                        * this family since it has an "ARP" like
+@@ -1277,7 +1350,6 @@
+               hash_start = (char*)eth_data->h_dest;
+               hash_size = ETH_ALEN;
+               break;
+-#endif
+       case ETH_P_ARP:
+               do_tx_balance = 0;
+@@ -1437,8 +1509,8 @@
+ {
+       int err = 0;
+-      err = alb_set_mac_addr(slave, slave->perm_hwaddr,
+-                              bond->alb_info.rlb_enabled);
++      err = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
++                                   bond->alb_info.rlb_enabled);
+       if (err) {
+               return err;
+       }
+@@ -1562,10 +1634,61 @@
+               alb_swap_mac_addr(bond, swap_slave, new_slave);
+       } else {
+               /* set the new_slave to the bond mac address */
+-              alb_set_mac_addr(new_slave, bond->device->dev_addr,
+-                               bond->alb_info.rlb_enabled);
++              alb_set_slave_mac_addr(new_slave, bond->device->dev_addr,
++                                     bond->alb_info.rlb_enabled);
+               /* fasten bond mac on new current slave */
+               alb_send_learning_packets(new_slave, bond->device->dev_addr);
+       }
+ }
++int
++bond_alb_set_mac_address(struct net_device *dev, void *addr)
++{
++      struct bonding *bond = dev->priv;
++      struct sockaddr *sa = addr;
++      struct slave *swap_slave = NULL;
++      int error = 0;
++
++      if (!is_valid_ether_addr(sa->sa_data)) {
++              return -EADDRNOTAVAIL;
++      }
++
++      error = alb_set_mac_address(bond, addr);
++      if (error) {
++              return error;
++      }
++
++      memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++
++      /* If there is no current_slave there is nothing else to do.
++       * Otherwise we'll need to pass the new address to it and handle
++       * duplications.
++       */
++      if (bond->current_slave == NULL) {
++              return 0;
++      }
++
++      swap_slave = bond_get_first_slave(bond);
++      while (swap_slave) {
++              if (!memcmp(swap_slave->dev->dev_addr, dev->dev_addr, ETH_ALEN)) {
++                      break;
++              }
++              swap_slave = bond_get_next_slave(bond, swap_slave);
++      }
++
++      if (swap_slave) {
++              alb_swap_mac_addr(bond, swap_slave, bond->current_slave);
++      } else {
++              alb_set_slave_mac_addr(bond->current_slave, dev->dev_addr,
++                                     bond->alb_info.rlb_enabled);
++
++              alb_send_learning_packets(bond->current_slave, dev->dev_addr);
++              if (bond->alb_info.rlb_enabled) {
++                      /* inform clients mac address has changed */
++                      rlb_req_update_slave_clients(bond, bond->current_slave);
++              }
++      }
++
++      return 0;
++}
++
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_alb.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_alb.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_alb.h   2003-09-27 11:38:24.460809776 +0800
+@@ -17,6 +17,13 @@
+  *
+  * The full GNU General Public License is included in this distribution in the
+  * file called LICENSE.
++ *
++ *
++ * Changes:
++ *
++ * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
++ *    - Add support for setting bond's MAC address with special
++ *      handling required for ALB/TLB.
+  */
+ #ifndef __BOND_ALB_H__
+@@ -122,6 +129,7 @@
+ void bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave);
+ int bond_alb_xmit(struct sk_buff *skb, struct net_device *dev);
+ void bond_alb_monitor(struct bonding *bond);
++int bond_alb_set_mac_address(struct net_device *dev, void *addr);
+ #endif /* __BOND_ALB_H__ */
+Index: linux-2.6.0-test5/drivers/net/bonding/bonding.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bonding.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bonding.h    2003-09-27 11:38:24.500803696 +0800
+@@ -99,10 +99,10 @@
+       rwlock_t ptrlock;
+       struct timer_list mii_timer;
+       struct timer_list arp_timer;
+-      struct net_device_stats *stats;
++      struct net_device_stats stats;
+ #ifdef CONFIG_PROC_FS
+-      struct proc_dir_entry *bond_proc_dir;
+-      struct proc_dir_entry *bond_proc_info_file;
++      struct proc_dir_entry *bond_proc_file;
++      char procdir_name[IFNAMSIZ];
+ #endif /* CONFIG_PROC_FS */
+       struct list_head bond_list;
+       struct net_device *device;
+Index: linux-2.6.0-test5/drivers/net/bonding/bond_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/bonding/bond_main.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/bonding/bond_main.c  2003-09-27 11:38:24.626784544 +0800
+@@ -278,7 +278,7 @@
+  *      bonding round-robin mode ignoring links after failover/recovery
+  *
+  * 2003/03/17 - Jay Vosburgh <fubar at us dot ibm dot com>
+- *    - kmalloc fix (GPF_KERNEL to GPF_ATOMIC) reported by
++ *    - kmalloc fix (GFP_KERNEL to GFP_ATOMIC) reported by
+  *      Shmulik dot Hen at intel.com.
+  *    - Based on discussion on mailing list, changed use of
+  *      update_slave_cnt(), created wrapper functions for adding/removing
+@@ -323,22 +323,22 @@
+  * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
+  *            Tsippy Mendelson <tsippy.mendelson at intel dot com> and
+  *            Shmulik Hen <shmulik.hen at intel dot com>
+- *    - Added support for IEEE 802.3ad Dynamic link aggregation mode.
++ *    - Added support for IEEE 802.3ad Dynamic link aggregation mode.
+  *
+  * 2003/05/01 - Amir Noam <amir.noam at intel dot com>
+- *    - Added ABI version control to restore compatibility between
+- *      new/old ifenslave and new/old bonding.
++ *    - Added ABI version control to restore compatibility between
++ *      new/old ifenslave and new/old bonding.
+  *
+  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+- *    - Fixed bug in bond_release_all(): save old value of current_slave
+- *      before setting it to NULL.
+- *    - Changed driver versioning scheme to include version number instead
+- *      of release date (that is already in another field). There are 3
+- *      fields X.Y.Z where:
+- *            X - Major version - big behavior changes
+- *            Y - Minor version - addition of features
+- *            Z - Extra version - minor changes and bug fixes
+- *      The current version is 1.0.0 as a base line.
++ *    - Fixed bug in bond_release_all(): save old value of current_slave
++ *      before setting it to NULL.
++ *    - Changed driver versioning scheme to include version number instead
++ *      of release date (that is already in another field). There are 3
++ *      fields X.Y.Z where:
++ *            X - Major version - big behavior changes
++ *            Y - Minor version - addition of features
++ *            Z - Extra version - minor changes and bug fixes
++ *      The current version is 1.0.0 as a base line.
+  *
+  * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
+  *            Amir Noam <amir.noam at intel dot com>
+@@ -371,6 +371,61 @@
+  *    - Added support for Adaptive load balancing mode which is
+  *      equivalent to Transmit load balancing + Receive load balancing.
+  *      new version - 2.2.0
++ *
++ * 2003/05/15 - Jay Vosburgh <fubar at us dot ibm dot com>
++ *    - Applied fix to activebackup_arp_monitor posted to bonding-devel
++ *      by Tony Cureington <tony.cureington * hp_com>.  Fixes ARP
++ *      monitor endless failover bug.  Version to 2.2.10
++ *
++ * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
++ *    - Fixed bug in ABI version control - Don't commit to a specific
++ *      ABI version if receiving unsupported ioctl commands.
++ *
++ * 2003/05/22 - Jay Vosburgh <fubar at us dot ibm dot com>
++ *    - Fix ifenslave -c causing bond to loose existing routes;
++ *      added bond_set_mac_address() that doesn't require the
++ *      bond to be down.
++ *    - In conjunction with fix for ifenslave -c, in
++ *      bond_change_active(), changing to the already active slave
++ *      is no longer an error (it successfully does nothing).
++ *
++ * 2003/06/30 - Amir Noam <amir.noam at intel dot com>
++ *    - Fixed bond_change_active() for ALB/TLB modes.
++ *      Version to 2.2.14.
++ *
++ * 2003/07/29 - Amir Noam <amir.noam at intel dot com>
++ *    - Fixed ARP monitoring bug.
++ *      Version to 2.2.15.
++ *
++ * 2003/07/31 - Willy Tarreau <willy at ods dot org>
++ *    - Fixed kernel panic when using ARP monitoring without
++ *      setting bond's IP address.
++ *      Version to 2.2.16.
++ *
++ * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
++ *    - Back port from 2.6: use alloc_netdev(); fix /proc handling;
++ *      made stats a part of bond struct so no need to allocate
++ *      and free it separately; use standard list operations instead
++ *      of pre-allocated array of bonds.
++ *      Version to 2.3.0.
++ *
++ * 2003/08/07 - Jay Vosburgh <fubar at us dot ibm dot com>,
++ *           Amir Noam <amir.noam at intel dot com> and
++ *           Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Propagating master's settings: Distinguish between modes that
++ *      use a primary slave from those that don't, and propagate settings
++ *      accordingly; Consolidate change_active opeartions and add
++ *      reselect_active and find_best opeartions; Decouple promiscuous
++ *      handling from the multicast mode setting; Add support for changing
++ *      HW address and MTU with proper unwind; Consolidate procfs code,
++ *      add CHANGENAME handler; Enhance netdev notification handling.
++ *      Version to 2.4.0.
++ *
++ * 2003/09/15 - Stephen Hemminger <shemminger at osdl dot org>,
++ *           Amir Noam <amir.noam at intel dot com>
++ *    - Convert /proc to seq_file interface.
++ *      Change /proc/net/bondX/info to /proc/net/bonding/bondX.
++ *      Set version to 2.4.1.
+  */
+ #include <linux/config.h>
+@@ -404,6 +459,8 @@
+ #include <linux/skbuff.h>
+ #include <net/sock.h>
+ #include <linux/rtnetlink.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/if_bonding.h>
+ #include <linux/smp.h>
+@@ -415,10 +472,10 @@
+ #include "bond_3ad.h"
+ #include "bond_alb.h"
+-#define DRV_VERSION           "2.2.0"
+-#define DRV_RELDATE           "April 15, 2003"
+-#define DRV_NAME              "bonding"
+-#define DRV_DESCRIPTION               "Ethernet Channel Bonding Driver"
++#define DRV_VERSION   "2.4.1"
++#define DRV_RELDATE   "September 15, 2003"
++#define DRV_NAME      "bonding"
++#define DRV_DESCRIPTION       "Ethernet Channel Bonding Driver"
+ static const char *version =
+ DRV_NAME ".c:v" DRV_VERSION " (" DRV_RELDATE ")\n";
+@@ -436,6 +493,11 @@
+ #define MAX_ARP_IP_TARGETS 16
+ #endif
++#define USES_PRIMARY(mode) \
++              (((mode) == BOND_MODE_ACTIVEBACKUP) || \
++               ((mode) == BOND_MODE_TLB) || \
++               ((mode) == BOND_MODE_ALB))
++
+ struct bond_parm_tbl {
+       char *modename;
+       int mode;
+@@ -443,7 +505,7 @@
+ static int arp_interval = BOND_LINK_ARP_INTERV;
+ static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, };
+-static unsigned long arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
++static u32 arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
+ static int arp_ip_count = 0;
+ static u32 my_ip = 0;
+ char *arp_target_hw_addr = NULL;
+@@ -474,8 +536,8 @@
+ {     "balance-xor",          BOND_MODE_XOR},
+ {     "broadcast",            BOND_MODE_BROADCAST},
+ {     "802.3ad",              BOND_MODE_8023AD},
+-{     "tlb",                  BOND_MODE_TLB},
+-{     "alb",                  BOND_MODE_ALB},
++{     "balance-tlb",          BOND_MODE_TLB},
++{     "balance-alb",          BOND_MODE_ALB},
+ {     NULL,                   -1},
+ };
+@@ -499,13 +561,16 @@
+ };
+ static LIST_HEAD(bond_dev_list);
++#ifdef CONFIG_PROC_FS
++static struct proc_dir_entry *bond_proc_dir = NULL;
++#endif
+ MODULE_PARM(max_bonds, "i");
+ MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
+ MODULE_PARM(miimon, "i");
+ MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
+ MODULE_PARM(use_carrier, "i");
+-MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 09 for off, 1 for on (default)");
++MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
+ MODULE_PARM(mode, "s");
+ MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
+ MODULE_PARM(arp_interval, "i");
+@@ -530,7 +595,6 @@
+ static void bond_mii_monitor(struct net_device *dev);
+ static void loadbalance_arp_monitor(struct net_device *dev);
+ static void activebackup_arp_monitor(struct net_device *dev);
+-static int bond_event(struct notifier_block *this, unsigned long event, void *ptr);
+ static void bond_mc_list_destroy(struct bonding *bond);
+ static void bond_mc_add(bonding_t *bond, void *addr, int alen);
+ static void bond_mc_delete(bonding_t *bond, void *addr, int alen);
+@@ -544,30 +608,17 @@
+ static int bond_release(struct net_device *master, struct net_device *slave);
+ static int bond_release_all(struct net_device *master);
+ static int bond_sethwaddr(struct net_device *master, struct net_device *slave);
++static void change_active_interface(struct bonding *bond, struct slave *new);
++static void reselect_active_interface(struct bonding *bond);
++static struct slave *find_best_interface(struct bonding *bond);
+-/*
+- * bond_get_info is the interface into the /proc filesystem.  This is
+- * a different interface than the BOND_INFO_QUERY ioctl.  That is done
+- * through the generic networking ioctl interface, and bond_info_query
+- * is the internal function which provides that information.
+- */
+-static int bond_get_info(char *buf, char **start, off_t offset, int length);
+-
+-/* Caller must hold bond->ptrlock for write */
+-static inline struct slave*
+-bond_assign_current_slave(struct bonding *bond,struct slave *newslave)
+-{
+-      if ((bond_mode == BOND_MODE_TLB) ||
+-          (bond_mode == BOND_MODE_ALB)) {
+-              bond_alb_assign_current_slave(bond, newslave);
+-      } else {
+-              bond->current_slave = newslave;
+-      }
+-
+-      return bond->current_slave;
+-}
+ /* #define BONDING_DEBUG 1 */
++#ifdef BONDING_DEBUG
++#define dprintk(x...) printk(x...)
++#else /* BONDING_DEBUG */
++#define dprintk(x...) do {} while (0)
++#endif /* BONDING_DEBUG */
+ /* several macros */
+@@ -662,7 +713,7 @@
+  * belongs to <bond>. It returns <slave> in case it's needed.
+  * Nothing is freed on return, structures are just unchained.
+  * If the bond->current_slave pointer was pointing to <slave>,
+- * it's replaced with bond->next, or NULL if not applicable.
++ * it should be changed by the calling function.
+  *
+  * bond->lock held for writing by caller.
+  */
+@@ -696,17 +747,6 @@
+       update_slave_cnt(bond, -1);
+-      /* no need to hold ptrlock since bond lock is
+-       * already held for writing
+-       */
+-      if (slave == bond->current_slave) {
+-              if ( bond->next != (slave_t *)bond) {  /* found one slave */
+-                      bond_assign_current_slave(bond, bond->next);
+-              } else {
+-                      bond_assign_current_slave(bond, NULL);
+-              }
+-      }
+-
+       return slave;
+ }
+@@ -1138,23 +1178,22 @@
+ } 
+ /*
+- * Push the promiscuity flag down to all slaves
++ * Push the promiscuity flag down to appropriate slaves
+  */
+ static void bond_set_promiscuity(bonding_t *bond, int inc)
+ { 
+       slave_t *slave; 
+-      switch (multicast_mode) {
+-      case BOND_MULTICAST_ACTIVE :
+-              /* write lock already acquired */
+-              if (bond->current_slave != NULL)
++
++      if (USES_PRIMARY(bond_mode)) {
++              if (bond->current_slave) {
+                       dev_set_promiscuity(bond->current_slave->dev, inc);
+-              break;
+-      case BOND_MULTICAST_ALL :
+-              for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
++              }
++
++      } else { 
++              for (slave = bond->prev; slave != (slave_t*)bond;
++                   slave = slave->prev) {
+                       dev_set_promiscuity(slave->dev, inc);
+-              break;
+-      case BOND_MULTICAST_DISABLED :
+-              break;
++              }
+       }
+ } 
+@@ -1200,20 +1239,23 @@
+       bonding_t *bond = master->priv;
+       struct dev_mc_list *dmi;
+-      if (multicast_mode == BOND_MULTICAST_DISABLED)
+-              return;
+-      /*
+-       * Lock the private data for the master
+-       */
+       write_lock_bh(&bond->lock);
+-      /* set promiscuity flag to slaves */
++      /*
++       * Do promisc before checking multicast_mode
++       */
+       if ( (master->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC) )
+               bond_set_promiscuity(bond, 1); 
+       if ( !(master->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC) ) 
+               bond_set_promiscuity(bond, -1); 
++      if (multicast_mode == BOND_MULTICAST_DISABLED) {
++              bond->flags = master->flags;
++              write_unlock_bh(&bond->lock);
++              return;
++      }
++
+       /* set allmulti flag to slaves */ 
+       if ( (master->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI) ) 
+               bond_set_allmulti(bond, 1); 
+@@ -1245,32 +1287,40 @@
+ /*
+  * Update the mc list and multicast-related flags for the new and 
+- * old active slaves (if any) according to the multicast mode
++ * old active slaves (if any) according to the multicast mode, and
++ * promiscuous flags unconditionally.
+  */
+ static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old)
+ {
+       struct dev_mc_list *dmi;
+-      switch(multicast_mode) {
+-      case BOND_MULTICAST_ACTIVE :            
++      if (USES_PRIMARY(bond_mode)) {
+               if (bond->device->flags & IFF_PROMISC) {
+-                      if (old != NULL && new != old)
++                      if (old)
+                               dev_set_promiscuity(old->dev, -1);
+-                      dev_set_promiscuity(new->dev, 1);
++                      if (new)
++                              dev_set_promiscuity(new->dev, 1);
+               }
++      }
++
++      switch(multicast_mode) {
++      case BOND_MULTICAST_ACTIVE :            
+               if (bond->device->flags & IFF_ALLMULTI) {
+-                      if (old != NULL && new != old)
++                      if (old)
+                               dev_set_allmulti(old->dev, -1);
+-                      dev_set_allmulti(new->dev, 1);
++                      if (new)
++                              dev_set_allmulti(new->dev, 1);
+               }
+               /* first remove all mc addresses from old slave if any,
+                  and _then_ add them to new active slave */
+-              if (old != NULL && new != old) {
++              if (old) {
+                       for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
+                               dev_mc_delete(old->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+               }
+-              for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
+-                      dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++              if (new) {
++                      for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
++                              dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++              }
+               break;
+       case BOND_MULTICAST_ALL :
+               /* nothing to do: mc list is already up-to-date on all slaves */
+@@ -1386,7 +1436,7 @@
+                        * The application already set the master's
+                        * mac address to that of the first slave
+                        */
+-                      memcpy(addr.sa_data, master_dev->dev_addr, ETH_ALEN);
++                      memcpy(addr.sa_data, master_dev->dev_addr, master_dev->addr_len);
+                       addr.sa_family = slave_dev->type;
+                       err = slave_dev->set_mac_address(slave_dev, &addr);
+                       if (err) {
+@@ -1432,11 +1482,19 @@
+               }
+       }
+-      if (multicast_mode == BOND_MULTICAST_ALL) {
+-              /* set promiscuity level to new slave */ 
+-              if (master_dev->flags & IFF_PROMISC)
++      /* set promiscuity level to new slave */ 
++      if (master_dev->flags & IFF_PROMISC) {
++              /* If the mode USES_PRIMARY, then the new slave gets the
++               * master's promisc (and mc) settings only if it becomes the
++               * current_slave, and that is taken care of later when calling
++               * bond_change_active()
++               */
++              if (!USES_PRIMARY(bond_mode)) {
+                       dev_set_promiscuity(slave_dev, 1); 
++              }
++      }
+  
++      if (multicast_mode == BOND_MULTICAST_ALL) {
+               /* set allmulti level to new slave */
+               if (master_dev->flags & IFF_ALLMULTI) 
+                       dev_set_allmulti(slave_dev, 1); 
+@@ -1549,9 +1607,7 @@
+ #endif
+                       /* first slave or no active slave yet, and this link
+                          is OK, so make this interface the active one */
+-                      bond_assign_current_slave(bond, new_slave);
+-                      bond_set_slave_active_flags(new_slave);
+-                      bond_mc_update(bond, new_slave, NULL);
++                      change_active_interface(bond, new_slave);
+               }
+               else {
+ #ifdef BONDING_DEBUG
+@@ -1559,11 +1615,14 @@
+ #endif
+                       bond_set_slave_inactive_flags(new_slave);
+               }
+-              read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
+-              ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list);
+-              ifa = *ifap;
+-              my_ip = ifa->ifa_address;
+-              read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
++              if (((struct in_device *)slave_dev->ip_ptr) != NULL) {
++                      read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
++                      ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list);
++                      ifa = *ifap;
++                      if (ifa != NULL)
++                              my_ip = ifa->ifa_address;
++                      read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
++              }
+               /* if there is a primary slave, remember it */
+               if (primary != NULL) {
+@@ -1598,7 +1657,7 @@
+                       /* first slave or no active slave yet, and this link
+                        * is OK, so make this interface the active one
+                        */
+-                      bond_assign_current_slave(bond, new_slave);
++                      change_active_interface(bond, new_slave);
+               }
+               /* if there is a primary slave, remember it */
+@@ -1613,8 +1672,13 @@
+ #endif
+               /* always active in trunk mode */
+               new_slave->state = BOND_STATE_ACTIVE;
++
++              /* In trunking mode there is little meaning to current_slave
++               * anyway (it holds no special properties of the bond device),
++               * so we can change it without calling change_active_interface()
++               */
+               if (bond->current_slave == NULL) 
+-                      bond_assign_current_slave(bond, new_slave);
++                      bond->current_slave = new_slave;
+       }
+       write_unlock_bh(&bond->lock);
+@@ -1705,6 +1769,13 @@
+               return -ENODEV;
+       }
++      /* Verify that master_dev is indeed the master of slave_dev */
++      if (!(slave_dev->flags & IFF_SLAVE) ||
++          (slave_dev->master != master_dev)) {
++
++              return -EINVAL;
++      }
++
+       bond = (struct bonding *) master_dev->priv;
+       write_lock_bh(&bond->lock);
+       slave = (slave_t *)bond;
+@@ -1717,67 +1788,46 @@
+               }
+       }
++      /*
++       * Changing to the current active: do nothing; return success.
++       */
++      if (newactive && (newactive == oldactive)) {
++              write_unlock_bh(&bond->lock);
++              return 0;
++      }
++
+       if ((newactive != NULL)&&
+           (oldactive != NULL)&&
+-          (newactive != oldactive)&&
+           (newactive->link == BOND_LINK_UP)&&
+           IS_UP(newactive->dev)) {
+-              bond_set_slave_inactive_flags(oldactive);
+-              bond_set_slave_active_flags(newactive);
+-              bond_mc_update(bond, newactive, oldactive);
+-              bond_assign_current_slave(bond, newactive);
+-              printk("%s : activate %s(old : %s)\n",
+-                      master_dev->name, newactive->dev->name, 
+-                      oldactive->dev->name);
+-      }
+-      else {
++              change_active_interface(bond, newactive);
++      } else {
+               ret = -EINVAL;
+       }
+       write_unlock_bh(&bond->lock);
+       return ret;
+ }
+-/* Choose a new valid interface from the pool, set it active
+- * and make it the current slave. If no valid interface is
+- * found, the oldest slave in BACK state is choosen and
+- * activated. If none is found, it's considered as no
+- * interfaces left so the current slave is set to NULL.
+- * The result is a pointer to the current slave.
+- *
+- * Since this function sends messages tails through printk, the caller
+- * must have started something like `printk(KERN_INFO "xxxx ");'.
++/**
++ * find_best_interface - select the best available slave to be the active one
++ * @bond: our bonding struct
+  *
+  * Warning: Caller must hold ptrlock for writing.
+  */
+-slave_t *change_active_interface(bonding_t *bond)
++static struct slave *find_best_interface(struct bonding *bond)
+ {
+-      slave_t *newslave, *oldslave;
+-      slave_t *bestslave = NULL;
++      struct slave *newslave, *oldslave;
++      struct slave *bestslave = NULL;
+       int mintime;
+       newslave = oldslave = bond->current_slave;
+       if (newslave == NULL) { /* there were no active slaves left */
+               if (bond->next != (slave_t *)bond) {  /* found one slave */
+-                      newslave = bond_assign_current_slave(bond, bond->next);
++                      newslave = bond->next;
+               } else {
+-
+-                      printk (" but could not find any %s interface.\n",
+-                              (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other");
+-                      bond_assign_current_slave(bond, NULL);
+                       return NULL; /* still no slave, return NULL */
+               }
+-      } else if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+-              /* make sure oldslave doesn't send arps - this could
+-               * cause a ping-pong effect between interfaces since they
+-               * would be able to tx arps - in active backup only one
+-               * slave should be able to tx arps, and that should be
+-               * the current_slave; the only exception is when all
+-               * slaves have gone down, then only one non-current slave can
+-               * send arps at a time; clearing oldslaves' mc list is handled
+-               * later in this function.
+-               */
+-              bond_set_slave_inactive_flags(oldslave);
+       }
+       mintime = updelay;
+@@ -1792,22 +1842,12 @@
+                       newslave = bond->primary_slave;
+       }
++      /* remember where to stop iterating over the slaves */
++      oldslave = newslave;
++
+       do {
+               if (IS_UP(newslave->dev)) {
+                       if (newslave->link == BOND_LINK_UP) {
+-                              /* this one is immediately usable */
+-                              if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+-                                      bond_set_slave_active_flags(newslave);
+-                                      bond_mc_update(bond, newslave, oldslave);
+-                                      printk (" and making interface %s the active one.\n",
+-                                              newslave->dev->name);
+-                              }
+-                              else {
+-                                      printk (" and setting pointer to interface %s.\n",
+-                                              newslave->dev->name);
+-                              }
+-
+-                              bond_assign_current_slave(bond, newslave);
+                               return newslave;
+                       }
+                       else if (newslave->link == BOND_LINK_BACK) {
+@@ -1820,46 +1860,105 @@
+               }
+       } while ((newslave = newslave->next) != oldslave);
+-      /* no usable backup found, we'll see if we at least got a link that was
+-         coming back for a long time, and could possibly already be usable.
+-      */
+-
+-      if (bestslave != NULL) {
+-              /* early take-over. */
+-              printk (" and making interface %s the active one %d ms earlier.\n",
+-                      bestslave->dev->name,
+-                      (updelay - bestslave->delay)*miimon);
+-
+-              bestslave->delay = 0;
+-              bestslave->link = BOND_LINK_UP;
+-              bestslave->jiffies = jiffies;
+-              bond_set_slave_active_flags(bestslave);
+-              bond_mc_update(bond, bestslave, oldslave);
+-              bond_assign_current_slave(bond, bestslave);
+-              return bestslave;
+-      }
+-
+-      if ((bond_mode == BOND_MODE_ACTIVEBACKUP) &&
+-          (multicast_mode == BOND_MULTICAST_ACTIVE) &&
+-          (oldslave != NULL)) {
+-              /* flush bonds (master's) mc_list from oldslave since it wasn't
+-               * updated (and deleted) above
+-               */ 
+-              bond_mc_list_flush(oldslave->dev, bond->device); 
+-              if (bond->device->flags & IFF_PROMISC) {
+-                      dev_set_promiscuity(oldslave->dev, -1);
++      return bestslave;
++}
++
++/**
++ * change_active_interface - change the active slave into the specified one
++ * @bond: our bonding struct
++ * @new: the new slave to make the active one
++ * 
++ * Set the new slave to the bond's settings and unset them on the old
++ * current_slave.
++ * Setting include flags, mc-list, promiscuity, allmulti, etc.
++ *
++ * If @new's link state is %BOND_LINK_BACK we'll set it to %BOND_LINK_UP,
++ * because it is apparently the best available slave we have, even though its
++ * updelay hasn't timed out yet.
++ *
++ * Warning: Caller must hold ptrlock for writing.
++ */
++static void change_active_interface(struct bonding *bond, struct slave *new)
++{
++      struct slave *old = bond->current_slave;
++
++      if (old == new) {
++              return;
++      }
++
++      if (new) {
++              if (new->link == BOND_LINK_BACK) {
++                      if (USES_PRIMARY(bond_mode)) {
++                              printk (KERN_INFO
++                                      "%s: making interface %s the new "
++                                      "active one %d ms earlier.\n",
++                                      bond->device->name, new->dev->name,
++                                      (updelay - new->delay) * miimon);
++                      }
++
++                      new->delay = 0;
++                      new->link = BOND_LINK_UP;
++                      new->jiffies = jiffies;
++
++                      if (bond_mode == BOND_MODE_8023AD) {
++                              bond_3ad_handle_link_change(new, BOND_LINK_UP);
++                      }
++
++                      if ((bond_mode == BOND_MODE_TLB) ||
++                          (bond_mode == BOND_MODE_ALB)) {
++                              bond_alb_handle_link_change(bond, new, BOND_LINK_UP);
++                      }
++              } else {
++                      if (USES_PRIMARY(bond_mode)) {
++                              printk (KERN_INFO
++                                      "%s: making interface %s the new active one.\n",
++                                      bond->device->name, new->dev->name);
++                      }
+               }
+-              if (bond->device->flags & IFF_ALLMULTI) {
+-                      dev_set_allmulti(oldslave->dev, -1);
++      }
++
++      if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
++              if (old) {
++                      bond_set_slave_inactive_flags(old);
++              }
++
++              if (new) {
++                      bond_set_slave_active_flags(new);
+               }
+       }
+-      printk (" but could not find any %s interface.\n",
+-              (bond_mode == BOND_MODE_ACTIVEBACKUP) ? "backup":"other");
+-      
+-      /* absolutely nothing found. let's return NULL */
+-      bond_assign_current_slave(bond, NULL);
+-      return NULL;
++      if (USES_PRIMARY(bond_mode)) {
++              bond_mc_update(bond, new, old);
++      }
++
++      if ((bond_mode == BOND_MODE_TLB) ||
++          (bond_mode == BOND_MODE_ALB)) {
++              bond_alb_assign_current_slave(bond, new);
++      } else {
++              bond->current_slave = new;
++      }
++}
++
++/**
++ * reselect_active_interface - select a new active slave, if needed
++ * @bond: our bonding struct
++ *
++ * This functions shoud be called when one of the following occurs:
++ * - The old current_slave has been released or lost its link.
++ * - The primary_slave has got its link back.
++ * - A slave has got its link back and there's no old current_slave.
++ *
++ * Warning: Caller must hold ptrlock for writing.
++ */
++static void reselect_active_interface(struct bonding *bond)
++{
++      struct slave *best_slave;
++
++      best_slave = find_best_interface(bond);
++
++      if (best_slave != bond->current_slave) {
++              change_active_interface(bond, best_slave);
++      }
+ }
+ /*
+@@ -1908,12 +2007,12 @@
+                               "of %s to a different address "
+                               "to avoid conflicts.\n",
+                                      slave->name,
+-                                     slave->dev_addr[0],
+-                                     slave->dev_addr[1],
+-                                     slave->dev_addr[2],
+-                                     slave->dev_addr[3],
+-                                     slave->dev_addr[4],
+-                                     slave->dev_addr[5],
++                                     our_slave->perm_hwaddr[0],
++                                     our_slave->perm_hwaddr[1],
++                                     our_slave->perm_hwaddr[2],
++                                     our_slave->perm_hwaddr[3],
++                                     our_slave->perm_hwaddr[4],
++                                     our_slave->perm_hwaddr[5],
+                                      bond->device->name,
+                                      slave->name);
+                       }
+@@ -1926,31 +2025,29 @@
+                               bond_3ad_unbind_slave(our_slave);
+                       }
+-                      /* release the slave from its bond */
+-                      bond_detach_slave(bond, our_slave);
+-
+-                      printk (KERN_INFO "%s: releasing %s interface %s",
++                      printk (KERN_INFO "%s: releasing %s interface %s\n",
+                               master->name,
+                               (our_slave->state == BOND_STATE_ACTIVE) ? "active" : "backup",
+                               slave->name);
+-                      if (our_slave == old_current) {
+-                              /* find a new interface and be verbose */
+-                              change_active_interface(bond); 
+-                      } else {
+-                              printk(".\n");
++                      /* release the slave from its bond */
++                      bond_detach_slave(bond, our_slave);
++
++                      if (bond->primary_slave == our_slave) {
++                              bond->primary_slave = NULL;
+                       }
+-                      
++
++                      if (bond->current_slave == our_slave) {
++                              change_active_interface(bond, NULL);
++                              reselect_active_interface(bond);
++                      }
++
+                       if (bond->current_slave == NULL) {
+                               printk(KERN_INFO
+                                       "%s: now running without any active interface !\n",
+                                       master->name);
+                       }
+-                      if (bond->primary_slave == our_slave) {
+-                              bond->primary_slave = NULL;
+-                      }
+-
+                       if ((bond_mode == BOND_MODE_TLB) ||
+                           (bond_mode == BOND_MODE_ALB)) {
+                               /* must be called only after the slave has been
+@@ -1972,16 +2069,22 @@
+               return -EINVAL;
+       }
++      /* unset promiscuity level from slave */
++      if (master->flags & IFF_PROMISC) {
++              /* If the mode USES_PRIMARY, then we should only remove its
++               * promisc settings if it was the current_slave, but that was
++               * already taken care of above when we detached the slave
++               */
++              if (!USES_PRIMARY(bond_mode)) {
++                      dev_set_promiscuity(slave, -1); 
++              }
++      }
++
+       /* undo settings and restore original values */
+-      
+       if (multicast_mode == BOND_MULTICAST_ALL) {
+               /* flush master's mc_list from slave */ 
+               bond_mc_list_flush (slave, master); 
+-              /* unset promiscuity level from slave */
+-              if (master->flags & IFF_PROMISC) 
+-                      dev_set_promiscuity(slave, -1); 
+-
+               /* unset allmulti level from slave */ 
+               if (master->flags & IFF_ALLMULTI)
+                       dev_set_allmulti(slave, -1); 
+@@ -2048,7 +2151,7 @@
+       }
+       old_current = bond->current_slave;
+-      bond_assign_current_slave(bond, NULL);
++      change_active_interface(bond, NULL);
+       bond->current_arp_slave = NULL;
+       bond->primary_slave = NULL;
+@@ -2077,17 +2180,17 @@
+                */
+               write_unlock_bh(&bond->lock);
+-              if (multicast_mode == BOND_MULTICAST_ALL 
+-                  || (multicast_mode == BOND_MULTICAST_ACTIVE 
+-                      && old_current == our_slave)) {
++              /* unset promiscuity level from slave */
++              if (master->flags & IFF_PROMISC) {
++                      if (!USES_PRIMARY(bond_mode)) {
++                              dev_set_promiscuity(slave_dev, -1); 
++                      }
++              }
++              if (multicast_mode == BOND_MULTICAST_ALL) {
+                       /* flush master's mc_list from slave */ 
+                       bond_mc_list_flush (slave_dev, master); 
+-                      /* unset promiscuity level from slave */
+-                      if (master->flags & IFF_PROMISC) 
+-                              dev_set_promiscuity(slave_dev, -1); 
+-
+                       /* unset allmulti level from slave */ 
+                       if (master->flags & IFF_ALLMULTI)
+                               dev_set_allmulti(slave_dev, -1); 
+@@ -2233,9 +2336,7 @@
+                                       write_lock(&bond->ptrlock);
+                                       if (slave == bond->current_slave) {
+                                               /* find a new interface and be verbose */
+-                                              change_active_interface(bond);
+-                                      } else {
+-                                              printk(".\n");
++                                              reselect_active_interface(bond);
+                                       }
+                                       write_unlock(&bond->ptrlock);
+                                       slave_died = 1;
+@@ -2331,7 +2432,7 @@
+                                       write_lock(&bond->ptrlock);
+                                       if ( (bond->primary_slave != NULL)
+                                         && (slave == bond->primary_slave) )
+-                                              change_active_interface(bond); 
++                                              reselect_active_interface(bond); 
+                                       write_unlock(&bond->ptrlock);
+                               }
+                               else
+@@ -2377,40 +2478,8 @@
+       /* no active interface at the moment or need to bring up the primary */
+       if (oldcurrent == NULL)  { /* no active interface at the moment */
+               if (bestslave != NULL) { /* last chance to find one ? */
+-                      if (bestslave->link == BOND_LINK_UP) {
+-                              printk (KERN_INFO
+-                                      "%s: making interface %s the new active one.\n",
+-                                      master->name, bestslave->dev->name);
+-                      } else {
+-                              printk (KERN_INFO
+-                                      "%s: making interface %s the new "
+-                                      "active one %d ms earlier.\n",
+-                                      master->name, bestslave->dev->name,
+-                                      (updelay - bestslave->delay) * miimon);
+-
+-                              bestslave->delay = 0;
+-                              bestslave->link  = BOND_LINK_UP;
+-                              bestslave->jiffies = jiffies;
+-
+-                              /* notify ad that the link status has changed */
+-                              if (bond_mode == BOND_MODE_8023AD) {
+-                                      bond_3ad_handle_link_change(bestslave, BOND_LINK_UP);
+-                              }
+-
+-                              if ((bond_mode == BOND_MODE_TLB) ||
+-                                  (bond_mode == BOND_MODE_ALB)) {
+-                                      bond_alb_handle_link_change(bond, bestslave, BOND_LINK_UP);
+-                              }
+-                      }
+-
+-                      if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+-                              bond_set_slave_active_flags(bestslave);
+-                              bond_mc_update(bond, bestslave, NULL);
+-                      } else if (bond_mode != BOND_MODE_8023AD) {
+-                              bestslave->state = BOND_STATE_ACTIVE;
+-                      }
+                       write_lock(&bond->ptrlock);
+-                      bond_assign_current_slave(bond, bestslave);
++                      change_active_interface(bond, bestslave);
+                       write_unlock(&bond->ptrlock);
+               } else if (slave_died) {
+                       /* print this message only once a slave has just died */
+@@ -2494,7 +2563,7 @@
+                                               "for interface %s, ",
+                                               master->name,
+                                               slave->dev->name);
+-                                      change_active_interface(bond); 
++                                      reselect_active_interface(bond); 
+                               } else {
+                                       printk(KERN_INFO
+                                               "%s: interface %s is now up\n",
+@@ -2526,7 +2595,7 @@
+                               write_lock(&bond->ptrlock);
+                               if (slave == bond->current_slave) {
+-                                      change_active_interface(bond);
++                                      reselect_active_interface(bond);
+                               }
+                               write_unlock(&bond->ptrlock);
+                       }
+@@ -2604,9 +2673,7 @@
+                               if ((bond->current_slave == NULL) &&
+                                   ((jiffies - slave->dev->trans_start) <=
+                                    the_delta_in_ticks)) {
+-                                      bond_assign_current_slave(bond, slave);
+-                                      bond_set_slave_active_flags(slave);
+-                                      bond_mc_update(bond, slave, NULL);
++                                      change_active_interface(bond, slave);
+                                       bond->current_arp_slave = NULL;
+                               } else if (bond->current_slave != slave) {
+                                       /* this slave has just come up but we 
+@@ -2696,7 +2763,8 @@
+                              master->name,
+                              slave->dev->name);
+                       write_lock(&bond->ptrlock);
+-                      slave = change_active_interface(bond);
++                      reselect_active_interface(bond);
++                      slave = bond->current_slave;
+                       write_unlock(&bond->ptrlock);
+                       bond->current_arp_slave = slave;
+                       if (slave != NULL) {
+@@ -2715,13 +2783,10 @@
+                              bond->primary_slave->dev->name);
+                              
+                       /* primary is up so switch to it */
+-                      bond_set_slave_inactive_flags(slave);
+-                      bond_mc_update(bond, bond->primary_slave, slave);
+                       write_lock(&bond->ptrlock);
+-                      bond_assign_current_slave(bond, bond->primary_slave);
++                      change_active_interface(bond, bond->primary_slave);
+                       write_unlock(&bond->ptrlock);
+                       slave = bond->primary_slave;
+-                      bond_set_slave_active_flags(slave);
+                       slave->jiffies = jiffies;
+               } else {
+                       bond->current_arp_slave = NULL;
+@@ -2730,10 +2795,8 @@
+               /* the current slave must tx an arp to ensure backup slaves
+                * rx traffic
+                */
+-              if ((slave != NULL) &&
+-                  (((jiffies - slave->dev->last_rx) >= the_delta_in_ticks) &&
+-                   (my_ip != 0))) {
+-                arp_send_all(slave);
++              if ((slave != NULL) && (my_ip != 0)) {
++                      arp_send_all(slave);
+               }
+       }
+@@ -2766,7 +2829,7 @@
+                               /* if the link state is up at this point, we 
+                                * mark it down - this can happen if we have 
+                                * simultaneous link failures and 
+-                               * change_active_interface doesn't make this 
++                               * reselect_active_interface doesn't make this 
+                                * one the current slave so it is still marked 
+                                * up when it is actually down
+                                */
+@@ -2986,7 +3049,7 @@
+       } else if (orig_app_abi_ver != app_abi_ver) {
+               printk(KERN_ERR
+                      "bonding: Error: already using ifenslave ABI "
+-                     "version %d; to upgrade ifenslave to version %d,"
++                     "version %d; to upgrade ifenslave to version %d, "
+                      "you must first reload bonding.\n",
+                      orig_app_abi_ver, app_abi_ver);
+               return -EINVAL;
+@@ -3011,15 +3074,9 @@
+               case SIOCBONDRELEASE:   
+                       ret = bond_release(master_dev, slave_dev); 
+                       break;
+-              case BOND_SETHWADDR_OLD:
+-              case SIOCBONDSETHWADDR: 
+-                      ret = bond_sethwaddr(master_dev, slave_dev);
+-                      break;
+               case BOND_CHANGE_ACTIVE_OLD:
+               case SIOCBONDCHANGEACTIVE:
+-                      if ((bond_mode == BOND_MODE_ACTIVEBACKUP) ||
+-                          (bond_mode == BOND_MODE_TLB) ||
+-                          (bond_mode == BOND_MODE_ALB)) {
++                      if (USES_PRIMARY(bond_mode)) {
+                               ret = bond_change_active(master_dev, slave_dev);
+                       }
+                       else {
+@@ -3141,7 +3198,7 @@
+                       dev_queue_xmit(skb);
+                       write_lock(&bond->ptrlock);
+-                      bond_assign_current_slave(bond, slave->next);
++                      bond->current_slave = slave->next;
+                       write_unlock(&bond->ptrlock);
+                       read_unlock(&bond->lock);
+@@ -3285,10 +3342,10 @@
+ static struct net_device_stats *bond_get_stats(struct net_device *dev)
+ {
+       bonding_t *bond = dev->priv;
+-      struct net_device_stats *stats = bond->stats, *sstats;
++      struct net_device_stats *stats = &(bond->stats), *sstats;
+       slave_t *slave;
+-      memset(bond->stats, 0, sizeof(struct net_device_stats));
++      memset(stats, 0, sizeof(struct net_device_stats));
+       read_lock_bh(&bond->lock);
+@@ -3327,152 +3384,511 @@
+       return stats;
+ }
+-static int bond_get_info(char *buf, char **start, off_t offset, int length)
+-{
+-      bonding_t *bond;
+-      int len = 0;
+-      off_t begin = 0;
+-      u16 link;
+-      slave_t *slave = NULL;
++#ifdef CONFIG_PROC_FS
++
++#define SEQ_START_TOKEN ((void *)1)
+-      len += sprintf(buf + len, "%s\n", version);
++static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct bonding *bond = seq->private;
++      loff_t off = 0;
++      struct slave *slave;
++      /* make sure the bond won't be taken away */
+       read_lock(&dev_base_lock);
+-      list_for_each_entry(bond, &bond_dev_list, bond_list) {
+-              /*
+-               * This function locks the mutex, so we can't lock it until 
+-               * afterwards
+-               */
+-              link = bond_check_mii_link(bond);
++      read_lock_bh(&bond->lock);
+-              len += sprintf(buf + len, "Bonding Mode: %s\n",
+-                             bond_mode_name());
++      if (*pos == 0) {
++              return SEQ_START_TOKEN;
++      }
+-              if ((bond_mode == BOND_MODE_ACTIVEBACKUP) ||
+-                  (bond_mode == BOND_MODE_TLB) ||
+-                  (bond_mode == BOND_MODE_ALB)) {
+-                      read_lock_bh(&bond->lock);
+-                      read_lock(&bond->ptrlock);
+-                      if (bond->current_slave != NULL) {
+-                              len += sprintf(buf + len, 
+-                                      "Currently Active Slave: %s\n", 
+-                                      bond->current_slave->dev->name);
+-                      }
+-                      read_unlock(&bond->ptrlock);
+-                      read_unlock_bh(&bond->lock);
+-              }
+-
+-              len += sprintf(buf + len, "MII Status: ");
+-              len += sprintf(buf + len, 
+-                              link == BMSR_LSTATUS ? "up\n" : "down\n");
+-              len += sprintf(buf + len, "MII Polling Interval (ms): %d\n", 
+-                              miimon);
+-              len += sprintf(buf + len, "Up Delay (ms): %d\n", 
+-                              updelay * miimon);
+-              len += sprintf(buf + len, "Down Delay (ms): %d\n", 
+-                              downdelay * miimon);
+-              len += sprintf(buf + len, "Multicast Mode: %s\n",
+-                             multicast_mode_name());
++      for (slave = bond->prev; slave != (slave_t *)bond;
++           slave = slave->prev) {
+-              read_lock_bh(&bond->lock);
++              if (++off == *pos) {
++                      return slave;
++              }
++      }
+-              if (bond_mode == BOND_MODE_8023AD) {
+-                      struct ad_info ad_info;
++      return NULL;
++}
+-                      len += sprintf(buf + len, "\n802.3ad info\n");
++static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct bonding *bond = seq->private;
++      struct slave *slave = v;
+-                      if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
+-                              len += sprintf(buf + len, "bond %s has no active aggregator\n", bond->device->name);
+-                      } else {
+-                              len += sprintf(buf + len, "Active Aggregator Info:\n");
++      ++*pos;
++      if (v == SEQ_START_TOKEN) {
++              slave = bond->prev;
++      } else {
++              slave = slave->prev;
++      }
+-                              len += sprintf(buf + len, "\tAggregator ID: %d\n", ad_info.aggregator_id);
+-                              len += sprintf(buf + len, "\tNumber of ports: %d\n", ad_info.ports);
+-                              len += sprintf(buf + len, "\tActor Key: %d\n", ad_info.actor_key);
+-                              len += sprintf(buf + len, "\tPartner Key: %d\n", ad_info.partner_key);
+-                              len += sprintf(buf + len, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+-                                             ad_info.partner_system[0],
+-                                             ad_info.partner_system[1],
+-                                             ad_info.partner_system[2],
+-                                             ad_info.partner_system[3],
+-                                             ad_info.partner_system[4],
+-                                             ad_info.partner_system[5]);
+-                      }
++      return (slave == (struct slave *) bond) ? NULL : slave;
++}
++
++static void bond_info_seq_stop(struct seq_file *seq, void *v)
++{
++      struct bonding *bond = seq->private;
++
++      read_unlock_bh(&bond->lock);
++      read_unlock(&dev_base_lock);
++}
++
++static void bond_info_show_master(struct seq_file *seq, struct bonding *bond)
++{
++      struct slave *curr;
++
++      read_lock(&bond->ptrlock);
++      curr = bond->current_slave;
++      read_unlock(&bond->ptrlock);
++
++      seq_printf(seq, "Bonding Mode: %s\n", bond_mode_name());
++
++      if (USES_PRIMARY(bond_mode)) {
++              if (curr) {
++                      seq_printf(seq,
++                                 "Currently Active Slave: %s\n",
++                                 curr->dev->name);
+               }
++      }
+-              for (slave = bond->prev; slave != (slave_t *)bond; 
+-                   slave = slave->prev) {
+-                      len += sprintf(buf + len, "\nSlave Interface: %s\n", slave->dev->name);
++      seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down");
++      seq_printf(seq, "MII Polling Interval (ms): %d\n", miimon);
++      seq_printf(seq, "Up Delay (ms): %d\n", updelay * miimon);
++      seq_printf(seq, "Down Delay (ms): %d\n", downdelay * miimon);
++      seq_printf(seq, "Multicast Mode: %s\n", multicast_mode_name());
+-                      len += sprintf(buf + len, "MII Status: ");
++      if (bond_mode == BOND_MODE_8023AD) {
++              struct ad_info ad_info;
+-                      len += sprintf(buf + len, 
+-                              slave->link == BOND_LINK_UP ? 
+-                              "up\n" : "down\n");
+-                      len += sprintf(buf + len, "Link Failure Count: %d\n", 
+-                              slave->link_failure_count);
+-
+-                      if (app_abi_ver >= 1) {
+-                              len += sprintf(buf + len,
+-                                             "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+-                                             slave->perm_hwaddr[0],
+-                                             slave->perm_hwaddr[1],
+-                                             slave->perm_hwaddr[2],
+-                                             slave->perm_hwaddr[3],
+-                                             slave->perm_hwaddr[4],
+-                                             slave->perm_hwaddr[5]);
+-                      }
++              seq_puts(seq, "\n802.3ad info\n");
+-                      if (bond_mode == BOND_MODE_8023AD) {
+-                              struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
++              if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
++                      seq_printf(seq, "bond %s has no active aggregator\n",
++                                 bond->device->name);
++              } else {
++                      seq_printf(seq, "Active Aggregator Info:\n");
+-                              if (agg) {
+-                                      len += sprintf(buf + len, "Aggregator ID: %d\n",
+-                                                     agg->aggregator_identifier);
+-                              } else {
+-                                      len += sprintf(buf + len, "Aggregator ID: N/A\n");
+-                              }
+-                      }
++                      seq_printf(seq, "\tAggregator ID: %d\n",
++                                 ad_info.aggregator_id);
++                      seq_printf(seq, "\tNumber of ports: %d\n",
++                                 ad_info.ports);
++                      seq_printf(seq, "\tActor Key: %d\n",
++                                 ad_info.actor_key);
++                      seq_printf(seq, "\tPartner Key: %d\n",
++                                 ad_info.partner_key);
++                      seq_printf(seq, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
++                                 ad_info.partner_system[0],
++                                 ad_info.partner_system[1],
++                                 ad_info.partner_system[2],
++                                 ad_info.partner_system[3],
++                                 ad_info.partner_system[4],
++                                 ad_info.partner_system[5]);
+               }
+-              read_unlock_bh(&bond->lock);
++      }
++}
+-              /*
+-               * Figure out the calcs for the /proc/net interface
+-               */
+-              *start = buf + (offset - begin);
+-              len -= (offset - begin);
+-              if (len > length) {
+-                      len = length;
++static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
++{
++      seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
++      seq_printf(seq, "MII Status: %s\n",
++                 (slave->link == BOND_LINK_UP) ?  "up" : "down");
++      seq_printf(seq, "Link Failure Count: %d\n",
++                 slave->link_failure_count);
++
++      if (app_abi_ver >= 1) {
++              seq_printf(seq,
++                         "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
++                         slave->perm_hwaddr[0],
++                         slave->perm_hwaddr[1],
++                         slave->perm_hwaddr[2],
++                         slave->perm_hwaddr[3],
++                         slave->perm_hwaddr[4],
++                         slave->perm_hwaddr[5]);
++      }
++
++      if (bond_mode == BOND_MODE_8023AD) {
++              const struct aggregator *agg
++                      = SLAVE_AD_INFO(slave).port.aggregator;
++
++              if (agg) {
++                      seq_printf(seq, "Aggregator ID: %d\n",
++                                 agg->aggregator_identifier);
++              } else {
++                      seq_puts(seq, "Aggregator ID: N/A\n");
+               }
+-              if (len < 0) {
+-                      len = 0;
++      }
++}
++
++static int bond_info_seq_show(struct seq_file *seq, void *v)
++{
++      if (v == SEQ_START_TOKEN) {
++              seq_printf(seq, "%s\n", version);
++              bond_info_show_master(seq, seq->private);
++      } else {
++              bond_info_show_slave(seq, v);
++      }
++
++      return 0;
++}
++
++static struct seq_operations bond_info_seq_ops = {
++      .start = bond_info_seq_start,
++      .next  = bond_info_seq_next,
++      .stop  = bond_info_seq_stop,
++      .show  = bond_info_seq_show,
++};
++
++static int bond_info_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      struct proc_dir_entry *proc;
++      int rc;
++
++      rc = seq_open(file, &bond_info_seq_ops);
++      if (!rc) {
++              /* recover the pointer buried in proc_dir_entry data */
++              seq = file->private_data;
++              proc = PDE(inode);
++              seq->private = proc->data;
++      }
++      return rc;
++}
++
++static struct file_operations bond_info_fops = {
++      .owner   = THIS_MODULE,
++      .open    = bond_info_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = seq_release,
++};
++
++static int bond_create_proc_info(struct bonding *bond)
++{
++      struct net_device *dev = bond->device;
++
++      if (bond_proc_dir) {
++              bond->bond_proc_file = create_proc_entry(dev->name,
++                                                       S_IRUGO, 
++                                                       bond_proc_dir);
++              if (bond->bond_proc_file == NULL) {
++                      printk(KERN_WARNING
++                             "%s: Cannot create /proc/net/bonding/%s\n", 
++                             dev->name, dev->name);
++              } else {
++                      bond->bond_proc_file->data = bond;
++                      bond->bond_proc_file->proc_fops = &bond_info_fops;
++                      bond->bond_proc_file->owner = THIS_MODULE;
++                      memcpy(bond->procdir_name, dev->name, IFNAMSIZ);
+               }
++      }
++
++      return 0;
++}
++static void bond_destroy_proc_info(struct bonding *bond)
++{
++      if (bond_proc_dir && bond->bond_proc_file) {
++              remove_proc_entry(bond->procdir_name, bond_proc_dir);
++              memset(bond->procdir_name, 0, IFNAMSIZ);
++              bond->bond_proc_file = NULL;
+       }
+-      read_unlock(&dev_base_lock);
++}
++#endif /* CONFIG_PROC_FS */
++
++/*
++ * Change HW address
++ *
++ * Note that many devices must be down to change the HW address, and
++ * downing the master releases all slaves.  We can make bonds full of
++ * bonding devices to test this, however.
++ */
++static inline int
++bond_set_mac_address(struct net_device *dev, void *addr)
++{
++      struct bonding *bond = dev->priv;
++      struct sockaddr *sa = addr, tmp_sa;
++      struct slave *slave;
++      int error;
++
++      dprintk(KERN_INFO "bond_set_mac_address %p %s\n", dev,
++             dev->name);
+-      return len;
++      if (!is_valid_ether_addr(sa->sa_data)) {
++              return -EADDRNOTAVAIL;
++      }
++
++      for (slave = bond->prev; slave != (struct slave *)bond;
++           slave = slave->prev) {
++              dprintk(KERN_INFO "bond_set_mac: slave %p %s\n", slave,
++                      slave->dev->name);
++              if (slave->dev->set_mac_address == NULL) {
++                      error = -EOPNOTSUPP;
++                      dprintk(KERN_INFO "bond_set_mac EOPNOTSUPP %s\n",
++                              slave->dev->name);
++                      goto unwind;
++              }
++
++              error = slave->dev->set_mac_address(slave->dev, addr);
++              if (error) {
++                      /* TODO: consider downing the slave 
++                       * and retry ?
++                       * User should expect communications
++                       * breakage anyway until ARP finish
++                       * updating, so...
++                       */
++                      dprintk(KERN_INFO "bond_set_mac err %d %s\n",
++                              error, slave->dev->name);
++                      goto unwind;
++              }
++      }
++
++      /* success */
++      memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++      return 0;
++
++unwind:
++      memcpy(tmp_sa.sa_data, dev->dev_addr, dev->addr_len);
++      tmp_sa.sa_family = dev->type;
++
++      for (slave = slave->next; slave != bond->next;
++           slave = slave->next) {
++              int tmp_error;
++
++              tmp_error = slave->dev->set_mac_address(slave->dev, &tmp_sa);
++              if (tmp_error) {
++                      dprintk(KERN_INFO "bond_set_mac_address: "
++                              "unwind err %d dev %s\n",
++                              tmp_error, slave->dev->name);
++              }
++      }
++
++      return error;
+ }
+-static int bond_event(struct notifier_block *this, unsigned long event, 
+-                      void *ptr)
++/*
++ * Change the MTU of all of a master's slaves to match the master
++ */
++static inline int
++bond_change_mtu(struct net_device *dev, int newmtu)
++{
++      bonding_t *bond = dev->priv;
++      slave_t *slave;
++      int error;
++
++      dprintk(KERN_INFO "CM: b %p nm %d\n", bond, newmtu);
++      for (slave = bond->prev; slave != (slave_t *)bond;
++           slave = slave->prev) {
++              dprintk(KERN_INFO "CM: s %p s->p %p c_m %p\n", slave,
++                      slave->prev, slave->dev->change_mtu);
++              if (slave->dev->change_mtu) {
++                      error = slave->dev->change_mtu(slave->dev, newmtu);
++              } else {
++                      slave->dev->mtu = newmtu;
++                      error = 0;
++              }
++
++              if (error) {
++                      /* If we failed to set the slave's mtu to the new value
++                       * we must abort the operation even in ACTIVE_BACKUP
++                       * mode, because if we allow the backup slaves to have
++                       * different mtu values than the active slave we'll
++                       * need to change their mtu when doing a failover. That
++                       * means changing their mtu from timer context, which
++                       * is probably not a good idea.
++                       */
++                      dprintk(KERN_INFO "bond_change_mtu err %d %s\n",
++                             error, slave->dev->name);
++                      goto unwind;
++              }
++      }
++
++      dev->mtu = newmtu;
++      return 0;
++
++
++unwind:
++      for (slave = slave->next; slave != bond->next;
++           slave = slave->next) {
++
++              if (slave->dev->change_mtu) {
++                      slave->dev->change_mtu(slave->dev, dev->mtu);
++              } else {
++                      slave->dev->mtu = dev->mtu;
++              }
++      }
++
++      return error;
++}
++
++/*
++ * Change device name
++ */
++static inline int bond_event_changename(struct bonding *bond)
++{
++#ifdef CONFIG_PROC_FS
++      bond_destroy_proc_info(bond);
++      bond_create_proc_info(bond);
++#endif
++
++      return NOTIFY_DONE;
++}
++
++static int bond_master_netdev_event(unsigned long event, struct net_device *event_dev)
++{
++      struct bonding *bond, *event_bond = NULL;
++
++      list_for_each_entry(bond, &bond_dev_list, bond_list) {
++              if (bond == event_dev->priv) {
++                      event_bond = bond;
++                      break;
++              }
++      }
++
++      if (event_bond == NULL) {
++              return NOTIFY_DONE;
++      }
++
++      switch (event) {
++      case NETDEV_CHANGENAME:
++              return bond_event_changename(event_bond);
++      case NETDEV_UNREGISTER:
++              /*
++               * TODO: remove a bond from the list?
++               */
++              break;
++      default:
++              break;
++      }
++
++      return NOTIFY_DONE;
++}
++
++static int bond_slave_netdev_event(unsigned long event, struct net_device *event_dev)
+ {
+-      struct net_device *event_dev = (struct net_device *)ptr;
+       struct net_device *master = event_dev->master;
+-      if (event == NETDEV_UNREGISTER && master != NULL) 
+-              bond_release(master, event_dev);
++      switch (event) {
++      case NETDEV_UNREGISTER:
++              if (master != NULL) {
++                      bond_release(master, event_dev);
++              }
++              break;
++      case NETDEV_CHANGE:
++              /*
++               * TODO: is this what we get if somebody
++               * sets up a hierarchical bond, then rmmod's
++               * one of the slave bonding devices?
++               */
++              break;
++      case NETDEV_DOWN:
++              /*
++               * ... Or is it this?
++               */
++              break;
++      case NETDEV_CHANGEMTU:
++              /*
++               * TODO: Should slaves be allowed to
++               * independently alter their MTU?  For
++               * an active-backup bond, slaves need
++               * not be the same type of device, so
++               * MTUs may vary.  For other modes,
++               * slaves arguably should have the
++               * same MTUs. To do this, we'd need to
++               * take over the slave's change_mtu
++               * function for the duration of their
++               * servitude.
++               */
++              break;
++      case NETDEV_CHANGENAME:
++              /*
++               * TODO: handle changing the primary's name
++               */
++              break;
++      default:
++              break;
++      }
+       return NOTIFY_DONE;
+ }
++/*
++ * bond_netdev_event: handle netdev notifier chain events.
++ *
++ * This function receives events for the netdev chain.  The caller (an
++ * ioctl handler calling notifier_call_chain) holds the necessary
++ * locks for us to safely manipulate the slave devices (RTNL lock,
++ * dev_probe_lock).
++ */
++static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
++{
++      struct net_device *event_dev = (struct net_device *)ptr;
++      unsigned short flags;
++      int res = NOTIFY_DONE;
++
++      dprintk(KERN_INFO "bond_netdev_event n_b %p ev %lx ptr %p\n",
++              this, event, ptr);
++
++      flags = event_dev->flags & (IFF_MASTER | IFF_SLAVE);
++      switch (flags) {
++      case IFF_MASTER:
++              res = bond_master_netdev_event(event, event_dev);
++              break;
++      case IFF_SLAVE:
++              res = bond_slave_netdev_event(event, event_dev);
++              break;
++      default:
++              /* A master that is also a slave ? */
++              break;
++      }
++
++      return res;
++}
++
+ static struct notifier_block bond_netdev_notifier = {
+-      .notifier_call = bond_event,
++      .notifier_call = bond_netdev_event,
+ };
++static inline void bond_deinit(struct net_device *dev)
++{
++      struct bonding *bond = dev->priv;
++
++      list_del(&bond->bond_list);
++
++#ifdef CONFIG_PROC_FS
++      bond_destroy_proc_info(bond);
++#endif
++}
++
++static void bond_free_all(void)
++{
++      struct bonding *bond, *nxt;
++
++      list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
++              struct net_device *dev = bond->device;
++
++              unregister_netdev(dev);
++              bond_deinit(dev);
++              free_netdev(dev);
++      }
++
++#ifdef CONFIG_PROC_FS
++      if (bond_proc_dir) {
++              remove_proc_entry(DRV_NAME, proc_net);
++              bond_proc_dir = NULL;
++      }
++#endif
++}
++
++/*
++ * Does not allocate but creates a /proc entry.
++ * Allowed to fail.
++ */
+ static int __init bond_init(struct net_device *dev)
+ {
+-      bonding_t *bond;
++      struct bonding *bond;
+       int count;
+ #ifdef BONDING_DEBUG
+@@ -3483,15 +3899,16 @@
+       /* initialize rwlocks */
+       rwlock_init(&bond->lock);
+       rwlock_init(&bond->ptrlock);
+-      
+-      /* space is reserved for stats in alloc_netdev call. */
+-      bond->stats = (struct net_device_stats *)(bond + 1);
++
++      /* Initialize pointers */
+       bond->next = bond->prev = (slave_t *)bond;
+       bond->current_slave = NULL;
+       bond->current_arp_slave = NULL;
+       bond->device = dev;
+       /* Initialize the device structure. */
++      dev->set_mac_address = bond_set_mac_address;
++
+       switch (bond_mode) {
+       case BOND_MODE_ACTIVEBACKUP:
+               dev->hard_start_xmit = bond_xmit_activebackup;
+@@ -3511,6 +3928,7 @@
+       case BOND_MODE_TLB:
+       case BOND_MODE_ALB:
+               dev->hard_start_xmit = bond_alb_xmit;
++              dev->set_mac_address = bond_alb_set_mac_address;
+               break;
+       default:
+               printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode);
+@@ -3522,7 +3940,7 @@
+       dev->stop = bond_close;
+       dev->set_multicast_list = set_multicast_list;
+       dev->do_ioctl = bond_ioctl;
+-
++      dev->change_mtu = bond_change_mtu;
+       dev->tx_queue_len = 0;
+       dev->flags |= IFF_MASTER|IFF_MULTICAST;
+ #ifdef CONFIG_NET_FASTROUTE
+@@ -3549,30 +3967,13 @@
+       } else {
+               printk("out ARP monitoring\n");
+       }
+-
++ 
+ #ifdef CONFIG_PROC_FS
+-      bond->bond_proc_dir = proc_mkdir(dev->name, proc_net);
+-      if (bond->bond_proc_dir == NULL) {
+-              printk(KERN_ERR "%s: Cannot init /proc/net/%s/\n", 
+-                      dev->name, dev->name);
+-              return -ENOMEM;
+-      }
+-      bond->bond_proc_dir->owner = THIS_MODULE;
+-
+-      bond->bond_proc_info_file = 
+-              create_proc_info_entry("info", 0, bond->bond_proc_dir, 
+-                                      bond_get_info);
+-      if (bond->bond_proc_info_file == NULL) {
+-              printk(KERN_ERR "%s: Cannot init /proc/net/%s/info\n", 
+-                      dev->name, dev->name);
+-              remove_proc_entry(dev->name, proc_net);
+-              return -ENOMEM;
+-      }
+-      bond->bond_proc_info_file->owner = THIS_MODULE;
+-#endif /* CONFIG_PROC_FS */
+-
++      bond_create_proc_info(bond);
++#endif
+       list_add_tail(&bond->bond_list, &bond_dev_list);
++
+       return 0;
+ }
+@@ -3605,6 +4006,7 @@
+       return -1;
+ }
++
+ static int __init bonding_init(void)
+ {
+       int no;
+@@ -3625,6 +4027,12 @@
+               }
+       }
++      if (USES_PRIMARY(bond_mode)) {
++              multicast_mode = BOND_MULTICAST_ACTIVE;
++      } else {
++              multicast_mode = BOND_MULTICAST_ALL;
++      }
++
+       if (multicast) {
+               multicast_mode = bond_parse_parm(multicast, bond_mc_tbl);
+               if (multicast_mode == -1) {
+@@ -3811,7 +4219,7 @@
+                         arp_interval = 0;
+               } else { 
+                       u32 ip = in_aton(arp_ip_target[arp_ip_count]); 
+-                      *(u32 *)(arp_ip_target[arp_ip_count]) = ip;
++                      arp_target[arp_ip_count] = ip;
+               }
+         }
+@@ -3837,9 +4245,7 @@
+                      "link failures! see bonding.txt for details.\n");
+       }
+-      if ((primary != NULL) && (bond_mode != BOND_MODE_ACTIVEBACKUP) &&
+-          (bond_mode != BOND_MODE_TLB) &&
+-          (bond_mode != BOND_MODE_ALB)){
++      if ((primary != NULL) && !USES_PRIMARY(bond_mode)) {
+               /* currently, using a primary only makes sense
+                * in active backup, TLB or ALB modes
+                */
+@@ -3850,50 +4256,72 @@
+               primary = NULL;
+       }
+-      register_netdevice_notifier(&bond_netdev_notifier);
++#ifdef CONFIG_PROC_FS
++      bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
++      if (bond_proc_dir == NULL)  {
++              printk(KERN_WARNING
++                     "bonding_init(): can not create /proc/net/" DRV_NAME);
++      } else {
++              bond_proc_dir->owner = THIS_MODULE;
++      }
++#endif
++
++      rtnl_lock();
++      err = 0;
+       for (no = 0; no < max_bonds; no++) {
+               struct net_device *dev;
+-              char name[IFNAMSIZ];
+-              snprintf(name, IFNAMSIZ, "bond%d", no);
+-
+-              dev = alloc_netdev(sizeof(bonding_t) 
+-                                 + sizeof(struct net_device_stats),
+-                                 name, ether_setup);
+-              if (!dev)
+-                      return -ENOMEM;
++              dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
++              if (!dev) {
++                      err = -ENOMEM;
++                      goto out_err;
++              }
++
++              err = dev_alloc_name(dev, "bond%d");
++              if (err < 0) {
++                      free_netdev(dev);
++                      goto out_err;
++              }
++
++              /* bond_init() must be called after dev_alloc_name() (for the
++               * /proc files), but before register_netdevice(), because we
++               * need to set function pointers.
++               */
++              err = bond_init(dev);
++              if (err < 0) {
++                      free_netdev(dev);
++                      goto out_err;
++              }
+-              dev->init = bond_init;
+               SET_MODULE_OWNER(dev);
+-              if ( (err = register_netdev(dev)) ) {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_INFO "%s: register_netdev failed %d\n",
+-                             dev->name, err);
+-#endif
+-                      kfree(dev);
+-                      return err;
+-              }       
++              err = register_netdevice(dev);
++              if (err < 0) {
++                      bond_deinit(dev);
++                      free_netdev(dev);
++                      goto out_err;
++              }
+       }
++
++      rtnl_unlock();
++      register_netdevice_notifier(&bond_netdev_notifier);
++
+       return 0;
++
++out_err:
++      rtnl_unlock();
++
++      /* free and unregister all bonds that were successfully added */
++      bond_free_all();
++
++      return err;
+ }
+ static void __exit bonding_exit(void)
+ {
+-      struct bonding *bond, *nxt;
+-
+       unregister_netdevice_notifier(&bond_netdev_notifier);
+-               
+-      list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+-              struct net_device *dev = bond->device;
+-#ifdef CONFIG_PROC_FS
+-              remove_proc_entry("info", bond->bond_proc_dir);
+-              remove_proc_entry(dev->name, proc_net);
+-#endif
+-              unregister_netdev(dev);
+-              free_netdev(dev);
+-      }
++      bond_free_all();
+ }
+ module_init(bonding_init);
+Index: linux-2.6.0-test5/drivers/net/cs89x0.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/cs89x0.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/cs89x0.c     2003-09-27 11:38:24.648781200 +0800
+@@ -90,7 +90,6 @@
+    or override something. */
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ /*
+  * Set this to zero to disable DMA code
+Index: linux-2.6.0-test5/drivers/net/depca.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/depca.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/depca.c      2003-09-27 11:38:24.701773144 +0800
+@@ -1,4 +1,4 @@
+-/*  depca.c: A DIGITAL DEPCA  & EtherWORKS ethernet driver for linux.
++/*  depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
+     Written 1994, 1995 by David C. Davies.
+@@ -253,7 +253,8 @@
+ #include <linux/types.h>
+ #include <linux/unistd.h>
+ #include <linux/ctype.h>
+-#include <linux/mca-legacy.h>
++#include <linux/moduleparam.h>
++#include <linux/device.h>
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+@@ -265,7 +266,6 @@
+ #endif
+ #ifdef CONFIG_EISA
+-#include <linux/device.h>
+ #include <linux/eisa.h>
+ #endif
+@@ -305,21 +305,21 @@
+ ** EISA bus defines
+ */
+ #define DEPCA_EISA_IO_PORTS 0x0c00    /* I/O port base address, slot 0 */
+-#define MAX_EISA_SLOTS 16
+-#define EISA_SLOT_INC 0x1000
+ /*
+ ** ISA Bus defines
+ */
+ #define DEPCA_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0xe0000,0x00000}
+-#define DEPCA_IO_PORTS {0x300, 0x200, 0}
+ #define DEPCA_TOTAL_SIZE 0x10
+-static short mem_chkd;
+-/*
+-** Adapter ID for the MCA EtherWORKS DE210/212 adapter
+-*/
+-#define DE212_ID 0x6def
++static struct {
++      u_long iobase;
++      struct platform_device *device;
++} depca_io_ports[] = {
++      { 0x300, NULL },
++      { 0x200, NULL },
++      { 0    , NULL },
++};
+ /*
+ ** Name <-> Adapter mapping
+@@ -330,34 +330,86 @@
+                        "DE210","DE212",\
+                          "DE422",\
+                          ""}
+-static enum {
++
++static char* __initdata depca_signature[] = DEPCA_SIGNATURE;
++
++enum depca_type {
+       DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
+-} adapter;
++};
++
++static char depca_string[] = "depca";
++
++static int depca_device_remove (struct device *device);
+ #ifdef CONFIG_EISA
+ struct eisa_device_id depca_eisa_ids[] = {
+-      { "DEC4220" },
++      { "DEC4220", de422 },
+       { "" }
+ };
+ static int depca_eisa_probe  (struct device *device);
+-static int depca_eisa_remove (struct device *device);
+ struct eisa_driver depca_eisa_driver = {
+       .id_table = depca_eisa_ids,
+       .driver   = {
+-              .name    = "depca",
++              .name    = depca_string,
+               .probe   = depca_eisa_probe,
+-              .remove  = __devexit_p (depca_eisa_remove)
++              .remove  = __devexit_p (depca_device_remove)
+       }
+ };
+ #endif
++#ifdef CONFIG_MCA
++/*
++** Adapter ID for the MCA EtherWORKS DE210/212 adapter
++*/
++#define DE210_ID 0x628d
++#define DE212_ID 0x6def
++
++static short depca_mca_adapter_ids[] = {
++      DE210_ID,
++      DE212_ID,
++      0x0000
++};
++
++static char *depca_mca_adapter_name[] = {
++      "DEC EtherWORKS MC Adapter (DE210)",
++      "DEC EtherWORKS MC Adapter (DE212)",
++      NULL
++};
++
++static enum depca_type depca_mca_adapter_type[] = {
++      de210,
++      de212,
++      0
++};
++
++static int depca_mca_probe (struct device *);
++
++static struct mca_driver depca_mca_driver = {
++      .id_table = depca_mca_adapter_ids,
++      .driver   = {
++              .name   = depca_string,
++              .bus    = &mca_bus_type,
++              .probe  = depca_mca_probe,
++              .remove = __devexit_p(depca_device_remove),
++      },
++};
++#endif
++
++static int depca_isa_probe (struct device *);
++
++static struct device_driver depca_isa_driver = {
++      .name   = depca_string,
++      .bus    = &platform_bus_type,
++      .probe  = depca_isa_probe,
++      .remove = __devexit_p(depca_device_remove),
++};
++      
+ /*
+ ** Miscellaneous info...
+ */
+ #define DEPCA_STRLEN 16
+-#define MAX_NUM_DEPCAS 2
+ /*
+ ** Memory Alignment. Each descriptor is 4 longwords long. To force a
+@@ -402,10 +454,13 @@
+ #define DEPCA_PKT_BIN_SZ  128 /* Should be >=100 unless you
+                                  increase DEPCA_PKT_STAT_SZ */
+ struct depca_private {
+-      char devname[DEPCA_STRLEN];     /* Device Product String                  */
+       char adapter_name[DEPCA_STRLEN];        /* /proc/ioports string                  */
+-      char adapter;           /* Adapter type                           */
+-      char mca_slot;          /* MCA slot, if MCA else -1               */
++      enum depca_type adapter;                /* Adapter type */
++      enum {
++                DEPCA_BUS_MCA = 1,
++                DEPCA_BUS_ISA,
++                DEPCA_BUS_EISA,
++        } depca_bus;          /* type of bus */
+       struct depca_init init_block;   /* Shadow Initialization block            */
+ /* CPU address space fields */
+       struct depca_rx_desc *rx_ring;  /* Pointer to start of RX descriptor ring */
+@@ -467,45 +522,39 @@
+ /*
+ ** Private functions
+ */
+-static int depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot);
+ static void depca_init_ring(struct net_device *dev);
+ static int depca_rx(struct net_device *dev);
+ static int depca_tx(struct net_device *dev);
+ static void LoadCSRs(struct net_device *dev);
+ static int InitRestartDepca(struct net_device *dev);
+-static void DepcaSignature(char *name, u_long paddr);
++static int DepcaSignature(char *name, u_long paddr);
+ static int DevicePresent(u_long ioaddr);
+ static int get_hw_addr(struct net_device *dev);
+ static void SetMulticastFilter(struct net_device *dev);
+-static void isa_probe(struct net_device *dev, u_long iobase);
+-#ifdef CONFIG_MCA
+-static void mca_probe(struct net_device *dev, u_long iobase);
+-#endif
+-static struct net_device *alloc_device(struct net_device *dev, u_long iobase);
+-static int depca_dev_index(char *s);
+-static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *));
+ static int load_packet(struct net_device *dev, struct sk_buff *skb);
+ static void depca_dbg_open(struct net_device *dev);
+-#ifdef MODULE
+-static int autoprobed = 1, loading_module = 1;
+-# else
+ static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
+ static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 };
+ static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 };
+ static u_char *depca_irq;
+-static int autoprobed, loading_module;
+-#endif                                /* MODULE */
+-static char name[DEPCA_STRLEN];
+-static int num_depcas, num_eth;
++static int irq;
++static int io;
++static char *adapter_name;
+ static int mem;                       /* For loadable module assignment
+                                  use insmod mem=0x????? .... */
+-static char *adapter_name;    /* = '\0';     If no PROM when loadable module
+-                                 use insmod adapter_name=DE??? ...
+-                                 bss initializes this to zero
+-                               */
++module_param (irq, int, 0);
++module_param (io, int, 0);
++module_param (adapter_name, charp, 0);
++module_param (mem, int, 0);
++MODULE_PARM_DESC(irq, "DEPCA IRQ number");
++MODULE_PARM_DESC(io, "DEPCA I/O base address");
++MODULE_PARM_DESC(adapter_name, "DEPCA adapter name");
++MODULE_PARM_DESC(mem, "DEPCA shared memory address");
++MODULE_LICENSE("GPL");
++
+ /*
+ ** Miscellaneous defines...
+ */
+@@ -513,52 +562,30 @@
+     outw(CSR0, DEPCA_ADDR);\
+     outw(STOP, DEPCA_DATA)
+-int __init depca_probe(struct net_device *dev)
+-{
+-      int tmp = num_depcas, status = -ENODEV;
+-      u_long iobase = dev->base_addr;
+-
+-      SET_MODULE_OWNER(dev);
+-
+-      if ((iobase == 0) && loading_module) {
+-              printk("Autoprobing is not supported when loading a module based driver.\n");
+-              status = -EIO;
+-      } else {
+-#ifdef CONFIG_MCA
+-              mca_probe(dev, iobase);
+-#endif
+-              isa_probe(dev, iobase);
+-#ifdef CONFIG_EISA
+-              eisa_driver_register (&depca_eisa_driver);
+-#endif
+-
+-              if ((tmp == num_depcas) && (iobase != 0) && loading_module) {
+-                      printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name, iobase);
+-              }
+-
+-              /*
+-                 ** Walk the device list to check that at least one device
+-                 ** initialised OK
+-               */
+-              for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
+-
+-              if (dev->priv)
+-                      status = 0;
+-              if (iobase == 0)
+-                      autoprobed = 1;
+-      }
+-
+-      return status;
+-}
+-
+-static int __init depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot)
++static int __init depca_hw_init (struct net_device *dev, struct device *device)
+ {
+       struct depca_private *lp;
+       int i, j, offset, netRAM, mem_len, status = 0;
+       s16 nicsr;
+-      u_long mem_start = 0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
+-      int is_eisa = ((ioaddr & 0x0fff) == DEPCA_EISA_IO_PORTS);
++      u_long ioaddr;
++      u_long mem_start;
++
++      /*
++       * We are now supposed to enter this function with the
++       * following fields filled with proper values :
++       *
++       * dev->base_addr
++       * lp->mem_start
++       * lp->depca_bus
++       * lp->adapter
++       *
++       * dev->irq can be set if known from device configuration (on
++       * MCA or EISA) or module option. Otherwise, it will be auto
++       * detected.
++       */
++      ioaddr = dev->base_addr;
++      
+       STOP_DEPCA;
+       nicsr = inb(DEPCA_NICSR);
+@@ -569,24 +596,34 @@
+               return -ENXIO;
+       }
+-      do {
+-              strcpy(name, (adapter_name ? adapter_name : ""));
+-              mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]);
+-              DepcaSignature(name, mem_start);
+-      } while (!mem && mem_base[mem_chkd] && (adapter == unknown));
++      lp = (struct depca_private *) dev->priv;
++      mem_start = lp->mem_start;
+-      if ((adapter == unknown) || !mem_start) {       /* DEPCA device not found */
++      if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
+               return -ENXIO;
+-      }
+-      dev->base_addr = ioaddr;
++      printk ("%s: %s at 0x%04lx",
++              device->bus_id, depca_signature[lp->adapter], ioaddr);
++      
++      switch (lp->depca_bus) {
++#ifdef CONFIG_MCA
++      case DEPCA_BUS_MCA:
++              printk(" (MCA slot %d)", to_mca_device(device)->slot + 1);
++              break;
++#endif
++
++#ifdef CONFIG_EISA
++      case DEPCA_BUS_EISA:
++              printk(" (EISA slot %d)", to_eisa_device(device)->slot);
++              break;
++#endif
+-      if (mca_slot != -1) {
+-              printk("%s: %s at 0x%04lx (MCA slot %d)", dev->name, name, ioaddr, mca_slot);
+-      } else if (is_eisa) {   /* EISA slot address */
+-              printk("%s: %s at 0x%04lx (EISA slot %d)", dev->name, name, ioaddr, (int) ((ioaddr >> 12) & 0x0f));
+-      } else {                /* ISA port address */
+-              printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);
++      case DEPCA_BUS_ISA:
++              break;
++
++      default:
++              printk("Unknown DEPCA bus %d\n", lp->depca_bus);
++              return -ENXIO;
+       }
+       printk(", h/w address ");
+@@ -601,18 +638,20 @@
+       printk("%2.2x", dev->dev_addr[i]);
+       /* Set up the maximum amount of network RAM(kB) */
+-      netRAM = ((adapter != DEPCA) ? 64 : 48);
+-      if ((nicsr & _128KB) && (adapter == de422))
++      netRAM = ((lp->adapter != DEPCA) ? 64 : 48);
++      if ((nicsr & _128KB) && (lp->adapter == de422))
+               netRAM = 128;
+-      offset = 0x0000;
+       /* Shared Memory Base Address */
+       if (nicsr & BUF) {
+-              offset = 0x8000;        /* 32kbyte RAM offset */
+               nicsr &= ~BS;   /* DEPCA RAM in top 32k */
+               netRAM -= 32;
++
++              /* Only EISA/ISA needs start address to be re-computed */
++              if (lp->depca_bus != DEPCA_BUS_MCA)
++                      mem_start += 0x8000;
+       }
+-      mem_start += offset;    /* (E)ISA start address */
++      
+       if ((mem_len = (NUM_RX_DESC * (sizeof(struct depca_rx_desc) + RX_BUFF_SZ) + NUM_TX_DESC * (sizeof(struct depca_tx_desc) + TX_BUFF_SZ) + sizeof(struct depca_init)))
+           > (netRAM << 10)) {
+               printk(",\n       requests %dkB RAM: only %dkB is available!\n", (mem_len >> 10), netRAM);
+@@ -622,23 +661,14 @@
+       printk(",\n      has %dkB RAM at 0x%.5lx", netRAM, mem_start);
+       /* Enable the shadow RAM. */
+-      if (adapter != DEPCA) {
++      if (lp->adapter != DEPCA) {
+               nicsr |= SHE;
+               outb(nicsr, DEPCA_NICSR);
+       }
+-      /* Define the device private memory */
+-      if (!is_eisa) {
+-              dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);
+-              if (dev->priv == NULL)
+-                      return -ENOMEM;
+-      }
+-      lp = (struct depca_private *) dev->priv;
+-      memset((char *) dev->priv, 0, sizeof(struct depca_private));
+-      lp->adapter = adapter;
+-      lp->mca_slot = mca_slot;
+       lp->lock = SPIN_LOCK_UNLOCKED;
+-      sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
++      sprintf(lp->adapter_name, "%s (%s)",
++              depca_signature[lp->adapter], device->bus_id);
+       status = -EBUSY;
+       /* Initialisation Block */
+@@ -702,7 +732,6 @@
+       /* To auto-IRQ we enable the initialization-done and DMA err,
+          interrupts. For now we will always get a DMA error. */
+       if (dev->irq < 2) {
+-#ifndef MODULE
+               unsigned char irqnum;
+               unsigned long irq_mask, delay;
+@@ -725,6 +754,9 @@
+               case de422:
+                       depca_irq = de422_irq;
+                       break;
++
++              default:
++                      break;  /* Not reached */
+               }
+               /* Trigger an initialization just for the interrupt. */
+@@ -733,6 +765,7 @@
+               delay = jiffies + HZ/50;
+               while (time_before(jiffies, delay))
+                       yield();
++
+               irqnum = probe_irq_off(irq_mask);
+               status = -ENXIO;
+@@ -746,13 +779,11 @@
+                                       printk(" and uses IRQ%d.\n", dev->irq);
+                               }
+-                      status = -ENXIO;
+                       if (!dev->irq) {
+                               printk(" but incorrect IRQ line detected.\n");
+-                              goto out_priv;
++                              return -ENXIO;
+                       }
+               }
+-#endif                                /* MODULE */
+       } else {
+               printk(" and assigned IRQ%d.\n", dev->irq);
+       }
+@@ -773,17 +804,14 @@
+       dev->mem_start = 0;
+-      /* Fill in the generic field of the device structure. */
+-      if (!is_eisa)
+-              ether_setup(dev);
++      device->driver_data = dev;
++      SET_NETDEV_DEV (dev, device);
++      
++      register_netdev (dev);
+       return 0;
+-      out_priv:
+-      if (!is_eisa) {
+-              kfree(dev->priv);
+-              dev->priv = NULL;
+-      } else {
+-              unregister_netdev (dev);
+-      }
++
++ out_priv:
++      
+       return status;
+ }
\f
+@@ -1284,215 +1312,265 @@
+       return;
+ }
++static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
++{
++      int status = 0;
++      
++      if (!request_region (ioaddr, DEPCA_TOTAL_SIZE, depca_string)) {
++              status = -EBUSY;
++              goto out;
++      }
++      
++      if (DevicePresent(ioaddr)) {
++              status = -ENODEV;
++              goto out_release;
++      }
++
++      if (!(*devp = alloc_etherdev (sizeof (struct depca_private)))) {
++              status = -ENOMEM;
++              goto out_release;
++      }
++
++      return 0;
++      
++ out_release:
++      release_region (ioaddr, DEPCA_TOTAL_SIZE);
++ out:
++      return status;
++}
++
+ #ifdef CONFIG_MCA
+ /*
+ ** Microchannel bus I/O device probe
+ */
+-static void __init mca_probe(struct net_device *dev, u_long ioaddr)
++static int __init depca_mca_probe(struct device *device)
+ {
+       unsigned char pos[2];
+       unsigned char where;
+-      unsigned long iobase;
+-      int irq;
+-      int slot = 0;
++      unsigned long iobase, mem_start;
++      int irq, err;
++      struct mca_device *mdev = to_mca_device (device);
++      struct net_device *dev;
++      struct depca_private *lp;
+       /*
+-         ** See if we've been here before.
+-       */
+-      if ((!ioaddr && autoprobed) || (ioaddr && !loading_module))
+-              return;
+-
+-      if (MCA_bus) {
+-              /*
+-                 ** Search for the adapter.  If an address has been given, search 
+-                 ** specifically for the card at that address.  Otherwise find the
+-                 ** first card in the system.
+-               */
+-              while ((dev != NULL) && ((slot = mca_find_adapter(DE212_ID, slot)) != MCA_NOTFOUND)) {
+-                      pos[0] = mca_read_stored_pos(slot, 2);
+-                      pos[1] = mca_read_stored_pos(slot, 3);
+-
+-                      /*
+-                         ** IO of card is handled by bits 1 and 2 of pos0.    
+-                         **
+-                         **    bit2 bit1    IO
+-                         **       0    0    0x2c00
+-                         **       0    1    0x2c10
+-                         **       1    0    0x2c20
+-                         **       1    1    0x2c30
+-                       */
+-                      where = (pos[0] & 6) >> 1;
+-                      iobase = 0x2c00 + (0x10 * where);
+-
+-                      if ((ioaddr) && (ioaddr != iobase)) {
+-                              /*
+-                                 ** Card was found, but not at the right IO location. Continue 
+-                                 ** scanning from the next MCA slot up for another card.
+-                               */
+-                              slot++;
+-                              continue;
+-                      }
+-
+-                      /*
+-                         ** Found the adapter we were looking for. Now start setting it up.
+-                         ** 
+-                         ** First work on decoding the IRQ.  It's stored in the lower 4 bits
+-                         ** of pos1.  Bits are as follows (from the ADF file):
+-                         **
+-                         **      Bits           
+-                         **   3   2   1   0    IRQ 
+-                         **   --------------------
+-                         **   0   0   1   0     5
+-                         **   0   0   0   1     9
+-                         **   0   1   0   0    10
+-                         **   1   0   0   0    11
+-                         * */
+-                      where = pos[1] & 0x0f;
+-                      switch (where) {
+-                      case 1:
+-                              irq = 9;
+-                              break;
+-                      case 2:
+-                              irq = 5;
+-                              break;
+-                      case 4:
+-                              irq = 10;
+-                              break;
+-                      case 8:
+-                              irq = 11;
+-                              break;
+-                      default:
+-                              printk("%s: mca_probe IRQ error.  You should never get here (%d).\n", dev->name, where);
+-                              return;
+-                      }
+-
+-                      /*
+-                         ** Shared memory address of adapter is stored in bits 3-5 of pos0.
+-                         ** They are mapped as follows:
+-                         **
+-                         **    Bit
+-                         **   5  4  3       Memory Addresses
+-                         **   0  0  0       C0000-CFFFF (64K)
+-                         **   1  0  0       C8000-CFFFF (32K)
+-                         **   0  0  1       D0000-DFFFF (64K)
+-                         **   1  0  1       D8000-DFFFF (32K)
+-                         **   0  1  0       E0000-EFFFF (64K)
+-                         **   1  1  0       E8000-EFFFF (32K)
+-                       */
+-                      where = (pos[0] & 0x18) >> 3;
+-                      mem = 0xc0000 + (where * 0x10000);
+-                      if (pos[0] & 0x20) {
+-                              mem += 0x8000;
+-                      }
++      ** Search for the adapter.  If an address has been given, search 
++      ** specifically for the card at that address.  Otherwise find the
++      ** first card in the system.
++      */
++      
++      pos[0] = mca_device_read_stored_pos(mdev, 2);
++      pos[1] = mca_device_read_stored_pos(mdev, 3);
+-                      /*
+-                         ** Get everything allocated and initialized...  (almost just
+-                         ** like the ISA and EISA probes)
+-                       */
+-                      if (!request_region (iobase, DEPCA_TOTAL_SIZE, "depca")) {
+-                              if (autoprobed)
+-                                      printk(KERN_WARNING "%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
+-                              goto next;
+-                      }
+-                      if (DevicePresent(iobase) != 0) {
+-                              /*
+-                                 ** If the MCA configuration says the card should be here,
+-                                 ** it really should be here.
+-                               */
+-                              printk(KERN_ERR "%s: MCA reports card at 0x%lx but it is not responding.\n", dev->name, iobase);
+-                              goto release_next;
+-                      }
++      /*
++      ** IO of card is handled by bits 1 and 2 of pos0.    
++      **
++      **    bit2 bit1    IO
++      **       0    0    0x2c00
++      **       0    1    0x2c10
++      **       1    0    0x2c20
++      **       1    1    0x2c30
++      */
++      where = (pos[0] & 6) >> 1;
++      iobase = 0x2c00 + (0x10 * where);
+-                      if (!(dev = alloc_device(dev, iobase)))
+-                              goto release_next;
++      /*
++      ** Found the adapter we were looking for. Now start setting it up.
++      ** 
++      ** First work on decoding the IRQ.  It's stored in the lower 4 bits
++      ** of pos1.  Bits are as follows (from the ADF file):
++      **
++      **      Bits           
++      **   3   2   1   0    IRQ 
++      **   --------------------
++      **   0   0   1   0     5
++      **   0   0   0   1     9
++      **   0   1   0   0    10
++      **   1   0   0   0    11
++      */
++      where = pos[1] & 0x0f;
++      switch (where) {
++      case 1:
++              irq = 9;
++              break;
++      case 2:
++              irq = 5;
++              break;
++      case 4:
++              irq = 10;
++              break;
++      case 8:
++              irq = 11;
++              break;
++      default:
++              printk("%s: mca_probe IRQ error.  You should never get here (%d).\n", dev->name, where);
++              return -EINVAL;
++      }
+-                      num_eth++;
+-                      dev->irq = irq;
+-                      if (depca_hw_init(dev, iobase, slot))
+-                              goto release_next;
++      /*
++      ** Shared memory address of adapter is stored in bits 3-5 of pos0.
++      ** They are mapped as follows:
++      **
++      **    Bit
++      **   5  4  3       Memory Addresses
++      **   0  0  0       C0000-CFFFF (64K)
++      **   1  0  0       C8000-CFFFF (32K)
++      **   0  0  1       D0000-DFFFF (64K)
++      **   1  0  1       D8000-DFFFF (32K)
++      **   0  1  0       E0000-EFFFF (64K)
++      **   1  1  0       E8000-EFFFF (32K)
++      */
++      where = (pos[0] & 0x18) >> 3;
++      mem_start = 0xc0000 + (where * 0x10000);
++      if (pos[0] & 0x20) {
++              mem_start += 0x8000;
++      }
++
++      /* claim the slot */
++      strncpy(mdev->name, depca_mca_adapter_name[mdev->index],
++              sizeof(mdev->name));
++      mca_device_set_claim(mdev, 1);
++      
++        /*
++      ** Get everything allocated and initialized...  (almost just
++      ** like the ISA and EISA probes)
++      */
++      irq = mca_device_transform_irq(mdev, irq);
++      iobase = mca_device_transform_ioport(mdev, iobase);
++
++      if ((err = depca_common_init (iobase, &dev)))
++              goto out_unclaim;
++
++      dev->irq = irq;
++      dev->base_addr = iobase;
++      lp = dev->priv;
++      lp->depca_bus = DEPCA_BUS_MCA;
++      lp->adapter = depca_mca_adapter_type[mdev->index];
++      lp->mem_start = mem_start;
++      
++      if ((err = depca_hw_init(dev, device)))
++              goto out_free;
+                       
+-                      /*
+-                      ** Adapter initialized correctly:  Name it in
+-                      ** /proc/mca.
+-                      */
+-                      mca_set_adapter_name(slot, "DE210/212 Ethernet Adapter");
+-                      mca_mark_as_used(slot);
+-                      num_depcas++;
+-
+-                      /*
+-                         ** If this is a probe by a module, return after setting up the
+-                         ** given card.
+-                       */
+-                      if (ioaddr)
+-                              return;
+-
+-                      /*
+-                      ** Set up to check the next slot and loop.
+-                       */
+-                      slot++;
+-                      continue;
++      return 0;
+-      release_next:
+-                      release_region (iobase, DEPCA_TOTAL_SIZE);
+-      next:
+-                      slot++;
+-              }
+-      }
++ out_free:
++      free_netdev (dev);
++      release_region (iobase, DEPCA_TOTAL_SIZE);
++ out_unclaim:
++      mca_device_set_claim(mdev, 0);
+-      return;
++      return err;;
+ }
+ #endif
+ /*
+ ** ISA bus I/O device probe
+ */
+-static void __init isa_probe(struct net_device *dev, u_long ioaddr)
++
++static void depca_platform_release (struct device *device)
+ {
+-      int i = num_depcas, maxSlots;
+-      s32 ports[] = DEPCA_IO_PORTS;
++      struct platform_device *pldev;
+-      if (!ioaddr && autoprobed)
+-              return;         /* Been here before ! */
+-      if (ioaddr > 0x400)
+-              return;         /* EISA Address */
+-      if (i >= MAX_NUM_DEPCAS)
+-              return;         /* Too many ISA adapters */
+-
+-      if (ioaddr == 0) {      /* Autoprobing */
+-              maxSlots = MAX_NUM_DEPCAS;
+-      } else {                /* Probe a specific location */
+-              ports[i] = ioaddr;
+-              maxSlots = i + 1;
+-      }
+-
+-      for (; (i < maxSlots) && (dev != NULL) && ports[i]; i++) {
+-              if (!request_region (ports[i], DEPCA_TOTAL_SIZE, "depca")) {
+-                      if (autoprobed)
+-                              printk("%s: region already allocated at 0x%04x.\n", dev->name, ports[i]);
++      /* free device */
++      pldev = to_platform_device (device);
++      kfree (pldev);
++}
++
++static void __init depca_platform_probe (void)
++{
++      int i;
++      struct platform_device *pldev;
++
++      for (i = 0; depca_io_ports[i].iobase; i++) {
++              depca_io_ports[i].device = NULL;
++              
++              /* if an address has been specified on the command
++               * line, use it (if valid) */
++              if (io && io != depca_io_ports[i].iobase)
++                      continue;
++              
++              if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
+                       continue;
+-              }
+-              if (DevicePresent(ports[i])) {
+-                      release_region (ports[i], DEPCA_TOTAL_SIZE);
++              memset (pldev, 0, sizeof (*pldev));
++              pldev->name = depca_string;
++              pldev->id   = i;
++              pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
++              pldev->dev.release       = depca_platform_release;
++              depca_io_ports[i].device = pldev;
++
++              if (platform_device_register (pldev)) {
++                      kfree (pldev);
++                      depca_io_ports[i].device = NULL;
+                       continue;
+               }
+-              if (!(dev = alloc_device(dev, ports[i]))) {
+-                      release_region (ports[i], DEPCA_TOTAL_SIZE);
+-                      continue;
++              if (!pldev->dev.driver) {
++              /* The driver was not bound to this device, there was
++               * no hardware at this address. Unregister it, as the
++               * release fuction will take care of freeing the
++               * allocated structure */
++                      
++                      depca_io_ports[i].device = NULL;
++                      platform_device_unregister (pldev);
+               }
++      }
++}
+-              num_eth++;
++static enum depca_type __init depca_shmem_probe (ulong *mem_start)
++{
++      u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
++      enum depca_type adapter = unknown;
++      int i;
+-              if (depca_hw_init(dev, ports[i], -1)) {
+-                      release_region (ports[i], DEPCA_TOTAL_SIZE);
+-                      continue;
+-              }
++      for (i = 0; mem_base[i]; i++) {
++              *mem_start = mem ? mem : mem_base[i];
++              adapter = DepcaSignature (adapter_name, *mem_start);
++              if (adapter != unknown)
++                      break;
++      }
++
++      return adapter;
++}
+-              num_depcas++;
++static int __init depca_isa_probe (struct device *device)
++{
++      struct net_device *dev;
++      struct depca_private *lp;
++      u_long ioaddr, mem_start = 0;
++      enum depca_type adapter = unknown;
++      int status = 0;
++
++      ioaddr = (u_long) device->platform_data;
++
++      if ((status = depca_common_init (ioaddr, &dev)))
++              goto out;
++
++      adapter = depca_shmem_probe (&mem_start);
++      
++      if (adapter == unknown) {
++              status = -ENODEV;
++              goto out_free;
+       }
+-      return;
++      dev->base_addr = ioaddr;
++      dev->irq = irq;         /* Use whatever value the user gave
++                               * us, and 0 if he didn't. */
++      lp = dev->priv;
++      lp->depca_bus = DEPCA_BUS_ISA;
++      lp->adapter = adapter;
++      lp->mem_start = mem_start;
++      
++      if ((status = depca_hw_init(dev, device)))
++              goto out_free;
++      
++      return 0;
++
++ out_free:
++      free_netdev (dev);
++      release_region (ioaddr, DEPCA_TOTAL_SIZE);
++ out:
++      return status;
+ }
+ /*
+@@ -1504,202 +1582,120 @@
+ {
+       struct eisa_device *edev;
+       struct net_device *dev;
+-      u_long iobase;
++      struct depca_private *lp;
++      u_long ioaddr, mem_start;
+       int status = 0;
+       edev = to_eisa_device (device);
+-      iobase = edev->base_addr + DEPCA_EISA_IO_PORTS;
++      ioaddr = edev->base_addr + DEPCA_EISA_IO_PORTS;
+-      if (!request_region (iobase, DEPCA_TOTAL_SIZE, "depca")) {
+-              status = -EBUSY;
++      if ((status = depca_common_init (ioaddr, &dev)))
+               goto out;
+-      }
+-      
+-      if (DevicePresent(iobase)) {
+-              status = -ENODEV;
+-              goto out_release;
+-      }
+-      if (!(dev = init_etherdev (NULL, sizeof (struct depca_private)))) {
+-              status = -ENOMEM;
+-              goto out_release;
+-      }
+-              
+-      eisa_set_drvdata (edev, dev);
++      /* It would have been nice to get card configuration from the
++       * card. Unfortunately, this register is write-only (shares
++       * it's address with the ethernet prom)... As we don't parse
++       * the EISA configuration structures (yet... :-), just rely on
++       * the ISA probing to sort it out... */
++      
++      depca_shmem_probe (&mem_start);
+-      if ((status = depca_hw_init(dev, iobase, -1)))
++      dev->base_addr = ioaddr;
++      dev->irq = irq;
++      lp = dev->priv;
++      lp->depca_bus = DEPCA_BUS_EISA;
++      lp->adapter = edev->id.driver_data;
++      lp->mem_start = mem_start;
++      
++      if ((status = depca_hw_init(dev, device)))
+               goto out_free;
+-
+-      num_depcas++;
++      
+       return 0;
+  out_free:
+-      kfree (dev);
+- out_release:
+-      release_region (iobase, DEPCA_TOTAL_SIZE);
++      free_netdev (dev);
++      release_region (ioaddr, DEPCA_TOTAL_SIZE);
+  out:
+       return status;
+ }
++#endif
+-static int __devexit depca_eisa_remove (struct device *device)
++static int __devexit depca_device_remove (struct device *device)
+ {
+       struct net_device *dev;
+-      struct eisa_device *edev;
+       struct depca_private *lp;
++      int bus;
+-      edev = to_eisa_device (device);
+-      dev  = eisa_get_drvdata (edev);
++      dev  = device->driver_data;
+       lp   = dev->priv;
+       unregister_netdev (dev);
+       iounmap (lp->sh_mem);
+       release_mem_region (lp->mem_start, lp->mem_len);
+       release_region (dev->base_addr, DEPCA_TOTAL_SIZE);
+-      kfree (dev);
++      bus = lp->depca_bus;
++      free_netdev (dev);
+       return 0;
+ }
+-#endif
+-
+-/*
+-** Search the entire 'eth' device list for a fixed probe. If a match isn't
+-** found then check for an autoprobe or unused device location. If they
+-** are not available then insert a new device structure at the end of
+-** the current list.
+-*/
+-static struct net_device *__init alloc_device(struct net_device *dev, u_long iobase)
+-{
+-      struct net_device *adev = NULL;
+-      int fixed = 0, new_dev = 0;
+-
+-      num_eth = depca_dev_index(dev->name);
+-      if (loading_module)
+-              return dev;
+-
+-      while (1) {
+-              if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0)) && !adev) {
+-                      adev = dev;
+-              } else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
+-                      fixed = 1;
+-              } else {
+-                      if (dev->next == NULL) {
+-                              new_dev = 1;
+-                      } else if (strncmp(dev->next->name, "eth", 3) != 0) {
+-                              new_dev = 1;
+-                      }
+-              }
+-              if ((dev->next == NULL) || new_dev || fixed)
+-                      break;
+-              dev = dev->next;
+-              num_eth++;
+-      }
+-      if (adev && !fixed) {
+-              dev = adev;
+-              num_eth = depca_dev_index(dev->name);
+-              new_dev = 0;
+-      }
+-
+-      if (((dev->next == NULL) && ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) || new_dev) {
+-              num_eth++;      /* New device */
+-              dev = insert_device(dev, iobase, depca_probe);
+-      }
+-
+-      return dev;
+-}
+-
+-/*
+-** If at end of eth device list and can't use current entry, malloc
+-** one up. If memory could not be allocated, print an error message.
+-*/
+-static struct net_device *__init insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *))
+-{
+-      struct net_device *new;
+-
+-      new = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-      if (new == NULL) {
+-              printk("eth%d: Device not initialised, insufficient memory\n", num_eth);
+-              return NULL;
+-      } else {
+-              new->next = dev->next;
+-              dev->next = new;
+-              dev = dev->next;        /* point to the new device */
+-              if (num_eth > 9999) {
+-                      sprintf(dev->name, "eth????");  /* New device name */
+-              } else {
+-                      sprintf(dev->name, "eth%d", num_eth);   /* New device name */
+-              }
+-              dev->base_addr = iobase;        /* assign the io address */
+-              dev->init = init;       /* initialisation routine */
+-      }
+-
+-      return dev;
+-}
+-
+-static int __init depca_dev_index(char *s)
+-{
+-      int i = 0, j = 0;
+-
+-      for (; *s; s++) {
+-              if (isdigit(*s)) {
+-                      j = 1;
+-                      i = (i * 10) + (*s - '0');
+-              } else if (j)
+-                      break;
+-      }
+-
+-      return i;
+-}
+ /*
+ ** Look for a particular board name in the on-board Remote Diagnostics
+ ** and Boot (readb) ROM. This will also give us a clue to the network RAM
+ ** base address.
+ */
+-static void __init DepcaSignature(char *name, u_long paddr)
++static int __init DepcaSignature(char *name, u_long base_addr)
+ {
+       u_int i, j, k;
+-      const char *signatures[] = DEPCA_SIGNATURE;
+       void *ptr;
+       char tmpstr[16];
++      u_long prom_addr = base_addr + 0xc000;
++      u_long mem_addr = base_addr + 0x8000; /* 32KB */
++
++      /* Can't reserve the prom region, it is already marked as
++       * used, at least on x86. Instead, reserve a memory region a
++       * board would certainly use. If it works, go ahead. If not,
++       * run like hell... */
++      
++      if (!request_mem_region (mem_addr, 16, depca_string))
++              return unknown;
+       /* Copy the first 16 bytes of ROM */
+-      ptr = ioremap(paddr + 0xc000, 16);
++
++      ptr = ioremap(prom_addr, 16);
+       if (ptr == NULL) {
+-              printk(KERN_ERR "depca: I/O remap failed at %lx\n", paddr + 0xc000);
+-              adapter = unknown;
+-              return;
++              printk(KERN_ERR "depca: I/O remap failed at %lx\n", prom_addr);
++              return unknown;
+       }
+       for (i = 0; i < 16; i++) {
+               tmpstr[i] = readb(ptr + i);
+       }
+       iounmap(ptr);
++      release_mem_region (mem_addr, 16);
++
+       /* Check if PROM contains a valid string */
+-      for (i = 0; *signatures[i] != '\0'; i++) {
+-              for (j = 0, k = 0; j < 16 && k < strlen(signatures[i]); j++) {
+-                      if (signatures[i][k] == tmpstr[j]) {    /* track signature */
++      for (i = 0; *depca_signature[i] != '\0'; i++) {
++              for (j = 0, k = 0; j < 16 && k < strlen(depca_signature[i]); j++) {
++                      if (depca_signature[i][k] == tmpstr[j]) {       /* track signature */
+                               k++;
+                       } else {        /* lost signature; begin search again */
+                               k = 0;
+                       }
+               }
+-              if (k == strlen(signatures[i]))
++              if (k == strlen(depca_signature[i]))
+                       break;
+       }
+       /* Check if name string is valid, provided there's no PROM */
+-      if (*name && (i == unknown)) {
+-              for (i = 0; *signatures[i] != '\0'; i++) {
+-                      if (strcmp(name, signatures[i]) == 0)
++      if (name && *name && (i == unknown)) {
++              for (i = 0; *depca_signature[i] != '\0'; i++) {
++                      if (strcmp(name, depca_signature[i]) == 0)
+                               break;
+               }
+       }
+-      /* Update search results */
+-      strcpy(name, signatures[i]);
+-      adapter = i;
+-
+-      return;
++      return i;
+ }
+ /*
+@@ -1773,10 +1769,11 @@
+ static int __init get_hw_addr(struct net_device *dev)
+ {
+       u_long ioaddr = dev->base_addr;
++      struct depca_private *lp = dev->priv;
+       int i, k, tmp, status = 0;
+       u_short j, x, chksum;
+-      x = (((adapter == de100) || (adapter == de101)) ? 1 : 0);
++      x = (((lp->adapter == de100) || (lp->adapter == de101)) ? 1 : 0);
+       for (i = 0, k = 0, j = 0; j < 3; j++) {
+               k <<= 1;
+@@ -2083,55 +2080,40 @@
+       return status;
+ }
+-#ifdef MODULE
+-static struct net_device thisDepca;
+-static int irq = 7;           /* EDIT THESE LINE FOR YOUR CONFIGURATION */
+-static int io = 0x200;                /* Or use the irq= io= options to insmod */
+-MODULE_PARM(irq, "i");
+-MODULE_PARM(io, "i");
+-MODULE_PARM_DESC(irq, "DEPCA IRQ number");
+-MODULE_PARM_DESC(io, "DEPCA I/O base address");
+-
+-/* See depca_probe() for autoprobe messages when a module */
+-int init_module(void)
++static int __init depca_module_init (void)
+ {
+-      thisDepca.irq = irq;
+-      thisDepca.base_addr = io;
+-      thisDepca.init = depca_probe;
++        int err = 0;
+-      if (register_netdev(&thisDepca) != 0)
+-              return -EIO;
+-
+-      return 0;
++#if CONFIG_MCA
++        err = mca_register_driver (&depca_mca_driver);
++#endif
++#ifdef CONFIG_EISA
++        err |= eisa_driver_register (&depca_eisa_driver);
++#endif
++      err |= driver_register (&depca_isa_driver);
++      depca_platform_probe ();
++      
++        return err;
+ }
+-void cleanup_module(void)
++static void __exit depca_module_exit (void)
+ {
+-      struct depca_private *lp = thisDepca.priv;
+-
+-      unregister_netdev(&thisDepca);
+-      if (lp) {
+-              iounmap(lp->sh_mem);
+-              release_mem_region (lp->mem_start, lp->mem_len);
+-#ifdef CONFIG_MCA
+-              if (lp->mca_slot != -1)
+-                      mca_mark_as_unused(lp->mca_slot);
++      int i;
++#if CONFIG_MCA
++        mca_unregister_driver (&depca_mca_driver);
+ #endif
+-              kfree(lp);
+-              thisDepca.priv = NULL;
+-      }
+-      thisDepca.irq = 0;
++#ifdef CONFIG_EISA
++        eisa_driver_unregister (&depca_eisa_driver);
++#endif
++      driver_unregister (&depca_isa_driver);
+-      release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE);
++      for (i = 0; depca_io_ports[i].iobase; i++) {
++              if (depca_io_ports[i].device) {
++                      platform_device_unregister (depca_io_ports[i].device);
++                      depca_io_ports[i].device = NULL;
++              }
++      }
+ }
+-#endif                                /* MODULE */
+-MODULE_LICENSE("GPL");
+-\f
+-/*
+- * Local variables:
+- *  compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c depca.c"
+- *
+- *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c depca.c"
+- * End:
+- */
++module_init (depca_module_init);
++module_exit (depca_module_exit);
+Index: linux-2.6.0-test5/drivers/net/dgrs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/dgrs.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/dgrs.c       2003-09-27 11:38:24.748766000 +0800
+@@ -84,6 +84,7 @@
+  */
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/delay.h>
+@@ -120,7 +121,7 @@
+ #include "dgrs_asstruct.h"
+ #include "dgrs_bcomm.h"
+-static struct pci_device_id dgrs_pci_tbl[] __initdata = {
++static struct pci_device_id dgrs_pci_tbl[] = {
+       { SE6_PCI_VENDOR_ID, SE6_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
+       { }                     /* Terminating entry */
+ };
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_ethtool.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_ethtool.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_ethtool.c        2003-09-27 11:38:24.783760680 +0800
+@@ -190,6 +190,55 @@
+       return 0;
+ }
++static int
++e1000_ethtool_gpause(struct e1000_adapter *adapter,
++                     struct ethtool_pauseparam *epause)
++{
++      struct e1000_hw *hw = &adapter->hw;
++      
++      epause->autoneg = 
++              (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
++      
++      if(hw->fc == e1000_fc_rx_pause)
++              epause->rx_pause = 1;
++      else if(hw->fc == e1000_fc_tx_pause)
++              epause->tx_pause = 1;
++      else if(hw->fc == e1000_fc_full) {
++              epause->rx_pause = 1;
++              epause->tx_pause = 1;
++      }
++      
++      return 0;
++}
++
++static int
++e1000_ethtool_spause(struct e1000_adapter *adapter,
++                     struct ethtool_pauseparam *epause)
++{
++      struct e1000_hw *hw = &adapter->hw;
++      
++      adapter->fc_autoneg = epause->autoneg;
++
++      if(epause->rx_pause && epause->tx_pause)
++              hw->fc = e1000_fc_full;
++      else if(epause->rx_pause && !epause->tx_pause)
++              hw->fc = e1000_fc_rx_pause;
++      else if(!epause->rx_pause && epause->tx_pause)
++              hw->fc = e1000_fc_tx_pause;
++      else if(!epause->rx_pause && !epause->tx_pause)
++              hw->fc = e1000_fc_none;
++
++      hw->original_fc = hw->fc;
++
++      if(netif_running(adapter->netdev)) {
++              e1000_down(adapter);
++              e1000_up(adapter);
++      } else
++              e1000_reset(adapter);
++      
++      return 0;
++}
++
+ static void
+ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
+                        struct ethtool_drvinfo *drvinfo)
+@@ -958,9 +1007,13 @@
+       case e1000_82544:
+       case e1000_82540:
+       case e1000_82545:
++      case e1000_82545_rev_3:
+       case e1000_82546:
++      case e1000_82546_rev_3:
+       case e1000_82541:
++      case e1000_82541_rev_2:
+       case e1000_82547:
++      case e1000_82547_rev_2:
+               return e1000_integrated_phy_loopback(adapter);
+               break;
+@@ -983,9 +1036,12 @@
+ {
+       uint32_t rctl;
+-      if(adapter->hw.media_type == e1000_media_type_fiber) {
++      if(adapter->hw.media_type == e1000_media_type_fiber ||
++         adapter->hw.media_type == e1000_media_type_internal_serdes) {
+               if(adapter->hw.mac_type == e1000_82545 ||
+-                 adapter->hw.mac_type == e1000_82546)
++                 adapter->hw.mac_type == e1000_82546 ||
++                 adapter->hw.mac_type == e1000_82545_rev_3 ||
++                 adapter->hw.mac_type == e1000_82546_rev_3)
+                       return e1000_set_phy_loopback(adapter);
+               else {
+                       rctl = E1000_READ_REG(&adapter->hw, RCTL);
+@@ -1010,9 +1066,12 @@
+       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+       if(adapter->hw.media_type == e1000_media_type_copper ||
+-         (adapter->hw.media_type == e1000_media_type_fiber &&
++         ((adapter->hw.media_type == e1000_media_type_fiber ||
++           adapter->hw.media_type == e1000_media_type_internal_serdes) &&
+           (adapter->hw.mac_type == e1000_82545 ||
+-           adapter->hw.mac_type == e1000_82546))) {
++           adapter->hw.mac_type == e1000_82546 ||
++           adapter->hw.mac_type == e1000_82545_rev_3 ||
++           adapter->hw.mac_type == e1000_82546_rev_3))) {
+               adapter->hw.autoneg = TRUE;
+               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
+               if(phy_reg & MII_CR_LOOPBACK) {
+@@ -1114,7 +1173,7 @@
+                       e1000_down(adapter);
+               else
+                       e1000_reset(adapter);
+-              
++
+               if(e1000_reg_test(adapter, &data[0]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+@@ -1162,6 +1221,7 @@
+               return;
+       case E1000_DEV_ID_82546EB_FIBER:
++      case E1000_DEV_ID_82546GB_FIBER:
+               /* Wake events only supported on port A for dual fiber */
+               if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
+                       wol->supported = 0;
+@@ -1200,6 +1260,7 @@
+               return wol->wolopts ? -EOPNOTSUPP : 0;
+       case E1000_DEV_ID_82546EB_FIBER:
++      case E1000_DEV_ID_82546GB_FIBER:
+               /* Wake events only supported on port A for dual fiber */
+               if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+                       return wol->wolopts ? -EOPNOTSUPP : 0;
+@@ -1437,6 +1498,19 @@
+               addr += offsetof(struct ethtool_eeprom, data);
+               return e1000_ethtool_seeprom(adapter, &eeprom, addr);
+       }
++      case ETHTOOL_GPAUSEPARAM: {
++              struct ethtool_pauseparam epause = {ETHTOOL_GPAUSEPARAM};
++              e1000_ethtool_gpause(adapter, &epause);
++              if(copy_to_user(addr, &epause, sizeof(epause)))
++                      return -EFAULT;
++              return 0;
++      }
++      case ETHTOOL_SPAUSEPARAM: {
++              struct ethtool_pauseparam epause;
++              if(copy_from_user(&epause, addr, sizeof(epause)))
++                      return -EFAULT;
++              return e1000_ethtool_spause(adapter, &epause);
++      }
+       case ETHTOOL_GSTATS: {
+               struct {
+                       struct ethtool_stats eth_stats;
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000.h   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000.h        2003-09-27 11:38:24.870747456 +0800
+@@ -122,7 +122,12 @@
+ #define E1000_RX_BUFFER_WRITE 16      /* Must be power of 2 */
+ #define AUTO_ALL_MODES       0
+-#define E1000_EEPROM_APME    4
++#define E1000_EEPROM_APME    0x0400
++
++#ifndef E1000_MASTER_SLAVE
++/* Switch to override PHY master/slave setting */
++#define E1000_MASTER_SLAVE    e1000_ms_hw_default
++#endif
+ /* only works for sizes that are powers of 2 */
+ #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
+@@ -180,6 +185,7 @@
+       spinlock_t stats_lock;
+       atomic_t irq_sem;
+       struct work_struct tx_timeout_task;
++      uint8_t fc_autoneg;
+       struct timer_list blink_timer;
+       unsigned long led_status;
+@@ -194,6 +200,7 @@
+       uint32_t tx_head_addr;
+       uint32_t tx_fifo_size;
+       atomic_t tx_fifo_stall;
++      boolean_t pcix_82544;
+       /* RX */
+       struct e1000_desc_ring rx_ring;
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_hw.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_hw.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_hw.c     2003-09-27 11:38:25.047720552 +0800
+@@ -34,14 +34,15 @@
+ static int32_t e1000_set_phy_type(struct e1000_hw *hw);
+ static void e1000_phy_init_script(struct e1000_hw *hw);
+-static int32_t e1000_setup_fiber_link(struct e1000_hw *hw);
+ static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
++static int32_t e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
++static int32_t e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
+ static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw);
+ static int32_t e1000_config_mac_to_phy(struct e1000_hw *hw);
+-static int32_t e1000_force_mac_fc(struct e1000_hw *hw);
+ static void e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
+ static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
+-static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count);
++static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data,
++                                     uint16_t count);
+ static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw);
+ static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw);
+ static int32_t e1000_write_eeprom_spi(struct e1000_hw *hw, uint16_t offset,
+@@ -52,13 +53,30 @@
+ static int32_t e1000_spi_eeprom_ready(struct e1000_hw *hw);
+ static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
+ static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
+-static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count);
++static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data,
++                                    uint16_t count);
++static int32_t e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
++                                      uint16_t phy_data);
++static int32_t e1000_read_phy_reg_ex(struct e1000_hw *hw,uint32_t reg_addr,
++                                     uint16_t *phy_data);
+ static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
+ static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
+ static void e1000_release_eeprom(struct e1000_hw *hw);
+ static void e1000_standby_eeprom(struct e1000_hw *hw);
+ static int32_t e1000_id_led_init(struct e1000_hw * hw);
++static int32_t e1000_set_vco_speed(struct e1000_hw *hw);
++/* IGP cable length table */
++static const
++uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
++    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
++      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
++      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
++      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
++      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
++      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
++      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
++      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
+ /******************************************************************************
+@@ -100,50 +118,41 @@
+     DEBUGFUNC("e1000_phy_init_script");
+     if(hw->phy_init_script) {
+-        msec_delay(10);
++        msec_delay(20);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
+         e1000_write_phy_reg(hw,0x0000,0x0140);
+         msec_delay(5);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95);
+-        e1000_write_phy_reg(hw,0x0015,0x0001);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71);
+-        e1000_write_phy_reg(hw,0x0011,0xBD21);
++        if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
++            e1000_write_phy_reg(hw, 0x1F95, 0x0001);
++
++            e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79);
+-        e1000_write_phy_reg(hw,0x0019,0x0018);
++            e1000_write_phy_reg(hw, 0x1F79, 0x0018);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30);
+-        e1000_write_phy_reg(hw,0x0010,0x1600);
++            e1000_write_phy_reg(hw, 0x1F30, 0x1600);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31);
+-        e1000_write_phy_reg(hw,0x0011,0x0014);
++            e1000_write_phy_reg(hw, 0x1F31, 0x0014);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32);
+-        e1000_write_phy_reg(hw,0x0012,0x161C);
++            e1000_write_phy_reg(hw, 0x1F32, 0x161C);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94);
+-        e1000_write_phy_reg(hw,0x0014,0x0003);
++            e1000_write_phy_reg(hw, 0x1F94, 0x0003);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96);
+-        e1000_write_phy_reg(hw,0x0016,0x003F);
++            e1000_write_phy_reg(hw, 0x1F96, 0x003F);
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010);
+-        e1000_write_phy_reg(hw,0x0010,0x0008);
++            e1000_write_phy_reg(hw, 0x2010, 0x0008);
++        } else {
++            e1000_write_phy_reg(hw, 0x1F73, 0x0099);
++        }
+-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
+-        e1000_write_phy_reg(hw,0x0000,0x3300);
++        e1000_write_phy_reg(hw, 0x0000, 0x3300);
+         if(hw->mac_type == e1000_82547) {
+             uint16_t fused, fine, coarse;
+             /* Move to analog registers page */
+-            e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 
+-                                IGP01E1000_ANALOG_REGS_PAGE);
+-
+             e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
+             if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
+@@ -158,17 +167,14 @@
+                 } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
+                     fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
+-                fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) | 
+-                        (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) | 
++                fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
++                        (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
+                         (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
+                 e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
+-                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS, 
++                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
+                                     IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
+             }
+-            /* Return to first page of registers */
+-            e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+-                                IGP01E1000_IEEE_REGS_PAGE);
+         }
+     }
+ }
+@@ -218,32 +224,89 @@
+     case E1000_DEV_ID_82545EM_FIBER:
+         hw->mac_type = e1000_82545;
+         break;
++    case E1000_DEV_ID_82545GM_COPPER:
++    case E1000_DEV_ID_82545GM_FIBER:
++    case E1000_DEV_ID_82545GM_SERDES:
++        hw->mac_type = e1000_82545_rev_3;
++        break;
+     case E1000_DEV_ID_82546EB_COPPER:
+     case E1000_DEV_ID_82546EB_FIBER:
+     case E1000_DEV_ID_82546EB_QUAD_COPPER:
+         hw->mac_type = e1000_82546;
+         break;
++    case E1000_DEV_ID_82546GB_COPPER:
++    case E1000_DEV_ID_82546GB_FIBER:
++    case E1000_DEV_ID_82546GB_SERDES:
++        hw->mac_type = e1000_82546_rev_3;
++        break;
+     case E1000_DEV_ID_82541EI:
+-    case E1000_DEV_ID_82541EP:
++    case E1000_DEV_ID_82541EI_MOBILE:
+         hw->mac_type = e1000_82541;
+         break;
++    case E1000_DEV_ID_82541ER:
++    case E1000_DEV_ID_82541GI:
++    case E1000_DEV_ID_82541GI_MOBILE:
++        hw->mac_type = e1000_82541_rev_2;
++        break;
+     case E1000_DEV_ID_82547EI:
+         hw->mac_type = e1000_82547;
+         break;
++    case E1000_DEV_ID_82547GI:
++        hw->mac_type = e1000_82547_rev_2;
++        break;
+     default:
+         /* Should never have loaded on this device */
+         return -E1000_ERR_MAC_TYPE;
+     }
+-
+     return E1000_SUCCESS;
+ }
++
++/*****************************************************************************
++ * Set media type and TBI compatibility.
++ *
++ * hw - Struct containing variables accessed by shared code
++ * **************************************************************************/
++void
++e1000_set_media_type(struct e1000_hw *hw)
++{
++    uint32_t status;
++
++    DEBUGFUNC("e1000_set_media_type");
++
++    if(hw->mac_type != e1000_82543) {
++        /* tbi_compatibility is only valid on 82543 */
++        hw->tbi_compatibility_en = FALSE;
++    }
++
++    switch (hw->device_id) {
++    case E1000_DEV_ID_82545GM_SERDES:
++    case E1000_DEV_ID_82546GB_SERDES:
++        hw->media_type = e1000_media_type_internal_serdes;
++        break;
++    default:
++        if(hw->mac_type >= e1000_82543) {
++            status = E1000_READ_REG(hw, STATUS);
++            if(status & E1000_STATUS_TBIMODE) {
++                hw->media_type = e1000_media_type_fiber;
++                /* tbi_compatibility not valid on fiber */
++                hw->tbi_compatibility_en = FALSE;
++            } else {
++                hw->media_type = e1000_media_type_copper;
++            }
++        } else {
++            /* This is an 82542 (fiber only) */
++            hw->media_type = e1000_media_type_fiber;
++        }
++    }
++}
++
+ /******************************************************************************
+  * Reset the transmit and receive units; mask and clear all interrupts.
+  *
+  * hw - Struct containing variables accessed by shared code
+  *****************************************************************************/
+-void
++int32_t
+ e1000_reset_hw(struct e1000_hw *hw)
+ {
+     uint32_t ctrl;
+@@ -280,49 +343,75 @@
+      */
+     msec_delay(10);
+-    /* Issue a global reset to the MAC.  This will reset the chip's
+-     * transmit, receive, DMA, and link units.  It will not effect
+-     * the current PCI configuration.  The global reset bit is self-
+-     * clearing, and should clear within a microsecond.
+-     */
+-    DEBUGOUT("Issuing a global reset to MAC\n");
+     ctrl = E1000_READ_REG(hw, CTRL);
+     /* Must reset the PHY before resetting the MAC */
+     if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+         E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+-      msec_delay(5);
++        msec_delay(5);
+     }
++    /* Issue a global reset to the MAC.  This will reset the chip's
++     * transmit, receive, DMA, and link units.  It will not effect
++     * the current PCI configuration.  The global reset bit is self-
++     * clearing, and should clear within a microsecond.
++     */
++    DEBUGOUT("Issuing a global reset to MAC\n");
++
+     switch(hw->mac_type) {
+         case e1000_82544:
+         case e1000_82540:
+         case e1000_82545:
+         case e1000_82546:
+         case e1000_82541:
++        case e1000_82541_rev_2:
+             /* These controllers can't ack the 64-bit write when issuing the
+              * reset, so use IO-mapping as a workaround to issue the reset */
+             E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
+             break;
++        case e1000_82545_rev_3:
++        case e1000_82546_rev_3:
++            /* Reset is performed on a shadow of the control register */
++            E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
++            break;
+         default:
+             E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+             break;
+     }
+-    /* Force a reload from the EEPROM if necessary */
+-    if(hw->mac_type < e1000_82540) {
+-        /* Wait for reset to complete */
+-        udelay(10);
+-        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+-        ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+-        E1000_WRITE_FLUSH(hw);
+-        /* Wait for EEPROM reload */
+-        msec_delay(2);
+-    } else {
+-        /* Wait for EEPROM reload (it happens automatically) */
+-        msec_delay(5);
+-        /* Dissable HW ARPs on ASF enabled adapters */
++    /* After MAC reset, force reload of EEPROM to restore power-on settings to
++     * device.  Later controllers reload the EEPROM automatically, so just wait
++     * for reload to complete.
++     */
++    switch(hw->mac_type) {
++        case e1000_82542_rev2_0:
++        case e1000_82542_rev2_1:
++        case e1000_82543:
++        case e1000_82544:
++            /* Wait for reset to complete */
++            udelay(10);
++            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
++            ctrl_ext |= E1000_CTRL_EXT_EE_RST;
++            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
++            E1000_WRITE_FLUSH(hw);
++            /* Wait for EEPROM reload */
++            msec_delay(2);
++            break;
++        case e1000_82541:
++        case e1000_82541_rev_2:
++        case e1000_82547:
++        case e1000_82547_rev_2:
++            /* Wait for EEPROM reload */
++            msec_delay(20);
++            break;
++        default:
++            /* Wait for EEPROM reload (it happens automatically) */
++            msec_delay(5);
++            break;
++    }
++
++    /* Disable HW ARPs on ASF enabled adapters */
++    if(hw->mac_type >= e1000_82540) {
+         manc = E1000_READ_REG(hw, MANC);
+         manc &= ~(E1000_MANC_ARP_EN);
+         E1000_WRITE_REG(hw, MANC, manc);
+@@ -350,6 +439,8 @@
+         if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+             e1000_pci_set_mwi(hw);
+     }
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -366,7 +457,7 @@
+ int32_t
+ e1000_init_hw(struct e1000_hw *hw)
+ {
+-    uint32_t ctrl, status;
++    uint32_t ctrl;
+     uint32_t i;
+     int32_t ret_val;
+     uint16_t pcix_cmd_word;
+@@ -377,31 +468,13 @@
+     DEBUGFUNC("e1000_init_hw");
+     /* Initialize Identification LED */
+-    ret_val = e1000_id_led_init(hw);
+-    if(ret_val < 0) {
++    if((ret_val = e1000_id_led_init(hw))) {
+         DEBUGOUT("Error Initializing Identification LED\n");
+         return ret_val;
+     }
+-    /* Set the Media Type and exit with error if it is not valid. */
+-    if(hw->mac_type != e1000_82543) {
+-        /* tbi_compatibility is only valid on 82543 */
+-        hw->tbi_compatibility_en = FALSE;
+-    }
+-
+-    if(hw->mac_type >= e1000_82543) {
+-        status = E1000_READ_REG(hw, STATUS);
+-        if(status & E1000_STATUS_TBIMODE) {
+-            hw->media_type = e1000_media_type_fiber;
+-            /* tbi_compatibility not valid on fiber */
+-            hw->tbi_compatibility_en = FALSE;
+-        } else {
+-            hw->media_type = e1000_media_type_copper;
+-        }
+-    } else {
+-        /* This is an 82542 (fiber only) */
+-        hw->media_type = e1000_media_type_fiber;
+-    }
++    /* Set the media type and TBI compatibility */
++    e1000_set_media_type(hw);
+     /* Disabling VLAN filtering. */
+     DEBUGOUT("Initializing the IEEE VLAN\n");
+@@ -446,21 +519,30 @@
+         E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
+     }
+-    /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
+-    if(hw->bus_type == e1000_bus_type_pcix) {
+-        e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
+-        e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
+-        cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
+-            PCIX_COMMAND_MMRBC_SHIFT;
+-        stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
+-            PCIX_STATUS_HI_MMRBC_SHIFT;
+-        if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
+-            stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
+-        if(cmd_mmrbc > stat_mmrbc) {
+-            pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
+-            pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
+-            e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
++    switch(hw->mac_type) {
++    case e1000_82545_rev_3:
++    case e1000_82546_rev_3:
++        break;
++    default:
++        /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
++        if(hw->bus_type == e1000_bus_type_pcix) {
++            e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
++            e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI,
++                &pcix_stat_hi_word);
++            cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
++                PCIX_COMMAND_MMRBC_SHIFT;
++            stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
++                PCIX_STATUS_HI_MMRBC_SHIFT;
++            if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
++                stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
++            if(cmd_mmrbc > stat_mmrbc) {
++                pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
++                pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
++                e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER,
++                    &pcix_cmd_word);
++            }
+         }
++        break;
+     }
+     /* Call a subroutine to configure the link and setup flow control. */
+@@ -484,6 +566,46 @@
+ }
+ /******************************************************************************
++ * Adjust SERDES output amplitude based on EEPROM setting.
++ *
++ * hw - Struct containing variables accessed by shared code.
++ *****************************************************************************/
++static int32_t
++e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
++{
++    uint16_t eeprom_data;
++    int32_t  ret_val;
++
++    DEBUGFUNC("e1000_adjust_serdes_amplitude");
++
++    if(hw->media_type != e1000_media_type_internal_serdes)
++        return E1000_SUCCESS;
++
++    switch(hw->mac_type) {
++    case e1000_82545_rev_3:
++    case e1000_82546_rev_3:
++        break;
++    default:
++        return E1000_SUCCESS;
++    }
++
++    if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
++                                     &eeprom_data))) {
++        return ret_val;
++    }
++
++    if(eeprom_data != EEPROM_RESERVED_WORD) {
++        /* Adjust SERDES output amplitude only. */
++        eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK; 
++        if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
++                                          eeprom_data)))
++            return ret_val;
++    }
++
++    return E1000_SUCCESS;
++}
++
++/******************************************************************************
+  * Configures flow control and link settings.
+  *
+  * hw - Struct containing variables accessed by shared code
+@@ -554,9 +676,9 @@
+     }
+     /* Call the necessary subroutine to configure the link. */
+-    ret_val = (hw->media_type == e1000_media_type_fiber) ?
+-              e1000_setup_fiber_link(hw) :
+-              e1000_setup_copper_link(hw);
++    ret_val = (hw->media_type == e1000_media_type_copper) ?
++              e1000_setup_copper_link(hw) :
++              e1000_setup_fiber_serdes_link(hw);
+     /* Initialize the flow control address, type, and PAUSE timer
+      * registers to their default values.  This is done even if flow
+@@ -595,7 +717,7 @@
+ }
+ /******************************************************************************
+- * Sets up link for a fiber based adapter
++ * Sets up link for a fiber based or serdes based adapter
+  *
+  * hw - Struct containing variables accessed by shared code
+  *
+@@ -604,28 +726,37 @@
+  * and receiver are not enabled.
+  *****************************************************************************/
+ static int32_t
+-e1000_setup_fiber_link(struct e1000_hw *hw)
++e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
+ {
+     uint32_t ctrl;
+     uint32_t status;
+     uint32_t txcw = 0;
+     uint32_t i;
+-    uint32_t signal;
++    uint32_t signal = 0;
+     int32_t ret_val;
+-    DEBUGFUNC("e1000_setup_fiber_link");
++    DEBUGFUNC("e1000_setup_fiber_serdes_link");
+-    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
++    /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+      * set when the optics detect a signal. On older adapters, it will be
+-     * cleared when there is a signal
++     * cleared when there is a signal.  This applies to fiber media only.
++     * If we're on serdes media, adjust the output amplitude to value set in
++     * the EEPROM.
+      */
+     ctrl = E1000_READ_REG(hw, CTRL);
+-    if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
+-    else signal = 0;
++    if(hw->media_type == e1000_media_type_fiber)
++        signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
++
++    if((ret_val = e1000_adjust_serdes_amplitude(hw)))
++        return ret_val;
+     /* Take the link out of reset */
+     ctrl &= ~(E1000_CTRL_LRST);
++    /* Adjust VCO speed to improve BER performance */
++    if((ret_val = e1000_set_vco_speed(hw)))
++        return ret_val;
++
+     e1000_config_collision_dist(hw);
+     /* Check for a software override of the flow control settings, and setup
+@@ -692,8 +823,10 @@
+      * indication in the Device Status Register.  Time-out if a link isn't
+      * seen in 500 milliseconds seconds (Auto-negotiation should complete in
+      * less than 500 milliseconds even if the other end is doing it in SW).
++     * For internal serdes, we just assume a signal is present, then poll.
+      */
+-    if((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
++    if(hw->media_type == e1000_media_type_internal_serdes ||
++       (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
+         DEBUGOUT("Looking for Link\n");
+         for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
+             msec_delay(10);
+@@ -701,19 +834,20 @@
+             if(status & E1000_STATUS_LU) break;
+         }
+         if(i == (LINK_UP_TIMEOUT / 10)) {
+-            /* AutoNeg failed to achieve a link, so we'll call
+-             * e1000_check_for_link. This routine will force the link up if we
+-             * detect a signal. This will allow us to communicate with
+-             * non-autonegotiating link partners.
+-             */
+             DEBUGOUT("Never got a valid link from auto-neg!!!\n");
+             hw->autoneg_failed = 1;
+-            ret_val = e1000_check_for_link(hw);
+-            if(ret_val < 0) {
+-                DEBUGOUT("Error while checking for link\n");
+-                return ret_val;
++            if(hw->media_type == e1000_media_type_fiber) {
++                /* AutoNeg failed to achieve a link, so we'll call
++                 * e1000_check_for_link. This routine will force the link up if
++                 * we detect a signal. This will allow us to communicate with
++                 * non-autonegotiating link partners.
++                 */
++                if((ret_val = e1000_check_for_link(hw))) {
++                    DEBUGOUT("Error while checking for link\n");
++                    return ret_val;
++                }
++                hw->autoneg_failed = 0;
+             }
+-            hw->autoneg_failed = 0;
+         } else {
+             hw->autoneg_failed = 0;
+             DEBUGOUT("Valid Link Found\n");
+@@ -721,7 +855,7 @@
+     } else {
+         DEBUGOUT("No Signal Detected\n");
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -756,233 +890,281 @@
+     }
+     /* Make sure we have a valid PHY */
+-    ret_val = e1000_detect_gig_phy(hw);
+-    if(ret_val < 0) {
++    if((ret_val = e1000_detect_gig_phy(hw))) {
+         DEBUGOUT("Error, did not detect valid phy.\n");
+         return ret_val;
+     }
+     DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
+-    if (hw->phy_type == e1000_phy_igp) {
+-
+-        ret_val = e1000_phy_reset(hw);
+-        if(ret_val < 0) {
+-            DEBUGOUT("Error Resetting the PHY\n");
+-            return ret_val;
+-        }
++    if(hw->mac_type <= e1000_82543 ||
++       hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
++       hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
++        hw->phy_reset_disable = FALSE;
+-        /* Wait 10ms for MAC to configure PHY from eeprom settings */
+-        msec_delay(15);
++    if(!hw->phy_reset_disable) {
++        if (hw->phy_type == e1000_phy_igp) {
+-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++            if((ret_val = e1000_phy_reset(hw))) {
++                DEBUGOUT("Error Resetting the PHY\n");
++                return ret_val;
++            }
+-        /* Configure activity LED after PHY reset */
+-        led_ctrl = E1000_READ_REG(hw, LEDCTL);
+-        led_ctrl &= IGP_ACTIVITY_LED_MASK;
+-        led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
+-        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
++            /* Wait 10ms for MAC to configure PHY from eeprom settings */
++            msec_delay(15);
+-        if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+-            /* Disable SmartSpeed */
+-            if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+-                                  &phy_data) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
+-            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+-                                   phy_data) < 0) {
+-                DEBUGOUT("PHY Write Error\n");
+-                return -E1000_ERR_PHY;
+-            }
+-            /* Set auto Master/Slave resolution process */
+-            if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
++            /* Configure activity LED after PHY reset */
++            led_ctrl = E1000_READ_REG(hw, LEDCTL);
++            led_ctrl &= IGP_ACTIVITY_LED_MASK;
++            led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
++            E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
++
++            /* disable lplu d3 during driver init */
++            if((ret_val = e1000_set_d3_lplu_state(hw, FALSE))) {
++                DEBUGOUT("Error Disabling LPLU D3\n");
++                return ret_val;
+             }
+-            phy_data &= ~CR_1000T_MS_ENABLE;
+-            if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data) < 0) {
+-                DEBUGOUT("PHY Write Error\n");
+-                return -E1000_ERR_PHY;
++
++            /* Configure mdi-mdix settings */
++            if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++                                             &phy_data)))
++                return ret_val;
++
++            if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
++                hw->dsp_config_state = e1000_dsp_config_disabled;
++                /* Force MDI for IGP B-0 PHY */
++                phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
++                              IGP01E1000_PSCR_FORCE_MDI_MDIX);
++                hw->mdix = 1;
++
++            } else {
++                hw->dsp_config_state = e1000_dsp_config_enabled;
++                phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
++
++                switch (hw->mdix) {
++                case 1:
++                    phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
++                    break;
++                case 2:
++                    phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
++                    break;
++                case 0:
++                default:
++                    phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
++                    break;
++                }
+             }
+-        }
++            if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++                                              phy_data)))
++                return ret_val;
+-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++            /* set auto-master slave resolution settings */
++            if(hw->autoneg) {
++                e1000_ms_type phy_ms_setting = hw->master_slave;
++
++                if(hw->ffe_config_state == e1000_ffe_config_active)
++                    hw->ffe_config_state = e1000_ffe_config_enabled;
++
++                if(hw->dsp_config_state == e1000_dsp_config_activated)
++                    hw->dsp_config_state = e1000_dsp_config_enabled;
++
++                /* when autonegotiation advertisment is only 1000Mbps then we
++                 * should disable SmartSpeed and enable Auto MasterSlave
++                 * resolution as hardware default. */
++                if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
++                    /* Disable SmartSpeed */
++                    if((ret_val = e1000_read_phy_reg(hw,
++                                                    IGP01E1000_PHY_PORT_CONFIG,
++                                                    &phy_data)))
++                        return ret_val;
++                    phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
++                    if((ret_val = e1000_write_phy_reg(hw,
++                                                     IGP01E1000_PHY_PORT_CONFIG,
++                                                     phy_data)))
++                        return ret_val;
++                    /* Set auto Master/Slave resolution process */
++                    if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
++                                                     &phy_data)))
++                        return ret_val;
++                    phy_data &= ~CR_1000T_MS_ENABLE;
++                    if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
++                                                      phy_data)))
++                        return ret_val;
++                }
+-        /* Force MDI for IGP PHY */
+-        phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
+-                      IGP01E1000_PSCR_FORCE_MDI_MDIX);
++                if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
++                                                 &phy_data)))
++                    return ret_val;
+-        hw->mdix = 1;
++                /* load defaults for future use */
++                hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
++                                            ((phy_data & CR_1000T_MS_VALUE) ?
++                                             e1000_ms_force_master :
++                                             e1000_ms_force_slave) :
++                                             e1000_ms_auto;
++
++                switch (phy_ms_setting) {
++                case e1000_ms_force_master:
++                    phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
++                    break;
++                case e1000_ms_force_slave:
++                    phy_data |= CR_1000T_MS_ENABLE;
++                    phy_data &= ~(CR_1000T_MS_VALUE);
++                    break;
++                case e1000_ms_auto:
++                    phy_data &= ~CR_1000T_MS_ENABLE;
++                default:
++                    break;
++                }
++                if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
++                                                  phy_data)))
++                    return ret_val;
++            }
++        } else {
++            /* Enable CRS on TX. This must be set for half-duplex operation. */
++            if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++                                             &phy_data)))
++                return ret_val;
+-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++            phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+-    } else {
+-        /* Enable CRS on TX. This must be set for half-duplex operation. */
+-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
+-        phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
++            /* Options:
++             *   MDI/MDI-X = 0 (default)
++             *   0 - Auto for all speeds
++             *   1 - MDI mode
++             *   2 - MDI-X mode
++             *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
++             */
++            phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+-        /* Options:
+-         *   MDI/MDI-X = 0 (default)
+-         *   0 - Auto for all speeds
+-         *   1 - MDI mode
+-         *   2 - MDI-X mode
+-         *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+-         */
+-        phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
++            switch (hw->mdix) {
++            case 1:
++                phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
++                break;
++            case 2:
++                phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
++                break;
++            case 3:
++                phy_data |= M88E1000_PSCR_AUTO_X_1000T;
++                break;
++            case 0:
++            default:
++                phy_data |= M88E1000_PSCR_AUTO_X_MODE;
++                break;
++            }
+-        switch (hw->mdix) {
+-        case 1:
+-            phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+-            break;
+-        case 2:
+-            phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+-            break;
+-        case 3:
+-            phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+-            break;
+-        case 0:
+-        default:
+-            phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+-            break;
+-        }
++            /* Options:
++             *   disable_polarity_correction = 0 (default)
++             *       Automatic Correction for Reversed Cable Polarity
++             *   0 - Disabled
++             *   1 - Enabled
++             */
++            phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
++            if(hw->disable_polarity_correction == 1)
++                phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
++            if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++                                              phy_data)))
++                return ret_val;
+-        /* Options:
+-         *   disable_polarity_correction = 0 (default)
+-         *       Automatic Correction for Reversed Cable Polarity
+-         *   0 - Disabled
+-         *   1 - Enabled
+-         */
+-        phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+-        if(hw->disable_polarity_correction == 1)
+-            phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+-        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++            /* Force TX_CLK in the Extended PHY Specific Control Register
++             * to 25MHz clock.
++             */
++            if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++                                             &phy_data)))
++                return ret_val;
+-        /* Force TX_CLK in the Extended PHY Specific Control Register
+-         * to 25MHz clock.
+-         */
+-        if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
+-        phy_data |= M88E1000_EPSCR_TX_CLK_25;
++            phy_data |= M88E1000_EPSCR_TX_CLK_25;
+-        if (hw->phy_revision < M88E1011_I_REV_4) {
+-            /* Configure Master and Slave downshift values */
+-            phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+-                          M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+-            phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+-                         M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+-            if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+-                                   phy_data) < 0) {
+-                DEBUGOUT("PHY Write Error\n");
+-                return -E1000_ERR_PHY;
++            if (hw->phy_revision < M88E1011_I_REV_4) {
++                /* Configure Master and Slave downshift values */
++                phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
++                              M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
++                phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
++                             M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
++                if((ret_val = e1000_write_phy_reg(hw,
++                                                  M88E1000_EXT_PHY_SPEC_CTRL,
++                                                  phy_data)))
++                    return ret_val;
+             }
+-        }
+-        /* SW Reset the PHY so all changes take effect */
+-        ret_val = e1000_phy_reset(hw);
+-        if(ret_val < 0) {
+-            DEBUGOUT("Error Resetting the PHY\n");
+-            return ret_val;
++            /* SW Reset the PHY so all changes take effect */
++            if((ret_val = e1000_phy_reset(hw))) {
++                DEBUGOUT("Error Resetting the PHY\n");
++                return ret_val;
++            }
+         }
+-    }
+-    /* Options:
+-     *   autoneg = 1 (default)
+-     *      PHY will advertise value(s) parsed from
+-     *      autoneg_advertised and fc
+-     *   autoneg = 0
+-     *      PHY will be set to 10H, 10F, 100H, or 100F
+-     *      depending on value parsed from forced_speed_duplex.
+-     */
++        /* Options:
++         *   autoneg = 1 (default)
++         *      PHY will advertise value(s) parsed from
++         *      autoneg_advertised and fc
++         *   autoneg = 0
++         *      PHY will be set to 10H, 10F, 100H, or 100F
++         *      depending on value parsed from forced_speed_duplex.
++         */
++
++        /* Is autoneg enabled?  This is enabled by default or by software
++         * override.  If so, call e1000_phy_setup_autoneg routine to parse the
++         * autoneg_advertised and fc options. If autoneg is NOT enabled, then
++         * the user should have provided a speed/duplex override.  If so, then
++         * call e1000_phy_force_speed_duplex to parse and set this up.
++         */
++        if(hw->autoneg) {
++            /* Perform some bounds checking on the hw->autoneg_advertised
++             * parameter.  If this variable is zero, then set it to the default.
++             */
++            hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+-    /* Is autoneg enabled?  This is enabled by default or by software override.
+-     * If so, call e1000_phy_setup_autoneg routine to parse the
+-     * autoneg_advertised and fc options. If autoneg is NOT enabled, then the
+-     * user should have provided a speed/duplex override.  If so, then call
+-     * e1000_phy_force_speed_duplex to parse and set this up.
+-     */
+-    if(hw->autoneg) {
+-        /* Perform some bounds checking on the hw->autoneg_advertised
+-         * parameter.  If this variable is zero, then set it to the default.
+-         */
+-        hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
++            /* If autoneg_advertised is zero, we assume it was not defaulted
++             * by the calling code so we set to advertise full capability.
++             */
++            if(hw->autoneg_advertised == 0)
++                hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+-        /* If autoneg_advertised is zero, we assume it was not defaulted
+-         * by the calling code so we set to advertise full capability.
+-         */
+-        if(hw->autoneg_advertised == 0)
+-            hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
++            DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
++            if((ret_val = e1000_phy_setup_autoneg(hw))) {
++                DEBUGOUT("Error Setting up Auto-Negotiation\n");
++                return ret_val;
++            }
++            DEBUGOUT("Restarting Auto-Neg\n");
+-        DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+-        ret_val = e1000_phy_setup_autoneg(hw);
+-        if(ret_val < 0) {
+-            DEBUGOUT("Error Setting up Auto-Negotiation\n");
+-            return ret_val;
+-        }
+-        DEBUGOUT("Restarting Auto-Neg\n");
++            /* Restart auto-negotiation by setting the Auto Neg Enable bit and
++             * the Auto Neg Restart bit in the PHY control register.
++             */
++            if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
++                return ret_val;
+-        /* Restart auto-negotiation by setting the Auto Neg Enable bit and
+-         * the Auto Neg Restart bit in the PHY control register.
+-         */
+-        if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
+-        phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+-        if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++            phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
++            if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
++                return ret_val;
+-        /* Does the user want to wait for Auto-Neg to complete here, or
+-         * check at a later time (for example, callback routine).
+-         */
+-        if(hw->wait_autoneg_complete) {
+-            ret_val = e1000_wait_autoneg(hw);
+-            if(ret_val < 0) {
+-                DEBUGOUT("Error while waiting for autoneg to complete\n");
++            /* Does the user want to wait for Auto-Neg to complete here, or
++             * check at a later time (for example, callback routine).
++             */
++            if(hw->wait_autoneg_complete) {
++                if((ret_val = e1000_wait_autoneg(hw))) {
++                    DEBUGOUT("Error while waiting for autoneg to complete\n");
++                    return ret_val;
++                }
++            }
++            hw->get_link_status = TRUE;
++        } else {
++            DEBUGOUT("Forcing speed and duplex\n");
++            if((ret_val = e1000_phy_force_speed_duplex(hw))) {
++                DEBUGOUT("Error Forcing Speed and Duplex\n");
+                 return ret_val;
+             }
+         }
+-        hw->get_link_status = TRUE;
+-    } else {
+-        DEBUGOUT("Forcing speed and duplex\n");
+-        ret_val = e1000_phy_force_speed_duplex(hw);
+-        if(ret_val < 0) {
+-            DEBUGOUT("Error Forcing Speed and Duplex\n");
+-            return ret_val;
+-        }
+-    }
++    } /* !hw->phy_reset_disable */
+     /* Check link status. Wait up to 100 microseconds for link to become
+      * valid.
+      */
+     for(i = 0; i < 10; i++) {
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++            return ret_val;
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++            return ret_val;
++
+         if(phy_data & MII_SR_LINK_STATUS) {
+             /* We have link, so we need to finish the config process:
+              *   1) Set up the MAC to the current PHY speed/duplex
+@@ -995,25 +1177,31 @@
+             if(hw->mac_type >= e1000_82544) {
+                 e1000_config_collision_dist(hw);
+             } else {
+-                ret_val = e1000_config_mac_to_phy(hw);
+-                if(ret_val < 0) {
++                if((ret_val = e1000_config_mac_to_phy(hw))) {
+                     DEBUGOUT("Error configuring MAC to PHY settings\n");
+                     return ret_val;
+-                  }
++                }
+             }
+-            ret_val = e1000_config_fc_after_link_up(hw);
+-            if(ret_val < 0) {
++            if((ret_val = e1000_config_fc_after_link_up(hw))) {
+                 DEBUGOUT("Error Configuring Flow Control\n");
+                 return ret_val;
+             }
+             DEBUGOUT("Valid link established!!!\n");
+-            return 0;
++
++            if(hw->phy_type == e1000_phy_igp) {
++                if((ret_val = e1000_config_dsp_after_link_change(hw, TRUE))) {
++                    DEBUGOUT("Error Configuring DSP after link up\n");
++                    return ret_val;
++                }
++            }
++            DEBUGOUT("Valid link established!!!\n");
++            return E1000_SUCCESS;
+         }
+         udelay(10);
+     }
+     DEBUGOUT("Unable to establish link!!!\n");
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1024,22 +1212,20 @@
+ int32_t
+ e1000_phy_setup_autoneg(struct e1000_hw *hw)
+ {
++    int32_t ret_val;
+     uint16_t mii_autoneg_adv_reg;
+     uint16_t mii_1000t_ctrl_reg;
+     DEBUGFUNC("e1000_phy_setup_autoneg");
+     /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+-    if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
++    if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
++                                     &mii_autoneg_adv_reg)))
++        return ret_val;
+     /* Read the MII 1000Base-T Control Register (Address 9). */
+-    if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
++    if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg)))
++        return ret_val;
+     /* Need to parse both autoneg_advertised and fc and set up
+      * the appropriate PHY registers.  First we will parse for
+@@ -1145,18 +1331,16 @@
+         return -E1000_ERR_CONFIG;
+     }
+-    if(e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) {
+-        DEBUGOUT("PHY Write Error\n");
+-        return -E1000_ERR_PHY;
+-    }
++    if((ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV,
++                                      mii_autoneg_adv_reg)))
++        return ret_val;
+     DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+-    if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) {
+-        DEBUGOUT("PHY Write Error\n");
+-        return -E1000_ERR_PHY;
+-    }
+-    return 0;
++    if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg)))
++        return ret_val;
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1192,10 +1376,8 @@
+     ctrl &= ~E1000_CTRL_ASDE;
+     /* Read the MII Control Register. */
+-    if(e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
++    if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg)))
++        return ret_val;
+     /* We need to disable autoneg in order to force link and duplex. */
+@@ -1241,19 +1423,18 @@
+     E1000_WRITE_REG(hw, CTRL, ctrl);
+     if (hw->phy_type == e1000_phy_m88) {
+-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++                                         &phy_data)))
++            return ret_val;
+         /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
+          * forced whenever speed are duplex are forced.
+          */
+         phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+-        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++                                          phy_data)))
++            return ret_val;
++
+         DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
+         /* Need to reset the PHY or these changes will be ignored */
+@@ -1262,26 +1443,23 @@
+         /* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
+          * forced whenever speed or duplex are forced.
+          */
+-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++                                         &phy_data)))
++            return ret_val;
+         phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+         phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
++                                          phy_data)))
++            return ret_val;
+     }
+     /* Write back the modified PHY MII control register. */
+-    if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) {
+-        DEBUGOUT("PHY Write Error\n");
+-        return -E1000_ERR_PHY;
+-    }
+     udelay(1);
++    if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg)))
++        return ret_val;
++
+     /* The wait_autoneg_complete flag may be a little misleading here.
+      * Since we are forcing speed and duplex, Auto-Neg is not enabled.
+@@ -1300,22 +1478,18 @@
+             /* Read the MII Status Register and wait for Auto-Neg Complete bit
+              * to be set.
+              */
+-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
+-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
++            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++                return ret_val;
++
++            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++                return ret_val;
++
+             if(mii_status_reg & MII_SR_LINK_STATUS) break;
+             msec_delay(100);
+         }
+         if(i == 0) { /* We didn't get link */
+             /* Reset the DSP and wait again for link. */
+-
+-            ret_val = e1000_phy_reset_dsp(hw);
+-            if(ret_val < 0) {
++            if((ret_val = e1000_phy_reset_dsp(hw))) {
+                 DEBUGOUT("Error Resetting PHY DSP\n");
+                 return ret_val;
+             }
+@@ -1327,14 +1501,11 @@
+             /* Read the MII Status Register and wait for Auto-Neg Complete bit
+              * to be set.
+              */
+-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
+-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
++            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++                return ret_val;
++
++            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++                return ret_val;
+         }
+     }
+@@ -1343,30 +1514,29 @@
+          * Extended PHY Specific Control Register to 25MHz clock.  This value
+          * defaults back to a 2.5MHz clock when the PHY is reset.
+          */
+-        if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++                                         &phy_data)))
++            return ret_val;
++
+         phy_data |= M88E1000_EPSCR_TX_CLK_25;
+-        if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
++                                          phy_data)))
++            return ret_val;
+         /* In addition, because of the s/w reset above, we need to enable CRS on
+          * TX.  This must be set for both full and half duplex operation.
+          */
+-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++                                         &phy_data)))
++            return ret_val;
++
+         phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+-        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
++                                          phy_data)))
++            return ret_val;
++
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1406,6 +1576,7 @@
+ e1000_config_mac_to_phy(struct e1000_hw *hw)
+ {
+     uint32_t ctrl;
++    int32_t ret_val;
+     uint16_t phy_data;
+     DEBUGFUNC("e1000_config_mac_to_phy");
+@@ -1421,10 +1592,10 @@
+      * registers depending on negotiated values.
+      */
+     if (hw->phy_type == e1000_phy_igp) {
+-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
++                                         &phy_data)))
++            return ret_val;
++
+         if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
+         else ctrl &= ~E1000_CTRL_FD;
+@@ -1440,10 +1611,10 @@
+                 IGP01E1000_PSSR_SPEED_100MBPS)
+             ctrl |= E1000_CTRL_SPD_100;
+     } else {
+-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++                                         &phy_data)))
++            return ret_val;
++
+         if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
+         else ctrl &= ~E1000_CTRL_FD;
+@@ -1459,7 +1630,7 @@
+     }
+     /* Write the configured values back to the Device Control Reg. */
+     E1000_WRITE_REG(hw, CTRL, ctrl);
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1473,7 +1644,7 @@
+  * by the PHY rather than the MAC. Software must also configure these
+  * bits when link is forced on a fiber connection.
+  *****************************************************************************/
+-static int32_t
++int32_t
+ e1000_force_mac_fc(struct e1000_hw *hw)
+ {
+     uint32_t ctrl;
+@@ -1526,7 +1697,7 @@
+         ctrl &= (~E1000_CTRL_TFCE);
+     E1000_WRITE_REG(hw, CTRL, ctrl);
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1557,9 +1728,9 @@
+      * configuration of the MAC to match the "fc" parameter.
+      */
+     if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
++       ((hw->media_type == e1000_media_type_internal_serdes) && (hw->autoneg_failed)) ||
+        ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) {
+-        ret_val = e1000_force_mac_fc(hw);
+-        if(ret_val < 0) {
++        if((ret_val = e1000_force_mac_fc(hw))) {
+             DEBUGOUT("Error forcing flow control settings\n");
+             return ret_val;
+         }
+@@ -1575,14 +1746,10 @@
+          * has completed.  We read this twice because this reg has
+          * some "sticky" (latched) bits.
+          */
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+-            DEBUGOUT("PHY Read Error \n");
+-            return -E1000_ERR_PHY;
+-        }
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+-            DEBUGOUT("PHY Read Error \n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++            return ret_val;
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
++            return ret_val;
+         if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
+             /* The AutoNeg process has completed, so we now need to
+@@ -1591,14 +1758,12 @@
+              * Register (Address 5) to determine how flow control was
+              * negotiated.
+              */
+-            if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
+-            if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
++            if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
++                                             &mii_nway_adv_reg)))
++                return ret_val;
++            if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
++                                             &mii_nway_lp_ability_reg)))
++                return ret_val;
+             /* Two bits in the Auto Negotiation Advertisement Register
+              * (Address 4) and two bits in the Auto Negotiation Base
+@@ -1704,7 +1869,7 @@
+                     hw->original_fc == e1000_fc_tx_pause) {
+                 hw->fc = e1000_fc_none;
+                 DEBUGOUT("Flow Control = NONE.\r\n");
+-            } else {
++            } else if(!hw->fc_strict_ieee) {
+                 hw->fc = e1000_fc_rx_pause;
+                 DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
+             }
+@@ -1713,7 +1878,10 @@
+              * negotiated to HALF DUPLEX, flow control should not be
+              * enabled per IEEE 802.3 spec.
+              */
+-            e1000_get_speed_and_duplex(hw, &speed, &duplex);
++            if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) {
++                DEBUGOUT("Error getting link speed and duplex\n");
++                return ret_val;
++            }
+             if(duplex == HALF_DUPLEX)
+                 hw->fc = e1000_fc_none;
+@@ -1721,16 +1889,15 @@
+             /* Now we call a subroutine to actually force the MAC
+              * controller to use the correct flow control settings.
+              */
+-            ret_val = e1000_force_mac_fc(hw);
+-            if(ret_val < 0) {
++            if((ret_val = e1000_force_mac_fc(hw))) {
+                 DEBUGOUT("Error forcing flow control settings\n");
+                 return ret_val;
+-             }
++            }
+         } else {
+             DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n");
+         }
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1747,19 +1914,19 @@
+     uint32_t ctrl;
+     uint32_t status;
+     uint32_t rctl;
+-    uint32_t signal;
++    uint32_t signal = 0;
+     int32_t ret_val;
+     uint16_t phy_data;
+     uint16_t lp_capability;
+     DEBUGFUNC("e1000_check_for_link");
+-    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
++    /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+      * set when the optics detect a signal. On older adapters, it will be
+-     * cleared when there is a signal
++     * cleared when there is a signal.  This applies to fiber media only.
+      */
+-    if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
+-    else signal = 0;
++    if(hw->media_type == e1000_media_type_fiber)
++        signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
+     ctrl = E1000_READ_REG(hw, CTRL);
+     status = E1000_READ_REG(hw, STATUS);
+@@ -1777,14 +1944,10 @@
+          * of the PHY.
+          * Read the register twice since the link bit is sticky.
+          */
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++            return ret_val;
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++            return ret_val;
+         if(phy_data & MII_SR_LINK_STATUS) {
+             hw->get_link_status = FALSE;
+@@ -1794,6 +1957,7 @@
+         } else {
+             /* No link detected */
++            e1000_config_dsp_after_link_change(hw, FALSE);
+             return 0;
+         }
+@@ -1802,6 +1966,9 @@
+          */
+         if(!hw->autoneg) return -E1000_ERR_CONFIG;
++        /* optimize the dsp settings for the igp phy */
++        e1000_config_dsp_after_link_change(hw, TRUE);
++
+         /* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
+          * have Si on board that is 82544 or newer, Auto
+          * Speed Detection takes care of MAC speed/duplex
+@@ -1813,8 +1980,7 @@
+         if(hw->mac_type >= e1000_82544)
+             e1000_config_collision_dist(hw);
+         else {
+-            ret_val = e1000_config_mac_to_phy(hw);
+-            if(ret_val < 0) {
++            if((ret_val = e1000_config_mac_to_phy(hw))) {
+                 DEBUGOUT("Error configuring MAC to PHY settings\n");
+                 return ret_val;
+             }
+@@ -1824,8 +1990,7 @@
+          * need to restore the desired flow control settings because we may
+          * have had to re-autoneg with a different link partner.
+          */
+-        ret_val = e1000_config_fc_after_link_up(hw);
+-        if(ret_val < 0) {
++        if((ret_val = e1000_config_fc_after_link_up(hw))) {
+             DEBUGOUT("Error configuring flow control\n");
+             return ret_val;
+         }
+@@ -1840,10 +2005,9 @@
+          * partner is TBI-based, and we turn on TBI Compatibility.
+          */
+         if(hw->tbi_compatibility_en) {
+-            if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &lp_capability) < 0) {
+-                DEBUGOUT("PHY Read Error\n");
+-                return -E1000_ERR_PHY;
+-            }
++            if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
++                                             &lp_capability)))
++                return ret_val;
+             if(lp_capability & (NWAY_LPAR_10T_HD_CAPS |
+                                 NWAY_LPAR_10T_FD_CAPS |
+                                 NWAY_LPAR_100TX_HD_CAPS |
+@@ -1900,8 +2064,7 @@
+         E1000_WRITE_REG(hw, CTRL, ctrl);
+         /* Configure Flow Control after forcing link up. */
+-        ret_val = e1000_config_fc_after_link_up(hw);
+-        if(ret_val < 0) {
++        if((ret_val = e1000_config_fc_after_link_up(hw))) {
+             DEBUGOUT("Error configuring flow control\n");
+             return ret_val;
+         }
+@@ -1918,7 +2081,7 @@
+         E1000_WRITE_REG(hw, TXCW, hw->txcw);
+         E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1928,12 +2091,14 @@
+  * speed - Speed of the connection
+  * duplex - Duplex setting of the connection
+  *****************************************************************************/
+-void
++int32_t
+ e1000_get_speed_and_duplex(struct e1000_hw *hw,
+                            uint16_t *speed,
+                            uint16_t *duplex)
+ {
+     uint32_t status;
++    int32_t ret_val;
++    uint16_t phy_data;
+     DEBUGFUNC("e1000_get_speed_and_duplex");
+@@ -1962,6 +2127,27 @@
+         *speed = SPEED_1000;
+         *duplex = FULL_DUPLEX;
+     }
++
++    /* IGP01 PHY may advertise full duplex operation after speed downgrade even
++     * if it is operating at half duplex.  Here we set the duplex settings to
++     * match the duplex in the link partner's capabilities.
++     */
++    if(hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
++        if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data)))
++            return ret_val;
++
++        if(!(phy_data & NWAY_ER_LP_NWAY_CAPS))
++            *duplex = HALF_DUPLEX;
++        else {
++            if((ret_val == e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data)))
++                return ret_val;
++            if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
++               (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
++                *duplex = HALF_DUPLEX;
++        }
++    }
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -1972,6 +2158,7 @@
+ int32_t
+ e1000_wait_autoneg(struct e1000_hw *hw)
+ {
++    int32_t ret_val;
+     uint16_t i;
+     uint16_t phy_data;
+@@ -1983,20 +2170,16 @@
+         /* Read the MII Status Register and wait for Auto-Neg
+          * Complete bit to be set.
+          */
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
+-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++            return ret_val;
++        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++            return ret_val;
+         if(phy_data & MII_SR_AUTONEG_COMPLETE) {
+-            return 0;
++            return E1000_SUCCESS;
+         }
+         msec_delay(100);
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -2010,11 +2193,11 @@
+                     uint32_t *ctrl)
+ {
+     /* Raise the clock input to the Management Data Clock (by setting the MDC
+-     * bit), and then delay 2 microseconds.
++     * bit), and then delay 10 microseconds.
+      */
+     E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
+     E1000_WRITE_FLUSH(hw);
+-    udelay(2);
++    udelay(10);
+ }
+ /******************************************************************************
+@@ -2028,11 +2211,11 @@
+                     uint32_t *ctrl)
+ {
+     /* Lower the clock input to the Management Data Clock (by clearing the MDC
+-     * bit), and then delay 2 microseconds.
++     * bit), and then delay 10 microseconds.
+      */
+     E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
+     E1000_WRITE_FLUSH(hw);
+-    udelay(2);
++    udelay(10);
+ }
+ /******************************************************************************
+@@ -2076,7 +2259,7 @@
+         E1000_WRITE_REG(hw, CTRL, ctrl);
+         E1000_WRITE_FLUSH(hw);
+-        udelay(2);
++        udelay(10);
+         e1000_raise_mdi_clk(hw, &ctrl);
+         e1000_lower_mdi_clk(hw, &ctrl);
+@@ -2138,8 +2321,8 @@
+ }
+ /*****************************************************************************
+-* Reads the value from a PHY register
+-*
++* Reads the value from a PHY register, if the value is on a specific non zero
++* page, sets the page first.
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ ******************************************************************************/
+@@ -2148,11 +2331,33 @@
+                    uint32_t reg_addr,
+                    uint16_t *phy_data)
+ {
++    uint32_t ret_val;
++
++    DEBUGFUNC("e1000_read_phy_reg");
++
++    if(hw->phy_type == e1000_phy_igp &&
++       (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
++        if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
++                                             (uint16_t)reg_addr)))
++            return ret_val;
++    }
++
++    ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
++                                    phy_data);
++
++    return ret_val;
++}
++
++int32_t
++e1000_read_phy_reg_ex(struct e1000_hw *hw,
++                      uint32_t reg_addr,
++                      uint16_t *phy_data)
++{
+     uint32_t i;
+     uint32_t mdic = 0;
+     const uint32_t phy_addr = 1;
+-    DEBUGFUNC("e1000_read_phy_reg");
++    DEBUGFUNC("e1000_read_phy_reg_ex");
+     if(reg_addr > MAX_PHY_REG_ADDRESS) {
+         DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+@@ -2172,7 +2377,7 @@
+         /* Poll the ready bit to see if the MDI read completed */
+         for(i = 0; i < 64; i++) {
+-            udelay(10);
++            udelay(50);
+             mdic = E1000_READ_REG(hw, MDIC);
+             if(mdic & E1000_MDIC_READY) break;
+         }
+@@ -2214,7 +2419,7 @@
+          */
+         *phy_data = e1000_shift_in_mdi_bits(hw);
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -2229,11 +2434,33 @@
+                     uint32_t reg_addr,
+                     uint16_t phy_data)
+ {
++    uint32_t ret_val;
++
++    DEBUGFUNC("e1000_write_phy_reg");
++
++    if(hw->phy_type == e1000_phy_igp &&
++       (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
++        if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
++                                             (uint16_t)reg_addr)))
++            return ret_val;
++    }
++
++    ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
++                                     phy_data);
++
++    return ret_val;
++}
++
++int32_t
++e1000_write_phy_reg_ex(struct e1000_hw *hw,
++                    uint32_t reg_addr,
++                    uint16_t phy_data)
++{
+     uint32_t i;
+     uint32_t mdic = 0;
+     const uint32_t phy_addr = 1;
+-    DEBUGFUNC("e1000_write_phy_reg");
++    DEBUGFUNC("e1000_write_phy_reg_ex");
+     if(reg_addr > MAX_PHY_REG_ADDRESS) {
+         DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+@@ -2254,7 +2481,7 @@
+         /* Poll the ready bit to see if the MDI read completed */
+         for(i = 0; i < 64; i++) {
+-            udelay(10);
++            udelay(50);
+             mdic = E1000_READ_REG(hw, MDIC);
+             if(mdic & E1000_MDIC_READY) break;
+         }
+@@ -2284,7 +2511,7 @@
+         e1000_shift_out_mdi_bits(hw, mdic, 32);
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -2329,11 +2556,6 @@
+     udelay(150);
+     if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
+-            DEBUGOUT("PHY Write Error\n");
+-            return;
+-        }
+-
+         /* Configure activity LED after PHY reset */
+         led_ctrl = E1000_READ_REG(hw, LEDCTL);
+         led_ctrl &= IGP_ACTIVITY_LED_MASK;
+@@ -2352,24 +2574,26 @@
+ int32_t
+ e1000_phy_reset(struct e1000_hw *hw)
+ {
++    int32_t ret_val;
+     uint16_t phy_data;
+     DEBUGFUNC("e1000_phy_reset");
+-    if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
+-    phy_data |= MII_CR_RESET;
+-    if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
+-        DEBUGOUT("PHY Write Error\n");
+-        return -E1000_ERR_PHY;
+-    }
+-    udelay(1);
+-    if (hw->phy_type == e1000_phy_igp) {
++    if(hw->mac_type != e1000_82541_rev_2) {
++        if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
++            return ret_val;
++
++        phy_data |= MII_CR_RESET;
++        if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
++            return ret_val;
++
++        udelay(1);
++    } else e1000_phy_hw_reset(hw);
++
++    if(hw->phy_type == e1000_phy_igp)
+         e1000_phy_init_script(hw);
+-    }
+-    return 0;
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -2380,23 +2604,21 @@
+ int32_t
+ e1000_detect_gig_phy(struct e1000_hw *hw)
+ {
++    int32_t phy_init_status, ret_val;
+     uint16_t phy_id_high, phy_id_low;
+     boolean_t match = FALSE;
+-    int32_t phy_init_status;
+     DEBUGFUNC("e1000_detect_gig_phy");
+     /* Read the PHY ID Registers to identify which PHY is onboard. */
+-    if(e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
++    if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
++        return ret_val;
++
+     hw->phy_id = (uint32_t) (phy_id_high << 16);
+     udelay(20);
+-    if(e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
++    if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
++        return ret_val;
++
+     hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
+     hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
+@@ -2409,11 +2631,15 @@
+         break;
+     case e1000_82540:
+     case e1000_82545:
++    case e1000_82545_rev_3:
+     case e1000_82546:
++    case e1000_82546_rev_3:
+         if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
+         break;
+     case e1000_82541:
++    case e1000_82541_rev_2:
+     case e1000_82547:
++    case e1000_82547_rev_2:
+         if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
+         break;
+     default:
+@@ -2424,7 +2650,7 @@
+     if ((match) && (phy_init_status == E1000_SUCCESS)) {
+         DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
+-        return 0;
++        return E1000_SUCCESS;
+     }
+     DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
+     return -E1000_ERR_PHY;
+@@ -2438,17 +2664,16 @@
+ static int32_t
+ e1000_phy_reset_dsp(struct e1000_hw *hw)
+ {
+-    int32_t ret_val = -E1000_ERR_PHY;
++    int32_t ret_val;
+     DEBUGFUNC("e1000_phy_reset_dsp");
+     do {
+-        if(e1000_write_phy_reg(hw, 29, 0x001d) < 0) break;
+-        if(e1000_write_phy_reg(hw, 30, 0x00c1) < 0) break;
+-        if(e1000_write_phy_reg(hw, 30, 0x0000) < 0) break;
+-        ret_val = 0;
++        if((ret_val = e1000_write_phy_reg(hw, 29, 0x001d))) break;
++        if((ret_val = e1000_write_phy_reg(hw, 30, 0x00c1))) break;
++        if((ret_val = e1000_write_phy_reg(hw, 30, 0x0000))) break;
++        ret_val = E1000_SUCCESS;
+     } while(0);
+-    if(ret_val < 0) DEBUGOUT("PHY Write Error\n");
+     return ret_val;
+ }
+@@ -2459,8 +2684,10 @@
+ * phy_info - PHY information structure
+ ******************************************************************************/
+ int32_t
+-e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
++e1000_phy_igp_get_info(struct e1000_hw *hw,
++                       struct e1000_phy_info *phy_info)
+ {
++    int32_t ret_val;
+     uint16_t phy_data, polarity, min_length, max_length, average;
+     DEBUGFUNC("e1000_phy_igp_get_info");
+@@ -2476,13 +2703,14 @@
+     phy_info->polarity_correction = e1000_polarity_reversal_enabled;
+     /* Check polarity status */
+-    if(e1000_check_polarity(hw, &polarity) < 0)
+-        return -E1000_ERR_PHY;
++    if((ret_val = e1000_check_polarity(hw, &polarity)))
++        return ret_val;
+     phy_info->cable_polarity = polarity;
+-    if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
+-        return -E1000_ERR_PHY;
++    if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
++                                     &phy_data)))
++        return ret_val;
+     phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
+                           IGP01E1000_PSSR_MDIX_SHIFT;
+@@ -2490,8 +2718,8 @@
+     if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+        IGP01E1000_PSSR_SPEED_1000MBPS) {
+         /* Local/Remote Receiver Information are only valid at 1000 Mbps */
+-        if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
+-            return -E1000_ERR_PHY;
++        if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
++            return ret_val;
+         phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                              SR_1000T_LOCAL_RX_STATUS_SHIFT;
+@@ -2499,8 +2727,8 @@
+                               SR_1000T_REMOTE_RX_STATUS_SHIFT;
+         /* Get cable length */
+-        if(e1000_get_cable_length(hw, &min_length, &max_length) < 0)
+-            return -E1000_ERR_PHY;
++        if((ret_val = e1000_get_cable_length(hw, &min_length, &max_length)))
++            return ret_val;
+         /* transalte to old method */
+         average = (max_length + min_length) / 2;
+@@ -2527,8 +2755,10 @@
+ * phy_info - PHY information structure
+ ******************************************************************************/
+ int32_t
+-e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
++e1000_phy_m88_get_info(struct e1000_hw *hw,
++                       struct e1000_phy_info *phy_info)
+ {
++    int32_t ret_val;
+     uint16_t phy_data, polarity;
+     DEBUGFUNC("e1000_phy_m88_get_info");
+@@ -2537,8 +2767,8 @@
+      * and it stored in the hw->speed_downgraded parameter. */
+     phy_info->downshift = hw->speed_downgraded;
+-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0)
+-        return -E1000_ERR_PHY;
++    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data)))
++        return ret_val;
+     phy_info->extended_10bt_distance =
+         (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+@@ -2548,13 +2778,13 @@
+         M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+     /* Check polarity status */
+-    if(e1000_check_polarity(hw, &polarity) < 0)
+-        return -E1000_ERR_PHY;
++    if((ret_val = e1000_check_polarity(hw, &polarity)))
++        return ret_val;
+     phy_info->cable_polarity = polarity;
+-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+-        return -E1000_ERR_PHY;
++    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data)))
++        return ret_val;
+     phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
+                           M88E1000_PSSR_MDIX_SHIFT;
+@@ -2566,8 +2796,8 @@
+         phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+                                   M88E1000_PSSR_CABLE_LENGTH_SHIFT);
+-        if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
+-            return -E1000_ERR_PHY;
++        if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
++            return ret_val;
+         phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                              SR_1000T_LOCAL_RX_STATUS_SHIFT;
+@@ -2589,6 +2819,7 @@
+ e1000_phy_get_info(struct e1000_hw *hw,
+                    struct e1000_phy_info *phy_info)
+ {
++    int32_t ret_val;
+     uint16_t phy_data;
+     DEBUGFUNC("e1000_phy_get_info");
+@@ -2607,20 +2838,18 @@
+         return -E1000_ERR_CONFIG;
+     }
+-    if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
+-    if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+-        DEBUGOUT("PHY Read Error\n");
+-        return -E1000_ERR_PHY;
+-    }
++    if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++        return ret_val;
++
++    if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
++        return ret_val;
++
+     if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
+         DEBUGOUT("PHY info is only valid if link is up\n");
+         return -E1000_ERR_CONFIG;
+     }
+-    if (hw->phy_type == e1000_phy_igp)
++    if(hw->phy_type == e1000_phy_igp)
+         return e1000_phy_igp_get_info(hw, phy_info);
+     else
+         return e1000_phy_m88_get_info(hw, phy_info);
+@@ -2636,7 +2865,7 @@
+         hw->mdix = 1;
+         return -E1000_ERR_CONFIG;
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+@@ -2668,7 +2897,9 @@
+         break;
+     case e1000_82540:
+     case e1000_82545:
++    case e1000_82545_rev_3:
+     case e1000_82546:
++    case e1000_82546_rev_3:
+         eeprom->type = e1000_eeprom_microwire;
+         eeprom->opcode_bits = 3;
+         eeprom->delay_usec = 50;
+@@ -2681,8 +2912,9 @@
+         }
+         break;
+     case e1000_82541:
++    case e1000_82541_rev_2:
+     case e1000_82547:
+-    default:
++    case e1000_82547_rev_2:
+         if (eecd & E1000_EECD_TYPE) {
+             eeprom->type = e1000_eeprom_spi;
+             eeprom->opcode_bits = 8;
+@@ -2707,6 +2939,18 @@
+             }
+         }
+         break;
++    default:
++        eeprom->type = e1000_eeprom_spi;
++        eeprom->opcode_bits = 8;
++        eeprom->delay_usec = 1;
++        if (eecd & E1000_EECD_ADDR_BITS) {
++            eeprom->page_size = 32;
++            eeprom->address_bits = 16;
++        } else {
++            eeprom->page_size = 8;
++            eeprom->address_bits = 8;
++        }
++        break;
+     }
+     if (eeprom->type == e1000_eeprom_spi) {
+@@ -2715,28 +2959,28 @@
+             eeprom_size &= EEPROM_SIZE_MASK;
+             switch (eeprom_size) {
+-                case EEPROM_SIZE_16KB:
+-                    eeprom->word_size = 8192;
+-                    break;
+-                case EEPROM_SIZE_8KB:
+-                    eeprom->word_size = 4096;
+-                    break;
+-                case EEPROM_SIZE_4KB:
+-                    eeprom->word_size = 2048;
+-                    break;
+-                case EEPROM_SIZE_2KB:
+-                    eeprom->word_size = 1024;
+-                    break;
+-                case EEPROM_SIZE_1KB:
+-                    eeprom->word_size = 512;
+-                    break;
+-                case EEPROM_SIZE_512B:
+-                    eeprom->word_size = 256;
+-                    break;
+-                case EEPROM_SIZE_128B:
+-                default:
+-                    eeprom->word_size = 64;
+-                    break;
++            case EEPROM_SIZE_16KB:
++                eeprom->word_size = 8192;
++                break;
++            case EEPROM_SIZE_8KB:
++                eeprom->word_size = 4096;
++                break;
++            case EEPROM_SIZE_4KB:
++                eeprom->word_size = 2048;
++                break;
++            case EEPROM_SIZE_2KB:
++                eeprom->word_size = 1024;
++                break;
++            case EEPROM_SIZE_1KB:
++                eeprom->word_size = 512;
++                break;
++            case EEPROM_SIZE_512B:
++                eeprom->word_size = 256;
++                break;
++            case EEPROM_SIZE_128B:
++            default:
++                eeprom->word_size = 64;
++                break;
+             }
+         }
+     }
+@@ -2841,7 +3085,8 @@
+  * hw - Struct containing variables accessed by shared code
+  *****************************************************************************/
+ static uint16_t
+-e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)
++e1000_shift_in_ee_bits(struct e1000_hw *hw,
++                       uint16_t count)
+ {
+     uint32_t eecd;
+     uint32_t i;
+@@ -3101,13 +3346,17 @@
+     }
+     /* Prepare the EEPROM for reading  */
+-    if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
++    if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+         return -E1000_ERR_EEPROM;
+     if(eeprom->type == e1000_eeprom_spi) {
++        uint16_t word_in;
+         uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
+-        if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
++        if(e1000_spi_eeprom_ready(hw)) {
++            e1000_release_eeprom(hw);
++            return -E1000_ERR_EEPROM;
++        }
+         e1000_standby_eeprom(hw);
+@@ -3118,30 +3367,35 @@
+         /* Send the READ command (opcode + addr)  */
+         e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
+         e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
+-    }
+-    else if(eeprom->type == e1000_eeprom_microwire) {
+-        /* Send the READ command (opcode + addr)  */
+-        e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
+-                                eeprom->opcode_bits);
+-        e1000_shift_out_ee_bits(hw, offset, eeprom->address_bits);
+-    }
+-    /* Read the data.  The address of the eeprom internally increments with
+-     * each word (microwire) or byte (spi) being read, saving on the overhead
+-     * of eeprom setup and tear-down.  The address counter will roll over if
+-     * reading beyond the size of the eeprom, thus allowing the entire memory
+-     * to be read starting from any offset. */
+-    for (i = 0; i < words; i++) {
+-        uint16_t word_in = e1000_shift_in_ee_bits(hw, 16);
+-        if (eeprom->type == e1000_eeprom_spi)
+-            word_in = (word_in >> 8) | (word_in << 8);
+-        data[i] = word_in;
++        /* Read the data.  The address of the eeprom internally increments with
++         * each byte (spi) being read, saving on the overhead of eeprom setup
++         * and tear-down.  The address counter will roll over if reading beyond
++         * the size of the eeprom, thus allowing the entire memory to be read
++         * starting from any offset. */
++        for (i = 0; i < words; i++) {
++            word_in = e1000_shift_in_ee_bits(hw, 16);
++            data[i] = (word_in >> 8) | (word_in << 8);
++        }
++    } else if(eeprom->type == e1000_eeprom_microwire) {
++        for (i = 0; i < words; i++) {
++            /* Send the READ command (opcode + addr)  */
++            e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
++                                    eeprom->opcode_bits);
++            e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
++                                    eeprom->address_bits);
++
++            /* Read the data.  For microwire, each word requires the overhead
++             * of eeprom setup and tear-down. */
++            data[i] = e1000_shift_in_ee_bits(hw, 16);
++            e1000_standby_eeprom(hw);
++        }
+     }
+     /* End this read operation */
+     e1000_release_eeprom(hw);
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3169,9 +3423,9 @@
+         checksum += eeprom_data;
+     }
+-    if(checksum == (uint16_t) EEPROM_SUM) {
+-        return 0;
+-    } else {
++    if(checksum == (uint16_t) EEPROM_SUM)
++        return E1000_SUCCESS;
++    else {
+         DEBUGOUT("EEPROM Checksum Invalid\n");
+         return -E1000_ERR_EEPROM;
+     }
+@@ -3205,7 +3459,7 @@
+         DEBUGOUT("EEPROM Write Error\n");
+         return -E1000_ERR_EEPROM;
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3403,7 +3657,7 @@
+     e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3437,7 +3691,7 @@
+     /* Save word 1 in lower half of part_num */
+     *part_num |= eeprom_data;
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3463,7 +3717,7 @@
+         hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
+         hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
+     }
+-    if((hw->mac_type == e1000_82546) &&
++    if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
+        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+         if(hw->perm_mac_addr[5] & 0x01)
+             hw->perm_mac_addr[5] &= ~(0x01);
+@@ -3472,7 +3726,7 @@
+     }
+     for(i = 0; i < NODE_ADDRESS_SIZE; i++)
+         hw->mac_addr[i] = hw->perm_mac_addr[i];
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3748,7 +4002,7 @@
+     if(hw->mac_type < e1000_82540) {
+         /* Nothing to do */
+-        return 0;
++        return E1000_SUCCESS;
+     }
+     ledctl = E1000_READ_REG(hw, LEDCTL);
+@@ -3799,7 +4053,7 @@
+             break;
+         }
+     }
+-    return 0;
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3811,49 +4065,48 @@
+ e1000_setup_led(struct e1000_hw *hw)
+ {
+     uint32_t ledctl;
++    int32_t ret_val = E1000_SUCCESS;
+     DEBUGFUNC("e1000_setup_led");
+-    switch(hw->device_id) {
+-    case E1000_DEV_ID_82542:
+-    case E1000_DEV_ID_82543GC_FIBER:
+-    case E1000_DEV_ID_82543GC_COPPER:
+-    case E1000_DEV_ID_82544EI_COPPER:
+-    case E1000_DEV_ID_82544EI_FIBER:
+-    case E1000_DEV_ID_82544GC_COPPER:
+-    case E1000_DEV_ID_82544GC_LOM:
++    switch(hw->mac_type) {
++    case e1000_82542_rev2_0:
++    case e1000_82542_rev2_1:
++    case e1000_82543:
++    case e1000_82544:
+         /* No setup necessary */
+         break;
+-    case E1000_DEV_ID_82545EM_FIBER:
+-    case E1000_DEV_ID_82546EB_FIBER:
+-        ledctl = E1000_READ_REG(hw, LEDCTL);
+-        /* Save current LEDCTL settings */
+-        hw->ledctl_default = ledctl;
+-        /* Turn off LED0 */
+-        ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
+-                    E1000_LEDCTL_LED0_BLINK |
+-                    E1000_LEDCTL_LED0_MODE_MASK);
+-        ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT);
+-        E1000_WRITE_REG(hw, LEDCTL, ledctl);
+-        break;
+-    case E1000_DEV_ID_82540EP:
+-    case E1000_DEV_ID_82540EP_LOM:
+-    case E1000_DEV_ID_82540EP_LP:
+-    case E1000_DEV_ID_82540EM:
+-    case E1000_DEV_ID_82540EM_LOM:
+-    case E1000_DEV_ID_82545EM_COPPER:
+-    case E1000_DEV_ID_82546EB_COPPER:
+-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
+-    case E1000_DEV_ID_82541EI:
+-    case E1000_DEV_ID_82541EP:
+-    case E1000_DEV_ID_82547EI:
+-        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
+-        break;
++    case e1000_82541:
++    case e1000_82547:
++    case e1000_82541_rev_2:
++    case e1000_82547_rev_2:
++        /* Turn off PHY Smart Power Down (if enabled) */
++        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
++                                         &hw->phy_spd_default)))
++            return ret_val;
++        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
++                                          (uint16_t)(hw->phy_spd_default &
++                                          ~IGP01E1000_GMII_SPD))))
++            return ret_val;
++        /* Fall Through */
+     default:
+-        DEBUGOUT("Invalid device ID\n");
+-        return -E1000_ERR_CONFIG;
++        if(hw->media_type == e1000_media_type_fiber) {
++            ledctl = E1000_READ_REG(hw, LEDCTL);
++            /* Save current LEDCTL settings */
++            hw->ledctl_default = ledctl;
++            /* Turn off LED0 */
++            ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
++                        E1000_LEDCTL_LED0_BLINK |
++                        E1000_LEDCTL_LED0_MODE_MASK);
++            ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
++                       E1000_LEDCTL_LED0_MODE_SHIFT);
++            E1000_WRITE_REG(hw, LEDCTL, ledctl);
++        } else if(hw->media_type == e1000_media_type_copper)
++            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
++        break;
+     }
+-    return 0;
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3864,39 +4117,33 @@
+ int32_t
+ e1000_cleanup_led(struct e1000_hw *hw)
+ {
++    int32_t ret_val = E1000_SUCCESS;
++
+     DEBUGFUNC("e1000_cleanup_led");
+-    switch(hw->device_id) {
+-    case E1000_DEV_ID_82542:
+-    case E1000_DEV_ID_82543GC_FIBER:
+-    case E1000_DEV_ID_82543GC_COPPER:
+-    case E1000_DEV_ID_82544EI_COPPER:
+-    case E1000_DEV_ID_82544EI_FIBER:
+-    case E1000_DEV_ID_82544GC_COPPER:
+-    case E1000_DEV_ID_82544GC_LOM:
++    switch(hw->mac_type) {
++    case e1000_82542_rev2_0:
++    case e1000_82542_rev2_1:
++    case e1000_82543:
++    case e1000_82544:
+         /* No cleanup necessary */
+         break;
+-    case E1000_DEV_ID_82540EP:
+-    case E1000_DEV_ID_82540EP_LOM:
+-    case E1000_DEV_ID_82540EP_LP:
+-    case E1000_DEV_ID_82540EM:
+-    case E1000_DEV_ID_82540EM_LOM:
+-    case E1000_DEV_ID_82545EM_COPPER:
+-    case E1000_DEV_ID_82545EM_FIBER:
+-    case E1000_DEV_ID_82546EB_COPPER:
+-    case E1000_DEV_ID_82546EB_FIBER:
+-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
+-    case E1000_DEV_ID_82541EI:
+-    case E1000_DEV_ID_82541EP:
+-    case E1000_DEV_ID_82547EI:
++    case e1000_82541:
++    case e1000_82547:
++    case e1000_82541_rev_2:
++    case e1000_82547_rev_2:
++        /* Turn on PHY Smart Power Down (if previously enabled) */
++        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
++                                          hw->phy_spd_default)))
++            return ret_val;
++        /* Fall Through */
++    default:
+         /* Restore LEDCTL settings */
+         E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
+         break;
+-    default:
+-        DEBUGOUT("Invalid device ID\n");
+-        return -E1000_ERR_CONFIG;
+     }
+-    return 0;
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3907,50 +4154,44 @@
+ int32_t
+ e1000_led_on(struct e1000_hw *hw)
+ {
+-    uint32_t ctrl;
++    uint32_t ctrl = E1000_READ_REG(hw, CTRL);
+     DEBUGFUNC("e1000_led_on");
+-    switch(hw->device_id) {
+-    case E1000_DEV_ID_82542:
+-    case E1000_DEV_ID_82543GC_FIBER:
+-    case E1000_DEV_ID_82543GC_COPPER:
+-    case E1000_DEV_ID_82544EI_FIBER:
+-        ctrl = E1000_READ_REG(hw, CTRL);
++    switch(hw->mac_type) {
++    case e1000_82542_rev2_0:
++    case e1000_82542_rev2_1:
++    case e1000_82543:
+         /* Set SW Defineable Pin 0 to turn on the LED */
+         ctrl |= E1000_CTRL_SWDPIN0;
+         ctrl |= E1000_CTRL_SWDPIO0;
+-        E1000_WRITE_REG(hw, CTRL, ctrl);
+         break;
+-    case E1000_DEV_ID_82544EI_COPPER:
+-    case E1000_DEV_ID_82544GC_COPPER:
+-    case E1000_DEV_ID_82544GC_LOM:
+-    case E1000_DEV_ID_82545EM_FIBER:
+-    case E1000_DEV_ID_82546EB_FIBER:
+-        ctrl = E1000_READ_REG(hw, CTRL);
+-        /* Clear SW Defineable Pin 0 to turn on the LED */
+-        ctrl &= ~E1000_CTRL_SWDPIN0;
+-        ctrl |= E1000_CTRL_SWDPIO0;
+-        E1000_WRITE_REG(hw, CTRL, ctrl);
+-        break;
+-    case E1000_DEV_ID_82540EP:
+-    case E1000_DEV_ID_82540EP_LOM:
+-    case E1000_DEV_ID_82540EP_LP:
+-    case E1000_DEV_ID_82540EM:
+-    case E1000_DEV_ID_82540EM_LOM:
+-    case E1000_DEV_ID_82545EM_COPPER:
+-    case E1000_DEV_ID_82546EB_COPPER:
+-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
+-    case E1000_DEV_ID_82541EI:
+-    case E1000_DEV_ID_82541EP:
+-    case E1000_DEV_ID_82547EI:
+-        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
++    case e1000_82544:
++        if(hw->media_type == e1000_media_type_fiber) {
++            /* Set SW Defineable Pin 0 to turn on the LED */
++            ctrl |= E1000_CTRL_SWDPIN0;
++            ctrl |= E1000_CTRL_SWDPIO0;
++        } else {
++            /* Clear SW Defineable Pin 0 to turn on the LED */
++            ctrl &= ~E1000_CTRL_SWDPIN0;
++            ctrl |= E1000_CTRL_SWDPIO0;
++        }
+         break;
+     default:
+-        DEBUGOUT("Invalid device ID\n");
+-        return -E1000_ERR_CONFIG;
++        if(hw->media_type == e1000_media_type_fiber) {
++            /* Clear SW Defineable Pin 0 to turn on the LED */
++            ctrl &= ~E1000_CTRL_SWDPIN0;
++            ctrl |= E1000_CTRL_SWDPIO0;
++        } else if(hw->media_type == e1000_media_type_copper) {
++            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
++            return E1000_SUCCESS;
++        }
++        break;
+     }
+-    return 0;
++
++    E1000_WRITE_REG(hw, CTRL, ctrl);
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -3961,50 +4202,44 @@
+ int32_t
+ e1000_led_off(struct e1000_hw *hw)
+ {
+-    uint32_t ctrl;
++    uint32_t ctrl = E1000_READ_REG(hw, CTRL);
+     DEBUGFUNC("e1000_led_off");
+-    switch(hw->device_id) {
+-    case E1000_DEV_ID_82542:
+-    case E1000_DEV_ID_82543GC_FIBER:
+-    case E1000_DEV_ID_82543GC_COPPER:
+-    case E1000_DEV_ID_82544EI_FIBER:
+-        ctrl = E1000_READ_REG(hw, CTRL);
++    switch(hw->mac_type) {
++    case e1000_82542_rev2_0:
++    case e1000_82542_rev2_1:
++    case e1000_82543:
+         /* Clear SW Defineable Pin 0 to turn off the LED */
+         ctrl &= ~E1000_CTRL_SWDPIN0;
+         ctrl |= E1000_CTRL_SWDPIO0;
+-        E1000_WRITE_REG(hw, CTRL, ctrl);
+         break;
+-    case E1000_DEV_ID_82544EI_COPPER:
+-    case E1000_DEV_ID_82544GC_COPPER:
+-    case E1000_DEV_ID_82544GC_LOM:
+-    case E1000_DEV_ID_82545EM_FIBER:
+-    case E1000_DEV_ID_82546EB_FIBER:
+-        ctrl = E1000_READ_REG(hw, CTRL);
+-        /* Set SW Defineable Pin 0 to turn off the LED */
+-        ctrl |= E1000_CTRL_SWDPIN0;
+-        ctrl |= E1000_CTRL_SWDPIO0;
+-        E1000_WRITE_REG(hw, CTRL, ctrl);
+-        break;
+-    case E1000_DEV_ID_82540EP:
+-    case E1000_DEV_ID_82540EP_LOM:
+-    case E1000_DEV_ID_82540EP_LP:
+-    case E1000_DEV_ID_82540EM:
+-    case E1000_DEV_ID_82540EM_LOM:
+-    case E1000_DEV_ID_82545EM_COPPER:
+-    case E1000_DEV_ID_82546EB_COPPER:
+-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
+-    case E1000_DEV_ID_82541EI:
+-    case E1000_DEV_ID_82541EP:
+-    case E1000_DEV_ID_82547EI:
+-        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
++    case e1000_82544:
++        if(hw->media_type == e1000_media_type_fiber) {
++            /* Clear SW Defineable Pin 0 to turn off the LED */
++            ctrl &= ~E1000_CTRL_SWDPIN0;
++            ctrl |= E1000_CTRL_SWDPIO0;
++        } else {
++            /* Set SW Defineable Pin 0 to turn off the LED */
++            ctrl |= E1000_CTRL_SWDPIN0;
++            ctrl |= E1000_CTRL_SWDPIO0;
++        }
+         break;
+     default:
+-        DEBUGOUT("Invalid device ID\n");
+-        return -E1000_ERR_CONFIG;
++        if(hw->media_type == e1000_media_type_fiber) {
++            /* Set SW Defineable Pin 0 to turn off the LED */
++            ctrl |= E1000_CTRL_SWDPIN0;
++            ctrl |= E1000_CTRL_SWDPIO0;
++        } else if(hw->media_type == e1000_media_type_copper) {
++            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
++            return E1000_SUCCESS;
++        }
++        break;
+     }
+-    return 0;
++
++    E1000_WRITE_REG(hw, CTRL, ctrl);
++
++    return E1000_SUCCESS;
+ }
+ /******************************************************************************
+@@ -4127,8 +4362,7 @@
+     DEBUGFUNC("e1000_update_adaptive");
+     if(hw->adaptive_ifs) {
+-        if((hw->collision_delta * hw->ifs_ratio) >
+-           hw->tx_packet_delta) {
++        if((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
+             if(hw->tx_packet_delta > MIN_NUM_XMITS) {
+                 hw->in_ifs_mode = TRUE;
+                 if(hw->current_ifs_val < hw->ifs_max_val) {
+@@ -4140,8 +4374,7 @@
+                 }
+             }
+         } else {
+-            if((hw->in_ifs_mode == TRUE) &&
+-               (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
++            if(hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
+                 hw->current_ifs_val = 0;
+                 hw->in_ifs_mode = FALSE;
+                 E1000_WRITE_REG(hw, AIT, 0);
+@@ -4324,7 +4557,8 @@
+  * min_length - The estimated minimum length
+  * max_length - The estimated maximum length
+  *
+- * returns: E1000_SUCCESS / -E1000_ERR_XXX
++ * returns: - E1000_ERR_XXX
++ *            E1000_SUCCESS
+  *
+  * This function always returns a ranged length (minimum & maximum).
+  * So for M88 phy's, this function interprets the one value returned from the
+@@ -4332,9 +4566,11 @@
+  * For IGP phy's, the function calculates the range by the AGC registers.
+  *****************************************************************************/
+ int32_t
+-e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length,
++e1000_get_cable_length(struct e1000_hw *hw,
++                       uint16_t *min_length,
+                        uint16_t *max_length)
+ {
++    int32_t ret_val;
+     uint16_t agc_value = 0;
+     uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
+     uint16_t i, phy_data;
+@@ -4345,8 +4581,9 @@
+     /* Use old method for Phy older than IGP */
+     if(hw->phy_type == e1000_phy_m88) {
+-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+-            return -E1000_ERR_PHY;
++        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++                                         &phy_data)))
++            return ret_val;
+         /* Convert the enum value to ranged values */
+         switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+@@ -4376,19 +4613,16 @@
+             break;
+         }
+     } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
+-        uint16_t agc_reg_array[IGP01E1000_PHY_AGC_NUM] = {IGP01E1000_PHY_AGC_A,
++        uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
++                                                         {IGP01E1000_PHY_AGC_A,
+                                                           IGP01E1000_PHY_AGC_B,
+                                                           IGP01E1000_PHY_AGC_C,
+                                                           IGP01E1000_PHY_AGC_D};
+         /* Read the AGC registers for all channels */
+-        for(i = 0; i < IGP01E1000_PHY_AGC_NUM; i++) {
+-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+-                                   agc_reg_array[i]) != E1000_SUCCESS)
+-                return -E1000_ERR_PHY;
+-            if(e1000_read_phy_reg(hw, agc_reg_array[i] &
+-                                  IGP01E1000_PHY_PAGE_SELECT, &phy_data) !=
+-                                  E1000_SUCCESS)
+-                return -E1000_ERR_PHY;
++        for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
++
++            if((ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data)))
++                return ret_val;
+             cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
+@@ -4404,20 +4638,15 @@
+                 min_agc = cur_agc;
+         }
+-        /* Return to page 0 */
+-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
+-           E1000_SUCCESS)
+-            return -E1000_ERR_PHY;
+-
+         /* Remove the minimal AGC result for length < 50m */
+-        if(agc_value < IGP01E1000_PHY_AGC_NUM * e1000_igp_cable_length_50) {
++        if(agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
+             agc_value -= min_agc;
+             /* Get the average length of the remaining 3 channels */
+-            agc_value /= (IGP01E1000_PHY_AGC_NUM - 1);
++            agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
+         } else {
+             /* Get the average length of all the 4 channels. */
+-            agc_value /= IGP01E1000_PHY_AGC_NUM;
++            agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
+         }
+         /* Set the range of the calculated length. */
+@@ -4439,7 +4668,8 @@
+  * polarity - output parameter : 0 - Polarity is not reversed
+  *                               1 - Polarity is reversed.
+  *
+- * returns: E1000_SUCCESS / -E1000_ERR_XXX
++ * returns: - E1000_ERR_XXX
++ *            E1000_SUCCESS
+  *
+  * For phy's older then IGP, this function simply reads the polarity bit in the
+  * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
+@@ -4448,22 +4678,26 @@
+  * IGP01E1000_PHY_PCS_INIT_REG.
+  *****************************************************************************/
+ int32_t
+-e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity)
++e1000_check_polarity(struct e1000_hw *hw,
++                     uint16_t *polarity)
+ {
++    int32_t ret_val;
+     uint16_t phy_data;
+     DEBUGFUNC("e1000_check_polarity");
+     if(hw->phy_type == e1000_phy_m88) {
+         /* return the Polarity bit in the Status register. */
+-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+-            return -E1000_ERR_PHY;
++        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++                                         &phy_data)))
++            return ret_val;
+         *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
+                     M88E1000_PSSR_REV_POLARITY_SHIFT;
+     } else if(hw->phy_type == e1000_phy_igp) {
+         /* Read the Status register to check the speed */
+-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
+-            return -E1000_ERR_PHY;
++        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
++                                         &phy_data)))
++            return ret_val;
+         /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
+          * find the polarity status */
+@@ -4471,18 +4705,9 @@
+            IGP01E1000_PSSR_SPEED_1000MBPS) {
+             /* Read the GIG initialization PCS register (0x00B4) */
+-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+-                                   IGP01E1000_PHY_PCS_INIT_REG) < 0)
+-                return -E1000_ERR_PHY;
+-
+-            if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG &
+-                                  IGP01E1000_PHY_PAGE_SELECT, &phy_data) < 0)
+-                return -E1000_ERR_PHY;
+-
+-            /* Return to page 0 */
+-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
+-               E1000_SUCCESS)
+-                return -E1000_ERR_PHY;
++            if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
++                                             &phy_data)))
++                return ret_val;
+             /* Check the polarity bits */
+             *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
+@@ -4502,7 +4727,8 @@
+  * downshift - output parameter : 0 - No Downshift ocured.
+  *                                1 - Downshift ocured.
+  *
+- * returns: E1000_SUCCESS / -E1000_ERR_XXX
++ * returns: - E1000_ERR_XXX
++ *            E1000_SUCCESS 
+  *
+  * For phy's older then IGP, this function reads the Downshift bit in the Phy
+  * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
+@@ -4512,25 +4738,287 @@
+ int32_t
+ e1000_check_downshift(struct e1000_hw *hw)
+ {
++    int32_t ret_val;
+     uint16_t phy_data;
+     DEBUGFUNC("e1000_check_downshift");
+     if(hw->phy_type == e1000_phy_igp) {
+-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
++                                         &phy_data)))
++            return ret_val;
++
+         hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
+     }
+     else if(hw->phy_type == e1000_phy_m88) {
+-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+-            DEBUGOUT("PHY Read Error\n");
+-            return -E1000_ERR_PHY;
+-        }
++        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
++                                         &phy_data)))
++            return ret_val;
++
+         hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
+-                                M88E1000_PSSR_DOWNSHIFT_SHIFT;
++                               M88E1000_PSSR_DOWNSHIFT_SHIFT;
+     }
+     return E1000_SUCCESS;
+ }
++/*****************************************************************************
++ *
++ * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
++ * gigabit link is achieved to improve link quality.
++ *
++ * hw: Struct containing variables accessed by shared code
++ *
++ * returns: - E1000_ERR_PHY if fail to read/write the PHY
++ *            E1000_SUCCESS at any other case.
++ *
++ ****************************************************************************/
++
++int32_t
++e1000_config_dsp_after_link_change(struct e1000_hw *hw,
++                                   boolean_t link_up)
++{
++    int32_t ret_val;
++    uint16_t phy_data, speed, duplex, i;
++    uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
++                                        {IGP01E1000_PHY_AGC_PARAM_A,
++                                        IGP01E1000_PHY_AGC_PARAM_B,
++                                        IGP01E1000_PHY_AGC_PARAM_C,
++                                        IGP01E1000_PHY_AGC_PARAM_D};
++    uint16_t min_length, max_length;
++
++    DEBUGFUNC("e1000_config_dsp_after_link_change");
++
++    if(hw->phy_type != e1000_phy_igp)
++        return E1000_SUCCESS;
++
++    if(link_up) {
++        if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) {
++            DEBUGOUT("Error getting link speed and duplex\n");
++            return ret_val;
++        }
++
++        if(speed == SPEED_1000) {
++
++            e1000_get_cable_length(hw, &min_length, &max_length);
++
++            if((hw->dsp_config_state == e1000_dsp_config_enabled) &&
++                min_length >= e1000_igp_cable_length_50) {
++
++                for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
++                    if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
++                                                     &phy_data)))
++                        return ret_val;
++
++                    phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
++
++                    if((ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
++                                                      phy_data)))
++                        return ret_val;
++                }
++                hw->dsp_config_state = e1000_dsp_config_activated;
++            }
++
++            if((hw->ffe_config_state == e1000_ffe_config_enabled) &&
++               (min_length < e1000_igp_cable_length_50)) {
++
++                uint16_t ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
++                uint32_t idle_errs = 0;
++
++                /* clear previous idle error counts */
++                if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
++                                                 &phy_data)))
++                    return ret_val;
++
++                for(i = 0; i < ffe_idle_err_timeout; i++) {
++                    udelay(1000);
++                    if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
++                                                     &phy_data)))
++                        return ret_val;
++
++                    idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
++                    if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
++                        hw->ffe_config_state = e1000_ffe_config_active;
++
++                        if((ret_val = e1000_write_phy_reg(hw,
++                                    IGP01E1000_PHY_DSP_FFE,
++                                    IGP01E1000_PHY_DSP_FFE_CM_CP)))
++                            return ret_val;
++                        break;
++                    }
++
++                    if(idle_errs)
++                        ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100;
++                }
++            }
++        }
++    } else {
++        if(hw->dsp_config_state == e1000_dsp_config_activated) {
++            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++                IGP01E1000_IEEE_FORCE_GIGA)))
++                return ret_val;
++            for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
++                if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
++                                                 &phy_data)))
++                    return ret_val;
++
++                phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
++                phy_data |=  IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
++
++                if((ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i],
++                                                  phy_data)))
++                    return ret_val;
++            }
++
++            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++                                              IGP01E1000_IEEE_RESTART_AUTONEG)))
++                return ret_val;
++
++            hw->dsp_config_state = e1000_dsp_config_enabled;
++        }
++
++        if(hw->ffe_config_state == e1000_ffe_config_active) {
++            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++                                              IGP01E1000_IEEE_FORCE_GIGA)))
++                return ret_val;
++            if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
++                                              IGP01E1000_PHY_DSP_FFE_DEFAULT)))
++                return ret_val;
++
++            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
++                                              IGP01E1000_IEEE_RESTART_AUTONEG)))
++                return ret_val;
++        hw->ffe_config_state = e1000_ffe_config_enabled;
++        }
++    }
++    return E1000_SUCCESS;
++}
++
++/*****************************************************************************
++ *
++ * This function sets the lplu state according to the active flag.  When
++ * activating lplu this function also disables smart speed and vise versa.
++ * lplu will not be activated unless the device autonegotiation advertisment
++ * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
++ * hw: Struct containing variables accessed by shared code
++ * active - true to enable lplu false to disable lplu.
++ *
++ * returns: - E1000_ERR_PHY if fail to read/write the PHY
++ *            E1000_SUCCESS at any other case.
++ *
++ ****************************************************************************/
++
++int32_t
++e1000_set_d3_lplu_state(struct e1000_hw *hw,
++                        boolean_t active)
++{
++    int32_t ret_val;
++    uint16_t phy_data;
++    DEBUGFUNC("e1000_set_d3_lplu_state");
++
++    if(!((hw->mac_type == e1000_82541_rev_2) ||
++         (hw->mac_type == e1000_82547_rev_2)))
++        return E1000_SUCCESS;
++
++    /* During driver activity LPLU should not be used or it will attain link
++     * from the lowest speeds starting from 10Mbps. The capability is used for
++     * Dx transitions and states */
++    if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data)))
++        return ret_val;
++
++    if(!active) {
++        phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
++        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
++            return ret_val;
++
++        /* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
++         * Dx states where the power conservation is most important.  During
++         * driver activity we should enable SmartSpeed, so performance is
++         * maintained. */
++        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++                                         &phy_data)))
++            return ret_val;
++
++        phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
++        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++                                          phy_data)))
++            return ret_val;
++
++    } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
++              (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
++              (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
++
++        phy_data |= IGP01E1000_GMII_FLEX_SPD;
++        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
++            return ret_val;
++
++        /* When LPLU is enabled we should disable SmartSpeed */
++        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++                                         &phy_data)))
++            return ret_val;
++
++        phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
++        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
++                                          phy_data)))
++            return ret_val;
++
++    }
++    return E1000_SUCCESS;
++}
++
++/******************************************************************************
++ * Change VCO speed register to improve Bit Error Rate performance of SERDES.
++ *
++ * hw - Struct containing variables accessed by shared code
++ *****************************************************************************/
++static int32_t
++e1000_set_vco_speed(struct e1000_hw *hw)
++{
++    int32_t  ret_val;
++    uint16_t default_page = 0;
++    uint16_t phy_data;
++
++    DEBUGFUNC("e1000_set_vco_speed");
++
++    switch(hw->mac_type) {
++    case e1000_82545_rev_3:
++    case e1000_82546_rev_3:
++       break;
++    default:
++        return E1000_SUCCESS;
++    }
++
++    /* Set PHY register 30, page 5, bit 8 to 0 */
++
++    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
++                                     &default_page)))
++        return ret_val;
++
++    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005)))
++        return ret_val;
++
++    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
++        return ret_val;
++
++    phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
++    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
++        return ret_val;
++
++    /* Set PHY register 30, page 4, bit 11 to 1 */
++
++    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004)))
++        return ret_val;
++
++    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
++        return ret_val;
++
++    phy_data |= M88E1000_PHY_VCO_REG_BIT11;
++    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
++        return ret_val;
++
++    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
++                                      default_page)))
++        return ret_val;
++
++    return E1000_SUCCESS;
++}
++
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_hw.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_hw.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_hw.h     2003-09-27 11:38:25.283684680 +0800
+@@ -33,9 +33,9 @@
+ #ifndef _E1000_HW_H_
+ #define _E1000_HW_H_
+-
+ #include "e1000_osdep.h"
++
+ /* Forward declarations of structures used by the shared code */
+ struct e1000_hw;
+ struct e1000_hw_stats;
+@@ -50,9 +50,13 @@
+     e1000_82544,
+     e1000_82540,
+     e1000_82545,
++    e1000_82545_rev_3,
+     e1000_82546,
++    e1000_82546_rev_3,
+     e1000_82541,
++    e1000_82541_rev_2,
+     e1000_82547,
++    e1000_82547_rev_2,
+     e1000_num_macs
+ } e1000_mac_type;
+@@ -67,6 +71,7 @@
+ typedef enum {
+     e1000_media_type_copper = 0,
+     e1000_media_type_fiber = 1,
++    e1000_media_type_internal_serdes = 2,
+     e1000_num_media_types
+ } e1000_media_type;
+@@ -90,7 +95,8 @@
+ typedef enum {
+     e1000_bus_type_unknown = 0,
+     e1000_bus_type_pci,
+-    e1000_bus_type_pcix
++    e1000_bus_type_pcix,
++    e1000_bus_type_reserved
+ } e1000_bus_type;
+ /* PCI bus speeds */
+@@ -108,7 +114,8 @@
+ typedef enum {
+     e1000_bus_width_unknown = 0,
+     e1000_bus_width_32,
+-    e1000_bus_width_64
++    e1000_bus_width_64,
++    e1000_bus_width_reserved
+ } e1000_bus_width;
+ /* PHY status info structure and supporting enums */
+@@ -186,6 +193,26 @@
+     e1000_phy_undefined = 0xFF
+ } e1000_phy_type;
++typedef enum {
++    e1000_ms_hw_default = 0,
++    e1000_ms_force_master,
++    e1000_ms_force_slave,
++    e1000_ms_auto
++} e1000_ms_type;
++
++typedef enum {
++    e1000_ffe_config_enabled = 0,
++    e1000_ffe_config_active,
++    e1000_ffe_config_blocked
++} e1000_ffe_config;
++
++typedef enum {
++    e1000_dsp_config_disabled = 0,
++    e1000_dsp_config_enabled,
++    e1000_dsp_config_activated,
++    e1000_dsp_config_undefined = 0xFF
++} e1000_dsp_config;
++
+ struct e1000_phy_info {
+     e1000_cable_length cable_length;
+     e1000_10bt_ext_dist_enable extended_10bt_distance;
+@@ -224,9 +251,10 @@
+ /* Function prototypes */
+ /* Initialization */
+-void e1000_reset_hw(struct e1000_hw *hw);
++int32_t e1000_reset_hw(struct e1000_hw *hw);
+ int32_t e1000_init_hw(struct e1000_hw *hw);
+ int32_t e1000_set_mac_type(struct e1000_hw *hw);
++void e1000_set_media_type(struct e1000_hw *hw);
+ /* Link Configuration */
+ int32_t e1000_setup_link(struct e1000_hw *hw);
+@@ -234,8 +262,9 @@
+ void e1000_config_collision_dist(struct e1000_hw *hw);
+ int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+ int32_t e1000_check_for_link(struct e1000_hw *hw);
+-void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
++int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
+ int32_t e1000_wait_autoneg(struct e1000_hw *hw);
++int32_t e1000_force_mac_fc(struct e1000_hw *hw);
+ /* PHY */
+ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
+@@ -292,6 +321,8 @@
+ uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
+ void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
+ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
++int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
++int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+ #define E1000_READ_REG_IO(a, reg) \
+     e1000_read_reg_io((a), E1000_##reg)
+@@ -313,13 +344,22 @@
+ #define E1000_DEV_ID_82540EP_LP          0x101E
+ #define E1000_DEV_ID_82545EM_COPPER      0x100F
+ #define E1000_DEV_ID_82545EM_FIBER       0x1011
++#define E1000_DEV_ID_82545GM_COPPER      0x1026
++#define E1000_DEV_ID_82545GM_FIBER       0x1027
++#define E1000_DEV_ID_82545GM_SERDES      0x1028
+ #define E1000_DEV_ID_82546EB_COPPER      0x1010
+ #define E1000_DEV_ID_82546EB_FIBER       0x1012
+ #define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
+ #define E1000_DEV_ID_82541EI             0x1013
+-#define E1000_DEV_ID_82541EP             0x1018
++#define E1000_DEV_ID_82541EI_MOBILE      0x1018
++#define E1000_DEV_ID_82541ER             0x1078
++#define E1000_DEV_ID_82547GI             0x1075
++#define E1000_DEV_ID_82541GI             0x1076
++#define E1000_DEV_ID_82541GI_MOBILE      0x1077
++#define E1000_DEV_ID_82546GB_COPPER      0x1079
++#define E1000_DEV_ID_82546GB_FIBER       0x107A
++#define E1000_DEV_ID_82546GB_SERDES      0x107B
+ #define E1000_DEV_ID_82547EI             0x1019
+-#define NUM_DEV_IDS 20
+ #define NODE_ADDRESS_SIZE 6
+ #define ETH_LENGTH_OF_ADDRESS 6
+@@ -385,7 +425,7 @@
+     E1000_IMS_RXSEQ  |    \
+     E1000_IMS_LSC)
+-/* The number of high/low register pairs in the RAR. The RAR (Receive Address
++/* Number of high/low register pairs in the RAR. The RAR (Receive Address
+  * Registers) holds the directed and multicast addresses that we monitor. We
+  * reserve one of these spots for our directed address, allowing us room for
+  * E1000_RAR_ENTRIES - 1 multicast addresses.
+@@ -539,7 +579,7 @@
+     volatile uint32_t high;     /* receive address high */
+ };
+-/* The number of entries in the Multicast Table Array (MTA). */
++/* Number of entries in the Multicast Table Array (MTA). */
+ #define E1000_NUM_MTA_REGISTERS 128
+ /* IPv4 Address Table Entry */
+@@ -599,6 +639,7 @@
+  * A - register array
+  */
+ #define E1000_CTRL     0x00000  /* Device Control - RW */
++#define E1000_CTRL_DUP 0x00004  /* Device Control Duplicate (Shadow) - RW */
+ #define E1000_STATUS   0x00008  /* Device Status - RO */
+ #define E1000_EECD     0x00010  /* EEPROM/Flash Control - RW */
+ #define E1000_EERD     0x00014  /* EEPROM Read - RW */
+@@ -934,6 +975,9 @@
+     e1000_bus_width bus_width;
+     e1000_bus_type bus_type;
+     struct e1000_eeprom_info eeprom;
++    e1000_ms_type master_slave;
++    e1000_ms_type original_master_slave;
++    e1000_ffe_config ffe_config_state;
+     uint32_t io_base;
+     uint32_t phy_id;
+     uint32_t phy_revision;
+@@ -950,6 +994,8 @@
+     uint32_t ledctl_default;
+     uint32_t ledctl_mode1;
+     uint32_t ledctl_mode2;
++    uint16_t phy_spd_default;
++    uint16_t dsp_reset_counter;
+     uint16_t autoneg_advertised;
+     uint16_t pci_cmd_word;
+     uint16_t fc_high_water;
+@@ -974,10 +1020,13 @@
+     uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
+     boolean_t disable_polarity_correction;
+     boolean_t speed_downgraded;
++    e1000_dsp_config dsp_config_state;
+     boolean_t get_link_status;
+     boolean_t tbi_compatibility_en;
+     boolean_t tbi_compatibility_on;
++    boolean_t phy_reset_disable;
+     boolean_t fc_send_xon;
++    boolean_t fc_strict_ieee;
+     boolean_t report_tx_early;
+     boolean_t adaptive_ifs;
+     boolean_t ifs_params_forced;
+@@ -1059,7 +1108,7 @@
+ #define E1000_EECD_PRES      0x00000100 /* EEPROM Present */
+ #define E1000_EECD_SIZE      0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
+ #define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
+-                                       * (0-small, 1-large) */
++                                         * (0-small, 1-large) */
+ #define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
+ #ifndef E1000_EEPROM_GRANT_ATTEMPTS
+ #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
+@@ -1121,22 +1170,22 @@
+ #define E1000_MDIC_ERROR     0x40000000
+ /* LED Control */
+-#define E1000_LEDCTL_LED0_MODE_MASK  0x0000000F
+-#define E1000_LEDCTL_LED0_MODE_SHIFT 0
+-#define E1000_LEDCTL_LED0_IVRT       0x00000040
+-#define E1000_LEDCTL_LED0_BLINK      0x00000080
+-#define E1000_LEDCTL_LED1_MODE_MASK  0x00000F00
+-#define E1000_LEDCTL_LED1_MODE_SHIFT 8
+-#define E1000_LEDCTL_LED1_IVRT       0x00004000
+-#define E1000_LEDCTL_LED1_BLINK      0x00008000
+-#define E1000_LEDCTL_LED2_MODE_MASK  0x000F0000
+-#define E1000_LEDCTL_LED2_MODE_SHIFT 16
+-#define E1000_LEDCTL_LED2_IVRT       0x00400000
+-#define E1000_LEDCTL_LED2_BLINK      0x00800000
+-#define E1000_LEDCTL_LED3_MODE_MASK  0x0F000000
+-#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+-#define E1000_LEDCTL_LED3_IVRT       0x40000000
+-#define E1000_LEDCTL_LED3_BLINK      0x80000000
++#define E1000_LEDCTL_LED0_MODE_MASK       0x0000000F
++#define E1000_LEDCTL_LED0_MODE_SHIFT      0
++#define E1000_LEDCTL_LED0_IVRT            0x00000040
++#define E1000_LEDCTL_LED0_BLINK           0x00000080
++#define E1000_LEDCTL_LED1_MODE_MASK       0x00000F00
++#define E1000_LEDCTL_LED1_MODE_SHIFT      8
++#define E1000_LEDCTL_LED1_IVRT            0x00004000
++#define E1000_LEDCTL_LED1_BLINK           0x00008000
++#define E1000_LEDCTL_LED2_MODE_MASK       0x000F0000
++#define E1000_LEDCTL_LED2_MODE_SHIFT      16
++#define E1000_LEDCTL_LED2_IVRT            0x00400000
++#define E1000_LEDCTL_LED2_BLINK           0x00800000
++#define E1000_LEDCTL_LED3_MODE_MASK       0x0F000000
++#define E1000_LEDCTL_LED3_MODE_SHIFT      24
++#define E1000_LEDCTL_LED3_IVRT            0x40000000
++#define E1000_LEDCTL_LED3_BLINK           0x80000000
+ #define E1000_LEDCTL_MODE_LINK_10_1000  0x0
+ #define E1000_LEDCTL_MODE_LINK_100_1000 0x1
+@@ -1159,109 +1208,109 @@
+ #define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
+ /* Interrupt Cause Read */
+-#define E1000_ICR_TXDW    0x00000001    /* Transmit desc written back */
+-#define E1000_ICR_TXQE    0x00000002    /* Transmit Queue empty */
+-#define E1000_ICR_LSC     0x00000004    /* Link Status Change */
+-#define E1000_ICR_RXSEQ   0x00000008    /* rx sequence error */
+-#define E1000_ICR_RXDMT0  0x00000010    /* rx desc min. threshold (0) */
+-#define E1000_ICR_RXO     0x00000040    /* rx overrun */
+-#define E1000_ICR_RXT0    0x00000080    /* rx timer intr (ring 0) */
+-#define E1000_ICR_MDAC    0x00000200    /* MDIO access complete */
+-#define E1000_ICR_RXCFG   0x00000400    /* RX /c/ ordered set */
+-#define E1000_ICR_GPI_EN0 0x00000800    /* GP Int 0 */
+-#define E1000_ICR_GPI_EN1 0x00001000    /* GP Int 1 */
+-#define E1000_ICR_GPI_EN2 0x00002000    /* GP Int 2 */
+-#define E1000_ICR_GPI_EN3 0x00004000    /* GP Int 3 */
+-#define E1000_ICR_TXD_LOW 0x00008000
+-#define E1000_ICR_SRPD    0x00010000
++#define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
++#define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
++#define E1000_ICR_LSC           0x00000004 /* Link Status Change */
++#define E1000_ICR_RXSEQ         0x00000008 /* rx sequence error */
++#define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
++#define E1000_ICR_RXO           0x00000040 /* rx overrun */
++#define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
++#define E1000_ICR_MDAC          0x00000200 /* MDIO access complete */
++#define E1000_ICR_RXCFG         0x00000400 /* RX /c/ ordered set */
++#define E1000_ICR_GPI_EN0       0x00000800 /* GP Int 0 */
++#define E1000_ICR_GPI_EN1       0x00001000 /* GP Int 1 */
++#define E1000_ICR_GPI_EN2       0x00002000 /* GP Int 2 */
++#define E1000_ICR_GPI_EN3       0x00004000 /* GP Int 3 */
++#define E1000_ICR_TXD_LOW       0x00008000
++#define E1000_ICR_SRPD          0x00010000
+ /* Interrupt Cause Set */
+-#define E1000_ICS_TXDW    E1000_ICR_TXDW        /* Transmit desc written back */
+-#define E1000_ICS_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
+-#define E1000_ICS_LSC     E1000_ICR_LSC         /* Link Status Change */
+-#define E1000_ICS_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
+-#define E1000_ICS_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
+-#define E1000_ICS_RXO     E1000_ICR_RXO         /* rx overrun */
+-#define E1000_ICS_RXT0    E1000_ICR_RXT0        /* rx timer intr */
+-#define E1000_ICS_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
+-#define E1000_ICS_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
+-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
+-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
+-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
+-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
+-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
+-#define E1000_ICS_SRPD    E1000_ICR_SRPD
++#define E1000_ICS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
++#define E1000_ICS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
++#define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
++#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
++#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
++#define E1000_ICS_RXO       E1000_ICR_RXO       /* rx overrun */
++#define E1000_ICS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
++#define E1000_ICS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
++#define E1000_ICS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
++#define E1000_ICS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
++#define E1000_ICS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
++#define E1000_ICS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
++#define E1000_ICS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
++#define E1000_ICS_TXD_LOW   E1000_ICR_TXD_LOW
++#define E1000_ICS_SRPD      E1000_ICR_SRPD
+ /* Interrupt Mask Set */
+-#define E1000_IMS_TXDW    E1000_ICR_TXDW        /* Transmit desc written back */
+-#define E1000_IMS_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
+-#define E1000_IMS_LSC     E1000_ICR_LSC         /* Link Status Change */
+-#define E1000_IMS_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
+-#define E1000_IMS_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
+-#define E1000_IMS_RXO     E1000_ICR_RXO         /* rx overrun */
+-#define E1000_IMS_RXT0    E1000_ICR_RXT0        /* rx timer intr */
+-#define E1000_IMS_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
+-#define E1000_IMS_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
+-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
+-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
+-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
+-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
+-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
+-#define E1000_IMS_SRPD    E1000_ICR_SRPD
++#define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
++#define E1000_IMS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
++#define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
++#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
++#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
++#define E1000_IMS_RXO       E1000_ICR_RXO       /* rx overrun */
++#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
++#define E1000_IMS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
++#define E1000_IMS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
++#define E1000_IMS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
++#define E1000_IMS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
++#define E1000_IMS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
++#define E1000_IMS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
++#define E1000_IMS_TXD_LOW   E1000_ICR_TXD_LOW
++#define E1000_IMS_SRPD      E1000_ICR_SRPD
+ /* Interrupt Mask Clear */
+-#define E1000_IMC_TXDW    E1000_ICR_TXDW        /* Transmit desc written back */
+-#define E1000_IMC_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
+-#define E1000_IMC_LSC     E1000_ICR_LSC         /* Link Status Change */
+-#define E1000_IMC_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
+-#define E1000_IMC_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
+-#define E1000_IMC_RXO     E1000_ICR_RXO         /* rx overrun */
+-#define E1000_IMC_RXT0    E1000_ICR_RXT0        /* rx timer intr */
+-#define E1000_IMC_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
+-#define E1000_IMC_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
+-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
+-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
+-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
+-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
+-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
+-#define E1000_IMC_SRPD    E1000_ICR_SRPD
++#define E1000_IMC_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
++#define E1000_IMC_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
++#define E1000_IMC_LSC       E1000_ICR_LSC       /* Link Status Change */
++#define E1000_IMC_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
++#define E1000_IMC_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
++#define E1000_IMC_RXO       E1000_ICR_RXO       /* rx overrun */
++#define E1000_IMC_RXT0      E1000_ICR_RXT0      /* rx timer intr */
++#define E1000_IMC_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
++#define E1000_IMC_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
++#define E1000_IMC_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
++#define E1000_IMC_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
++#define E1000_IMC_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
++#define E1000_IMC_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
++#define E1000_IMC_TXD_LOW   E1000_ICR_TXD_LOW
++#define E1000_IMC_SRPD      E1000_ICR_SRPD
+ /* Receive Control */
+-#define E1000_RCTL_RST          0x00000001      /* Software reset */
+-#define E1000_RCTL_EN           0x00000002      /* enable */
+-#define E1000_RCTL_SBP          0x00000004      /* store bad packet */
+-#define E1000_RCTL_UPE          0x00000008      /* unicast promiscuous enable */
+-#define E1000_RCTL_MPE          0x00000010      /* multicast promiscuous enab */
+-#define E1000_RCTL_LPE          0x00000020      /* long packet enable */
+-#define E1000_RCTL_LBM_NO       0x00000000      /* no loopback mode */
+-#define E1000_RCTL_LBM_MAC      0x00000040      /* MAC loopback mode */
+-#define E1000_RCTL_LBM_SLP      0x00000080      /* serial link loopback mode */
+-#define E1000_RCTL_LBM_TCVR     0x000000C0      /* tcvr loopback mode */
+-#define E1000_RCTL_RDMTS_HALF   0x00000000      /* rx desc min threshold size */
+-#define E1000_RCTL_RDMTS_QUAT   0x00000100      /* rx desc min threshold size */
+-#define E1000_RCTL_RDMTS_EIGTH  0x00000200      /* rx desc min threshold size */
+-#define E1000_RCTL_MO_SHIFT     12              /* multicast offset shift */
+-#define E1000_RCTL_MO_0         0x00000000      /* multicast offset 11:0 */
+-#define E1000_RCTL_MO_1         0x00001000      /* multicast offset 12:1 */
+-#define E1000_RCTL_MO_2         0x00002000      /* multicast offset 13:2 */
+-#define E1000_RCTL_MO_3         0x00003000      /* multicast offset 15:4 */
+-#define E1000_RCTL_MDR          0x00004000      /* multicast desc ring 0 */
+-#define E1000_RCTL_BAM          0x00008000      /* broadcast enable */
++#define E1000_RCTL_RST            0x00000001    /* Software reset */
++#define E1000_RCTL_EN             0x00000002    /* enable */
++#define E1000_RCTL_SBP            0x00000004    /* store bad packet */
++#define E1000_RCTL_UPE            0x00000008    /* unicast promiscuous enable */
++#define E1000_RCTL_MPE            0x00000010    /* multicast promiscuous enab */
++#define E1000_RCTL_LPE            0x00000020    /* long packet enable */
++#define E1000_RCTL_LBM_NO         0x00000000    /* no loopback mode */
++#define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
++#define E1000_RCTL_LBM_SLP        0x00000080    /* serial link loopback mode */
++#define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
++#define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size */
++#define E1000_RCTL_RDMTS_QUAT     0x00000100    /* rx desc min threshold size */
++#define E1000_RCTL_RDMTS_EIGTH    0x00000200    /* rx desc min threshold size */
++#define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
++#define E1000_RCTL_MO_0           0x00000000    /* multicast offset 11:0 */
++#define E1000_RCTL_MO_1           0x00001000    /* multicast offset 12:1 */
++#define E1000_RCTL_MO_2           0x00002000    /* multicast offset 13:2 */
++#define E1000_RCTL_MO_3           0x00003000    /* multicast offset 15:4 */
++#define E1000_RCTL_MDR            0x00004000    /* multicast desc ring 0 */
++#define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
+ /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+-#define E1000_RCTL_SZ_2048      0x00000000      /* rx buffer size 2048 */
+-#define E1000_RCTL_SZ_1024      0x00010000      /* rx buffer size 1024 */
+-#define E1000_RCTL_SZ_512       0x00020000      /* rx buffer size 512 */
+-#define E1000_RCTL_SZ_256       0x00030000      /* rx buffer size 256 */
++#define E1000_RCTL_SZ_2048        0x00000000    /* rx buffer size 2048 */
++#define E1000_RCTL_SZ_1024        0x00010000    /* rx buffer size 1024 */
++#define E1000_RCTL_SZ_512         0x00020000    /* rx buffer size 512 */
++#define E1000_RCTL_SZ_256         0x00030000    /* rx buffer size 256 */
+ /* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+-#define E1000_RCTL_SZ_16384     0x00010000      /* rx buffer size 16384 */
+-#define E1000_RCTL_SZ_8192      0x00020000      /* rx buffer size 8192 */
+-#define E1000_RCTL_SZ_4096      0x00030000      /* rx buffer size 4096 */
+-#define E1000_RCTL_VFE          0x00040000      /* vlan filter enable */
+-#define E1000_RCTL_CFIEN        0x00080000      /* canonical form enable */
+-#define E1000_RCTL_CFI          0x00100000      /* canonical form indicator */
+-#define E1000_RCTL_DPF          0x00400000      /* discard pause frames */
+-#define E1000_RCTL_PMCF         0x00800000      /* pass MAC control frames */
+-#define E1000_RCTL_BSEX         0x02000000      /* Buffer size extension */
++#define E1000_RCTL_SZ_16384       0x00010000    /* rx buffer size 16384 */
++#define E1000_RCTL_SZ_8192        0x00020000    /* rx buffer size 8192 */
++#define E1000_RCTL_SZ_4096        0x00030000    /* rx buffer size 4096 */
++#define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
++#define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
++#define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
++#define E1000_RCTL_DPF            0x00400000    /* discard pause frames */
++#define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
++#define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
+ /* Receive Descriptor */
+ #define E1000_RDT_DELAY 0x0000ffff      /* Delay timer (1=1024us) */
+@@ -1426,15 +1475,17 @@
+ #define EEPROM_SIZE_128B        0x0000
+ #define EEPROM_SIZE_MASK        0x1C00
+-
+ /* EEPROM Word Offsets */
+-#define EEPROM_COMPAT              0x0003
+-#define EEPROM_ID_LED_SETTINGS     0x0004
+-#define EEPROM_INIT_CONTROL1_REG   0x000A
+-#define EEPROM_INIT_CONTROL2_REG   0x000F
+-#define EEPROM_CFG                 0x0012
+-#define EEPROM_FLASH_VERSION       0x0032
+-#define EEPROM_CHECKSUM_REG        0x003F
++#define EEPROM_COMPAT                 0x0003
++#define EEPROM_ID_LED_SETTINGS        0x0004
++#define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude adjustment. */
++#define EEPROM_INIT_CONTROL1_REG      0x000A
++#define EEPROM_INIT_CONTROL2_REG      0x000F
++#define EEPROM_INIT_CONTROL3_PORT_B   0x0014
++#define EEPROM_INIT_CONTROL3_PORT_A   0x0024
++#define EEPROM_CFG                    0x0012
++#define EEPROM_FLASH_VERSION          0x0032
++#define EEPROM_CHECKSUM_REG           0x003F
+ /* Word definitions for ID LED Settings */
+ #define ID_LED_RESERVED_0000 0x0000
+@@ -1458,6 +1509,9 @@
+ #define IGP_LED3_MODE           0x07000000
++/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
++#define EEPROM_SERDES_AMPLITUDE_MASK  0x000F
++
+ /* Mask bits for fields in Word 0x0a of the EEPROM */
+ #define EEPROM_WORD0A_ILOS   0x0010
+ #define EEPROM_WORD0A_SWDPIO 0x01E0
+@@ -1479,6 +1533,8 @@
+ #define EEPROM_NODE_ADDRESS_BYTE_0 0
+ #define EEPROM_PBA_BYTE_1          8
++#define EEPROM_RESERVED_WORD          0xFFFF
++
+ /* EEPROM Map Sizes (Byte Counts) */
+ #define PBA_SIZE 4
+@@ -1490,7 +1546,7 @@
+ #define E1000_HDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
+ #define E1000_COLD_SHIFT                12
+-/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
++/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+ #define REQ_TX_DESCRIPTOR_MULTIPLE  8
+ #define REQ_RX_DESCRIPTOR_MULTIPLE  8
+@@ -1557,35 +1613,30 @@
+ #define PCIX_STATUS_HI_MMRBC_2K      0x2
+-/* The number of bits that we need to shift right to move the "pause"
+- * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
+- * in the TXCW register
++/* Number of bits required to shift right the "pause" bits from the
++ * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
+  */
+ #define PAUSE_SHIFT 5
+-/* The number of bits that we need to shift left to move the "SWDPIO"
+- * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
+- * in the CTRL register
++/* Number of bits required to shift left the "SWDPIO" bits from the
++ * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
+  */
+ #define SWDPIO_SHIFT 17
+-/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
+- * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
+- * Extended CTRL register.
+- * in the CTRL register
++/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
++ * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
+  */
+ #define SWDPIO__EXT_SHIFT 4
+-/* The number of bits that we need to shift left to move the "ILOS"
+- * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
+- * in the CTRL register
++/* Number of bits required to shift left the "ILOS" bit from the EEPROM
++ * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
+  */
+ #define ILOS_SHIFT  3
+ #define RECEIVE_BUFFER_ALIGN_SIZE  (256)
+-/* The number of milliseconds we wait for auto-negotiation to complete */
++/* Number of milliseconds we wait for auto-negotiation to complete */
+ #define LINK_UP_TIMEOUT             500
+ #define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
+@@ -1668,7 +1719,16 @@
+ #define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */
+ #define M88E1000_RX_ERR_CNTR       0x15  /* Receive Error Counter */
++#define M88E1000_PHY_EXT_CTRL      0x1A  /* PHY extend control register */
++#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
++#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */
++#define M88E1000_PHY_VCO_REG_BIT8  0x100 /* Bits 8 & 11 are adjusted for */
++#define M88E1000_PHY_VCO_REG_BIT11 0x800    /* improved BER performance */
++
+ #define IGP01E1000_IEEE_REGS_PAGE  0x0000
++#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
++#define IGP01E1000_IEEE_FORCE_GIGA      0x0140
++
+ /* IGP01E1000 Specific Registers */
+ #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
+ #define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
+@@ -1684,17 +1744,35 @@
+ #define IGP01E1000_PHY_AGC_C        0x1472
+ #define IGP01E1000_PHY_AGC_D        0x1872
+-/* Number of AGC registers */
+-#define IGP01E1000_PHY_AGC_NUM     4
++/* IGP01E1000 DSP Reset Register */
++#define IGP01E1000_PHY_DSP_RESET   0x1F33
++#define IGP01E1000_PHY_DSP_SET     0x1F71
++#define IGP01E1000_PHY_DSP_FFE     0x1F35
++
++#define IGP01E1000_PHY_CHANNEL_NUM    4
++#define IGP01E1000_PHY_AGC_PARAM_A    0x1171
++#define IGP01E1000_PHY_AGC_PARAM_B    0x1271
++#define IGP01E1000_PHY_AGC_PARAM_C    0x1471
++#define IGP01E1000_PHY_AGC_PARAM_D    0x1871
++
++#define IGP01E1000_PHY_EDAC_MU_INDEX        0xC000
++#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
++
++#define IGP01E1000_PHY_ANALOG_TX_STATE      0x2890
++#define IGP01E1000_PHY_ANALOG_CLASS_A       0x2000
++#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE  0x0004
++#define IGP01E1000_PHY_DSP_FFE_CM_CP        0x0069
++#define IGP01E1000_PHY_DSP_FFE_DEFAULT      0x002A
+ /* IGP01E1000 PCS Initialization register - stores the polarity status when
+  * speed = 1000 Mbps. */
+ #define IGP01E1000_PHY_PCS_INIT_REG  0x00B4
++#define IGP01E1000_PHY_PCS_CTRL_REG  0x00B5
+ #define IGP01E1000_ANALOG_REGS_PAGE  0x20C0
+ #define MAX_PHY_REG_ADDRESS 0x1F        /* 5 bit address bus (0-0x1F) */
+-
++#define MAX_PHY_MULTI_PAGE_REG  0xF     /*Registers that are equal on all pages*/
+ /* PHY Control Register */
+ #define MII_CR_SPEED_SELECT_MSB 0x0040  /* bits 6,13: 10=1000, 01=100, 00=10 */
+ #define MII_CR_COLL_TEST_ENABLE 0x0080  /* Collision test enable */
+@@ -1808,8 +1886,11 @@
+ #define SR_1000T_LOCAL_RX_STATUS  0x2000 /* Local receiver OK */
+ #define SR_1000T_MS_CONFIG_RES    0x4000 /* 1=Local TX is Master, 0=Slave */
+ #define SR_1000T_MS_CONFIG_FAULT  0x8000 /* Master/Slave config fault */
+-#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
+-#define SR_1000T_LOCAL_RX_STATUS_SHIFT  13
++#define SR_1000T_REMOTE_RX_STATUS_SHIFT          12
++#define SR_1000T_LOCAL_RX_STATUS_SHIFT           13
++#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT    5
++#define FFE_IDLE_ERR_COUNT_TIMEOUT_20            20
++#define FFE_IDLE_ERR_COUNT_TIMEOUT_100           100
+ /* Extended Status Register */
+ #define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
+@@ -1901,7 +1982,6 @@
+ #define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */
+ #define M88E1000_EPSCR_TX_CLK_0       0x0000 /* NO  TX_CLK */
+-
+ /* IGP01E1000 Specific Port Config Register - R/W */
+ #define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT  0x0010
+ #define IGP01E1000_PSCFR_PRE_EN                0x0020
+@@ -1952,6 +2032,11 @@
+ #define IGP01E1000_MSE_CHANNEL_B        0x0F00
+ #define IGP01E1000_MSE_CHANNEL_A        0xF000
++/* IGP01E1000 DSP reset macros */
++#define DSP_RESET_ENABLE     0x0
++#define DSP_RESET_DISABLE    0x2
++#define E1000_MAX_DSP_RESETS 10
++
+ /* IGP01E1000 AGC Registers */
+ #define IGP01E1000_AGC_LENGTH_SHIFT 7         /* Coarse - 13:11, Fine - 10:7 */
+@@ -1962,18 +2047,6 @@
+ /* The precision of the length is +/- 10 meters */
+ #define IGP01E1000_AGC_RANGE    10
+-/* IGP cable length table */
+-static const
+-uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
+-    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+-      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
+-      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
+-      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
+-      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
+-      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+-      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+-      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
+-
+ /* IGP01E1000 PCS Initialization register */
+ /* bits 3:6 in the PCS registers stores the channels polarity */
+ #define IGP01E1000_PHY_POLARITY_MASK    0x0078
+@@ -1982,11 +2055,12 @@
+ #define IGP01E1000_GMII_FLEX_SPD               0x10 /* Enable flexible speed
+                                                      * on Link-Up */
+ #define IGP01E1000_GMII_SPD                    0x20 /* Enable SPD */
++
+ /* IGP01E1000 Analog Register */
+-#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS         0x0011
+-#define IGP01E1000_ANALOG_FUSE_STATUS               0x0010
+-#define IGP01E1000_ANALOG_FUSE_CONTROL              0x001C
+-#define IGP01E1000_ANALOG_FUSE_BYPASS               0x001E
++#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS       0x20D1
++#define IGP01E1000_ANALOG_FUSE_STATUS             0x20D0
++#define IGP01E1000_ANALOG_FUSE_CONTROL            0x20DC
++#define IGP01E1000_ANALOG_FUSE_BYPASS             0x20DE
+ #define IGP01E1000_ANALOG_FUSE_POLY_MASK            0xF000
+ #define IGP01E1000_ANALOG_FUSE_FINE_MASK            0x0F80
+@@ -2032,5 +2106,8 @@
+ #define ADVERTISE_1000_HALF 0x0010
+ #define ADVERTISE_1000_FULL 0x0020
+ #define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F  /* Everything but 1000-Half */
++#define AUTONEG_ADVERTISE_10_100_ALL    0x000F /* All 10/100 speeds*/
++#define AUTONEG_ADVERTISE_10_ALL        0x0003 /* 10Mbps Full & Half speeds*/
++
+ #endif /* _E1000_HW_H_ */
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_main.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_main.c   2003-09-27 11:38:25.514649568 +0800
+@@ -30,6 +30,22 @@
+ /* Change Log
+  *
++ * 5.2.16     8/8/03
++ *   o Added support for new controllers: 82545GM, 82546GB, 82541/7_B1
++ *   o Bug fix: reset h/w before first EEPROM read because we don't know
++ *     who may have been messing with the device before we got there.
++ *     [Dave Johnson (ddj -a-t- cascv.brown.edu)]
++ *   o Bug fix: read the correct work from EEPROM to detect programmed
++ *     WoL settings.
++ *   o Bug fix: TSO would hang if space left in FIFO was being miscalculated
++ *     when mss dropped without a correspoding drop in the DMA buffer size.
++ *   o ASF for Fiber nics isn't supported.
++ *   o Bug fix: Workaround added for potential hang with 82544 running in
++ *     PCI-X if send buffer terminates within an evenly-aligned dword.
++ *   o Feature: Add support for ethtool flow control setting.
++ *   o Feature: Add support for ethtool TSO setting.
++ *   o Feature: Increase default Tx Descriptor count to 1024 for >= 82544.
++ *   
+  * 5.1.13     5/28/03
+  *   o Bug fix: request_irq() failure resulted in freeing resources twice!
+  *     [Don Fry (brazilnut@us.ibm.com)]
+@@ -39,18 +55,11 @@
+  *   o Cleanup: s/int/unsigned int/ for descriptor ring indexes.
+  *   
+  * 5.1.11     5/6/03
+- *   o Feature: Added support for 82546EB (Quad-port) hardware.
+- *   o Feature: Added support for Diagnostics through Ethtool.
+- *   o Cleanup: Removed /proc support.
+- *   o Cleanup: Removed proprietary IDIAG interface.
+- *   o Bug fix: TSO bug fixes.
+- *
+- * 5.0.42     3/5/03
+  */
+ char e1000_driver_name[] = "e1000";
+ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+-char e1000_driver_version[] = "5.1.13-k2";
++char e1000_driver_version[] = "5.2.16-k1";
+ char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
+ /* e1000_pci_tbl - PCI Device ID Table
+@@ -71,15 +80,28 @@
+       {0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-      {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-      {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-      {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-      {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       /* required last entry */
+       {0,}
+ };
+@@ -426,6 +448,11 @@
+       if(pci_using_dac)
+               netdev->features |= NETIF_F_HIGHDMA;
++      /* before reading the EEPROM, reset the controller to 
++       * put the device in a known good starting state */
++      
++      e1000_reset_hw(&adapter->hw);
++
+       /* make sure the EEPROM is good */
+       if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
+@@ -457,7 +484,7 @@
+       adapter->phy_info_timer.function = &e1000_update_phy_info;
+       adapter->phy_info_timer.data = (unsigned long) adapter;
+-      INIT_WORK(&adapter->tx_timeout_task, 
++      INIT_WORK(&adapter->tx_timeout_task,
+               (void (*)(void *))e1000_tx_timeout_task, netdev);
+       register_netdev(netdev);
+@@ -476,12 +503,28 @@
+        * enable the ACPI Magic Packet filter
+        */
+-      e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG,1, &eeprom_data);
+-      if((adapter->hw.mac_type >= e1000_82544) &&
+-         (eeprom_data & E1000_EEPROM_APME))
++      switch(adapter->hw.mac_type) {
++      case e1000_82542_rev2_0:
++      case e1000_82542_rev2_1:
++      case e1000_82543:
++              break;
++      case e1000_82546:
++      case e1000_82546_rev_3:
++              if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
++                 && (adapter->hw.media_type == e1000_media_type_copper)) {
++                      e1000_read_eeprom(&adapter->hw,
++                              EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
++                      break;
++              }
++              /* Fall Through */
++      default:
++              e1000_read_eeprom(&adapter->hw,
++                      EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
++              break;
++      }
++      if(eeprom_data & E1000_EEPROM_APME)
+               adapter->wol |= E1000_WUFC_MAG;
+-
+       /* reset the hardware with the new settings */
+       e1000_reset(adapter);
+@@ -516,7 +559,8 @@
+       struct e1000_adapter *adapter = netdev->priv;
+       uint32_t manc;
+-      if(adapter->hw.mac_type >= e1000_82540) {
++      if(adapter->hw.mac_type >= e1000_82540 &&
++         adapter->hw.media_type == e1000_media_type_copper) {
+               manc = E1000_READ_REG(&adapter->hw, MANC);
+               if(manc & E1000_MANC_SMBUS_EN) {
+                       manc |= E1000_MANC_ARP_EN;
+@@ -584,21 +628,13 @@
+       hw->fc_pause_time = E1000_FC_PAUSE_TIME;
+       hw->fc_send_xon = 1;
+-      if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547))
++      if((hw->mac_type == e1000_82541) ||
++         (hw->mac_type == e1000_82547) ||
++         (hw->mac_type == e1000_82541_rev_2) ||
++         (hw->mac_type == e1000_82547_rev_2))
+               hw->phy_init_script = 1;
+-      /* Media type - copper or fiber */
+-
+-      if(hw->mac_type >= e1000_82543) {
+-              uint32_t status = E1000_READ_REG(hw, STATUS);
+-
+-              if(status & E1000_STATUS_TBIMODE)
+-                      hw->media_type = e1000_media_type_fiber;
+-              else
+-                      hw->media_type = e1000_media_type_copper;
+-      } else {
+-              hw->media_type = e1000_media_type_fiber;
+-      }
++      e1000_set_media_type(hw);
+       if(hw->mac_type < e1000_82543)
+               hw->report_tx_early = 0;
+@@ -614,6 +650,7 @@
+       if(hw->media_type == e1000_media_type_copper) {
+               hw->mdix = AUTO_ALL_MODES;
+               hw->disable_polarity_correction = FALSE;
++              hw->master_slave = E1000_MASTER_SLAVE;
+       }
+       atomic_set(&adapter->irq_sem, 1);
+@@ -763,7 +800,8 @@
+               tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+               break;
+       default:
+-              if(adapter->hw.media_type == e1000_media_type_fiber)
++              if(adapter->hw.media_type == e1000_media_type_fiber ||
++                 adapter->hw.media_type == e1000_media_type_internal_serdes)
+                       tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+               else
+                       tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+@@ -798,6 +836,12 @@
+               adapter->txd_cmd |= E1000_TXD_CMD_RS;
+       else
+               adapter->txd_cmd |= E1000_TXD_CMD_RPS;
++
++      /* Cache if we're 82544 running in PCI-X because we'll
++       * need this to apply a workaround later in the send path. */
++      if(adapter->hw.mac_type == e1000_82544 &&
++         adapter->hw.bus_type == e1000_bus_type_pcix)
++              adapter->pcix_82544 = 1;
+ }
+ /**
+@@ -1490,27 +1534,46 @@
+ {
+       struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+       struct e1000_buffer *buffer_info;
+-      int len = skb->len;
++      unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD;
+       unsigned int offset = 0, size, count = 0, i;
+-
+ #ifdef NETIF_F_TSO
+-      unsigned int tso = skb_shinfo(skb)->tso_size;
++      unsigned int mss;
+ #endif
+-      unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
++      unsigned int nr_frags;
+       unsigned int f;
++
++#ifdef NETIF_F_TSO
++      mss = skb_shinfo(skb)->tso_size;
++      /* The controller does a simple calculation to 
++       * make sure there is enough room in the FIFO before
++       * initiating the DMA for each buffer.  The calc is:
++       * 4 = ceil(buffer len/mss).  To make sure we don't
++       * overrun the FIFO, adjust the max buffer len if mss
++       * drops. */
++      if (mss)
++              max_per_txd = min(mss << 2, max_per_txd);
++#endif
++      nr_frags = skb_shinfo(skb)->nr_frags;
+       len -= skb->data_len;
+       i = tx_ring->next_to_use;
+       while(len) {
+               buffer_info = &tx_ring->buffer_info[i];
+-              size = min(len, E1000_MAX_DATA_PER_TXD);
++              size = min(len, max_per_txd);
+ #ifdef NETIF_F_TSO
+               /* Workaround for premature desc write-backs
+                * in TSO mode.  Append 4-byte sentinel desc */
+-              if(tso && !nr_frags && size == len && size > 4)
++              if(mss && !nr_frags && size == len && size > 8)
+                       size -= 4;
+ #endif
++              /* Workaround for potential 82544 hang in PCI-X.  Avoid
++               * terminating buffers within evenly-aligned dwords. */
++              if(adapter->pcix_82544 &&
++                 !((unsigned long)(skb->data + offset + size - 1) & 4) &&
++                 size > 4)
++                      size -= 4;
++
+               buffer_info->length = size;
+               buffer_info->dma =
+                       pci_map_single(adapter->pdev,
+@@ -1530,22 +1593,30 @@
+               frag = &skb_shinfo(skb)->frags[f];
+               len = frag->size;
+-              offset = 0;
++              offset = frag->page_offset;
+               while(len) {
+                       buffer_info = &tx_ring->buffer_info[i];
+-                      size = min(len, E1000_MAX_DATA_PER_TXD);
++                      size = min(len, max_per_txd);
+ #ifdef NETIF_F_TSO
+                       /* Workaround for premature desc write-backs
+                        * in TSO mode.  Append 4-byte sentinel desc */
+-                      if(tso && f == (nr_frags-1) && size == len && size > 4)
++                      if(mss && f == (nr_frags-1) && size == len && size > 8)
+                               size -= 4;
+ #endif
++                      /* Workaround for potential 82544 hang in PCI-X.
++                       * Avoid terminating buffers within evenly-aligned
++                       * dwords. */
++                      if(adapter->pcix_82544 &&
++                         !((unsigned long)(frag->page+offset+size-1) & 4) &&
++                         size > 4)
++                              size -= 4;
++
+                       buffer_info->length = size;
+                       buffer_info->dma =
+                               pci_map_page(adapter->pdev,
+                                       frag->page,
+-                                      frag->page_offset + offset,
++                                      offset,
+                                       size,
+                                       PCI_DMA_TODEVICE);
+                       buffer_info->time_stamp = jiffies;
+@@ -1556,6 +1627,31 @@
+                       if(++i == tx_ring->count) i = 0;
+               }
+       }
++
++      if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) {
++
++              /* There aren't enough descriptors available to queue up
++               * this send, so undo the mapping and abort the send. 
++               * We could have done the check before we mapped the skb,
++               * but because of all the workarounds (above), it's too
++               * difficult to predict how many we're going to need.*/
++              i = first;
++
++              while(count--) {
++                      buffer_info = &tx_ring->buffer_info[i];
++                      if(buffer_info->dma) {
++                              pci_unmap_page(adapter->pdev,
++                                             buffer_info->dma,
++                                             buffer_info->length,
++                                             PCI_DMA_TODEVICE);
++                              buffer_info->dma = 0;
++                      }
++                      if(++i == tx_ring->count) i = 0;
++              }
++
++              return 0;
++      }
++
+       i = (i == 0) ? tx_ring->count - 1 : i - 1;
+       tx_ring->buffer_info[i].skb = skb;
+       tx_ring->buffer_info[first].next_to_watch = i;
+@@ -1650,29 +1746,19 @@
+       return 0;
+ }
+-/* Tx Descriptors needed, worst case */
+-#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \
+-                       (((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
+-#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \
+-      MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
+-
+ static int
+ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+ {
+       struct e1000_adapter *adapter = netdev->priv;
+       unsigned int first;
+       unsigned int tx_flags = 0;
++      int count;
+       if(skb->len <= 0) {
+               dev_kfree_skb_any(skb);
+               return 0;
+       }
+-      if(E1000_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED) {
+-              netif_stop_queue(netdev);
+-              return 1;
+-      }
+-
+       if(adapter->hw.mac_type == e1000_82547) {
+               if(e1000_82547_fifo_workaround(adapter, skb)) {
+                       netif_stop_queue(netdev);
+@@ -1693,7 +1779,12 @@
+       else if(e1000_tx_csum(adapter, skb))
+               tx_flags |= E1000_TX_FLAGS_CSUM;
+-      e1000_tx_queue(adapter, e1000_tx_map(adapter, skb, first), tx_flags);
++      if((count = e1000_tx_map(adapter, skb, first)))
++              e1000_tx_queue(adapter, count, tx_flags);
++      else {
++              netif_stop_queue(netdev);
++              return 1;
++      }
+       netdev->trans_start = jiffies;
+@@ -2001,6 +2092,7 @@
+                  !e1000_clean_tx_irq(adapter))
+                       break;
+ #endif
++
+       return IRQ_HANDLED;
+ }
+@@ -2387,7 +2479,7 @@
+       uint16_t mii_reg;
+       uint16_t spddplx;
+-      if(adapter->hw.media_type == e1000_media_type_fiber)
++      if(adapter->hw.media_type != e1000_media_type_copper)
+               return -EOPNOTSUPP;
+       switch (cmd) {
+@@ -2659,7 +2751,7 @@
+       case SYS_DOWN:
+       case SYS_HALT:
+       case SYS_POWER_OFF:
+-              while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
++              while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
+                       if(pci_dev_driver(pdev) == &e1000_driver)
+                               e1000_suspend(pdev, 3);
+               }
+@@ -2706,7 +2798,8 @@
+                       E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+               }
+-              if(adapter->hw.media_type == e1000_media_type_fiber) {
++              if(adapter->hw.media_type == e1000_media_type_fiber ||
++                 adapter->hw.media_type == e1000_media_type_internal_serdes) {
+                       /* keep the laser running in D3 */
+                       ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+                       ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
+@@ -2726,7 +2819,8 @@
+       pci_save_state(pdev, adapter->pci_state);
+-      if(adapter->hw.mac_type >= e1000_82540) {
++      if(adapter->hw.mac_type >= e1000_82540 &&
++         adapter->hw.media_type == e1000_media_type_copper) {
+               manc = E1000_READ_REG(&adapter->hw, MANC);
+               if(manc & E1000_MANC_SMBUS_EN) {
+                       manc |= E1000_MANC_ARP_EN;
+@@ -2764,7 +2858,8 @@
+       netif_device_attach(netdev);
+-      if(adapter->hw.mac_type >= e1000_82540) {
++      if(adapter->hw.mac_type >= e1000_82540 &&
++         adapter->hw.media_type == e1000_media_type_copper) {
+               manc = E1000_READ_REG(&adapter->hw, MANC);
+               manc &= ~(E1000_MANC_ARP_EN);
+               E1000_WRITE_REG(&adapter->hw, MANC, manc);
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_osdep.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_osdep.h     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_osdep.h  2003-09-27 11:38:25.533646680 +0800
+@@ -55,10 +55,13 @@
+ #define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
+ typedef enum {
++#undef FALSE
+     FALSE = 0,
++#undef TRUE
+     TRUE = 1
+ } boolean_t;
++#undef ASSERT
+ #define ASSERT(x)     if(!(x)) BUG()
+ #define MSGOUT(S, A, B)       printk(KERN_DEBUG S "\n", A, B)
+Index: linux-2.6.0-test5/drivers/net/e1000/e1000_param.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e1000/e1000_param.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e1000/e1000_param.c  2003-09-27 11:38:25.553643640 +0800
+@@ -140,7 +140,7 @@
+  * Valid Range: 0, 1
+  *  - 0 - disables all checksum offload
+  *  - 1 - enables receive IP/TCP/UDP checksum offload
+- *        on 82543 based NICs
++ *        on 82543 and newer -based NICs
+  *
+  * Default Value: 1
+  */
+@@ -458,6 +458,7 @@
+       switch(adapter->hw.media_type) {
+       case e1000_media_type_fiber:
++      case e1000_media_type_internal_serdes:
+               e1000_check_fiber_options(adapter);
+               break;
+       case e1000_media_type_copper:
+@@ -601,7 +602,7 @@
+       switch (speed + dplx) {
+       case 0:
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
+                       printk(KERN_INFO
+                              "Speed and duplex autonegotiation enabled\n");
+@@ -609,14 +610,14 @@
+       case HALF_DUPLEX:
+               printk(KERN_INFO "Half Duplex specified without Speed\n");
+               printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n");
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
+                                                ADVERTISE_100_HALF;
+               break;
+       case FULL_DUPLEX:
+               printk(KERN_INFO "Full Duplex specified without Speed\n");
+               printk(KERN_INFO "Using Autonegotiation at Full Duplex only\n");
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               adapter->hw.autoneg_advertised = ADVERTISE_10_FULL |
+                                                ADVERTISE_100_FULL |
+                                                ADVERTISE_1000_FULL;
+@@ -624,38 +625,38 @@
+       case SPEED_10:
+               printk(KERN_INFO "10 Mbps Speed specified without Duplex\n");
+               printk(KERN_INFO "Using Autonegotiation at 10 Mbps only\n");
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
+                                                ADVERTISE_10_FULL;
+               break;
+       case SPEED_10 + HALF_DUPLEX:
+               printk(KERN_INFO "Forcing to 10 Mbps Half Duplex\n");
+-              adapter->hw.autoneg = 0;
++              adapter->hw.autoneg = adapter->fc_autoneg = 0;
+               adapter->hw.forced_speed_duplex = e1000_10_half;
+               adapter->hw.autoneg_advertised = 0;
+               break;
+       case SPEED_10 + FULL_DUPLEX:
+               printk(KERN_INFO "Forcing to 10 Mbps Full Duplex\n");
+-              adapter->hw.autoneg = 0;
++              adapter->hw.autoneg = adapter->fc_autoneg = 0;
+               adapter->hw.forced_speed_duplex = e1000_10_full;
+               adapter->hw.autoneg_advertised = 0;
+               break;
+       case SPEED_100:
+               printk(KERN_INFO "100 Mbps Speed specified without Duplex\n");
+               printk(KERN_INFO "Using Autonegotiation at 100 Mbps only\n");
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               adapter->hw.autoneg_advertised = ADVERTISE_100_HALF |
+                                                ADVERTISE_100_FULL;
+               break;
+       case SPEED_100 + HALF_DUPLEX:
+               printk(KERN_INFO "Forcing to 100 Mbps Half Duplex\n");
+-              adapter->hw.autoneg = 0;
++              adapter->hw.autoneg = adapter->fc_autoneg = 0;
+               adapter->hw.forced_speed_duplex = e1000_100_half;
+               adapter->hw.autoneg_advertised = 0;
+               break;
+       case SPEED_100 + FULL_DUPLEX:
+               printk(KERN_INFO "Forcing to 100 Mbps Full Duplex\n");
+-              adapter->hw.autoneg = 0;
++              adapter->hw.autoneg = adapter->fc_autoneg = 0;
+               adapter->hw.forced_speed_duplex = e1000_100_full;
+               adapter->hw.autoneg_advertised = 0;
+               break;
+@@ -663,20 +664,20 @@
+               printk(KERN_INFO "1000 Mbps Speed specified without Duplex\n");
+               printk(KERN_INFO
+                      "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+               break;
+       case SPEED_1000 + HALF_DUPLEX:
+               printk(KERN_INFO "Half Duplex is not supported at 1000 Mbps\n");
+               printk(KERN_INFO
+                      "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+               break;
+       case SPEED_1000 + FULL_DUPLEX:
+               printk(KERN_INFO
+                      "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+-              adapter->hw.autoneg = 1;
++              adapter->hw.autoneg = adapter->fc_autoneg = 1;
+               adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+               break;
+       default:
+Index: linux-2.6.0-test5/drivers/net/e100/e100_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/e100/e100_main.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/e100/e100_main.c     2003-09-27 11:38:26.431510184 +0800
+@@ -551,6 +551,15 @@
+       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)
+ {
+@@ -643,7 +652,9 @@
+       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_HW_CSUM |
+                       NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+Index: linux-2.6.0-test5/drivers/net/eepro100.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/eepro100.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/eepro100.c   2003-09-27 11:38:26.452506992 +0800
+@@ -543,6 +543,7 @@
+ 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 @@
+       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 @@
+       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;
+Index: linux-2.6.0-test5/drivers/net/eepro.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/eepro.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/eepro.c      2003-09-27 11:38:26.466504864 +0800
+@@ -897,14 +897,12 @@
+               eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
+               if (request_irq (*irqp, NULL, SA_SHIRQ, "bogus", dev) != EBUSY) {
+-                      unsigned long irq_mask, delay;
++                      unsigned long irq_mask;
+                       /* Twinkle the interrupt, and check if it's seen */
+                       irq_mask = probe_irq_on();
+                       eepro_diag(ioaddr); /* RESET the 82595 */
+-
+-                      delay = jiffies + HZ/50;
+-                      while (time_before(jiffies, delay)) ;
++                      mdelay(20);
+                       if (*irqp == probe_irq_off(irq_mask))  /* It's a good IRQ line */
+                               break;
+Index: linux-2.6.0-test5/drivers/net/es3210.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/es3210.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/es3210.c     2003-09-27 11:38:26.470504256 +0800
+@@ -49,6 +49,7 @@
+       "es3210.c: Driver revision v0.03, 14/09/96\n";
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/ewrk3.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ewrk3.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ewrk3.c      2003-09-27 11:38:26.493500760 +0800
+@@ -564,7 +564,7 @@
+                                                               if (dev->irq < 2) {
+ #ifndef MODULE
+                                                                       u_char irqnum;
+-                                                                      unsigned long irq_mask, delay;
++                                                                      unsigned long irq_mask;
+                       
+                                                                       irq_mask = probe_irq_on();
+@@ -578,8 +578,7 @@
+                                                                       irqnum = irq[((icr & IRQ_SEL) >> 4)];
+-                                                                      delay = jiffies + HZ/50;
+-                                                                      while (time_before(jiffies, delay)) ;
++                                                                      mdelay(20);
+                                                                       dev->irq = probe_irq_off(irq_mask);
+                                                                       if ((dev->irq) && (irqnum == dev->irq)) {
+                                                                               printk(" and uses IRQ%d.\n", dev->irq);
+Index: linux-2.6.0-test5/drivers/net/fc/iph5526.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/fc/iph5526.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/fc/iph5526.c 2003-09-27 11:38:26.530495136 +0800
+@@ -110,7 +110,7 @@
+ #define ALIGNED_ADDR(addr, len) ((((unsigned long)(addr) + (len - 1)) & ~(len - 1)) - (unsigned long)(addr))
+-static struct pci_device_id iph5526_pci_tbl[] __initdata = {
++static struct pci_device_id iph5526_pci_tbl[] = {
+       { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, PCI_ANY_ID, PCI_ANY_ID, },
+       { }                     /* Terminating entry */
+Index: linux-2.6.0-test5/drivers/net/hamachi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamachi.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamachi.c    2003-09-27 11:38:26.548492400 +0800
+@@ -178,7 +178,7 @@
+ #include <asm/unaligned.h>
+ #include <asm/cache.h>
+-static char version[] __initdata =
++static char version[] __devinitdata =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "  Written by Donald Becker\n"
+ KERN_INFO "   Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
+ KERN_INFO "   Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
+@@ -569,7 +569,7 @@
+ static void set_rx_mode(struct net_device *dev);
+-static int __init hamachi_init_one (struct pci_dev *pdev,
++static int __devinit hamachi_init_one (struct pci_dev *pdev,
+                                   const struct pci_device_id *ent)
+ {
+       struct hamachi_private *hmp;
+@@ -794,7 +794,7 @@
+       return ret;
+ }
+-static int __init read_eeprom(long ioaddr, int location)
++static int __devinit read_eeprom(long ioaddr, int location)
+ {
+       int bogus_cnt = 1000;
+Index: linux-2.6.0-test5/drivers/net/hamradio/baycom_par.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/baycom_par.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/baycom_par.c        2003-09-27 11:38:26.553491640 +0800
+@@ -68,7 +68,6 @@
+ /*****************************************************************************/
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_fdx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/baycom_ser_fdx.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_fdx.c    2003-09-27 11:38:26.559490728 +0800
+@@ -71,7 +71,6 @@
+ /*****************************************************************************/
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/ioport.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_hdx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/baycom_ser_hdx.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/baycom_ser_hdx.c    2003-09-27 11:38:26.571488904 +0800
+@@ -61,7 +61,6 @@
+ /*****************************************************************************/
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/ioport.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/bpqether.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/bpqether.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/bpqether.c  2003-09-27 11:38:26.575488296 +0800
+@@ -389,8 +389,6 @@
+       return buf;
+ }
+-#define BPQ_PROC_START ((void *)1)
+-
+ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       int i = 1;
+@@ -399,7 +397,7 @@
+       rcu_read_lock();
+       if (*pos == 0)
+-              return BPQ_PROC_START;
++              return SEQ_START_TOKEN;
+       
+       list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
+               if (i == *pos)
+@@ -414,7 +412,7 @@
+       ++*pos;
+-      if (v == BPQ_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               p = bpq_devices.next;
+       else
+               p = ((struct bpqdev *)v)->bpq_list.next;
+@@ -431,7 +429,7 @@
+ static int bpq_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == BPQ_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, 
+                        "dev   ether      destination        accept from\n");
+       else {
+Index: linux-2.6.0-test5/drivers/net/hamradio/hdlcdrv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/hdlcdrv.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/hdlcdrv.c   2003-09-27 11:38:26.587486472 +0800
+@@ -43,7 +43,6 @@
+ /*****************************************************************************/
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/net.h>
+Index: linux-2.6.0-test5/drivers/net/hamradio/scc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/scc.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/scc.c       2003-09-27 11:38:26.603484040 +0800
+@@ -171,6 +171,7 @@
+ #include <linux/ctype.h>
+ #include <linux/kernel.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <net/ax25.h>
+@@ -202,8 +203,8 @@
+ static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs);
+ static void scc_init_timer(struct scc_channel *scc);
+-static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev);
+-static int scc_net_init(struct net_device *dev);
++static int scc_net_alloc(const char *name, struct scc_channel *scc);
++static void scc_net_setup(struct net_device *dev);
+ static int scc_net_open(struct net_device *dev);
+ static int scc_net_close(struct net_device *dev);
+ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb);
+@@ -235,7 +236,7 @@
+ /* These provide interrupt save 2-step access to the Z8530 registers */
+-static spinlock_t iolock;     /* Guards paired accesses */
++static spinlock_t iolock = SPIN_LOCK_UNLOCKED;        /* Guards paired accesses */
+ static inline unsigned char InReg(io_port port, unsigned char reg)
+ {
+@@ -1512,34 +1513,28 @@
+  * Allocate device structure, err, instance, and register driver
+  */
+-static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev)
++static int scc_net_alloc(const char *name, struct scc_channel *scc)
+ {
++      int err;
+       struct net_device *dev;
+-      if (dev_get(name))
+-      {
+-              printk(KERN_INFO "Z8530drv: device %s already exists.\n", name);
+-              return -EEXIST;
+-      }
+-
+-      if ((scc->dev = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL)
++      dev = alloc_netdev(0, name, scc_net_setup);
++      if (!dev) 
+               return -ENOMEM;
+-      dev = scc->dev;
+-      memset(dev, 0, sizeof(struct net_device));
+-
+-      strcpy(dev->name, name);
+-      dev->priv = (void *) scc;
+-      dev->init = scc_net_init;
+-
++      dev->priv = scc;
++      scc->dev = dev;
+       spin_lock_init(&scc->lock);
+-      
+-      if ((addev? register_netdevice(dev) : register_netdev(dev)) != 0) {
+-              kfree(dev);
+-                return -EIO;
+-        }
+-      SET_MODULE_OWNER(dev);
++      err = register_netdev(dev);
++      if (err) {
++              printk(KERN_ERR "%s: can't register network device (%d)\n", 
++                     name, err);
++              free_netdev(dev);
++              scc->dev = NULL;
++              return err;
++      }
++
+       return 0;
+ }
+@@ -1556,8 +1551,9 @@
+ /* ----> Initialize device <----- */
+-static int scc_net_init(struct net_device *dev)
++static void scc_net_setup(struct net_device *dev)
+ {
++      SET_MODULE_OWNER(dev);
+       dev->tx_queue_len    = 16;      /* should be enough... */
+       dev->open            = scc_net_open;
+@@ -1581,7 +1577,6 @@
+       dev->mtu = AX25_DEF_PACLEN;
+       dev->addr_len = AX25_ADDR_LEN;
+-      return 0;
+ }
+ /* ----> open network device <---- */
+@@ -1719,10 +1714,10 @@
+       struct scc_mem_config memcfg;
+       struct scc_hw_config hwcfg;
+       struct scc_calibrate cal;
++      struct scc_channel *scc;
+       int chan;
+-      unsigned char device_name[10];
++      unsigned char device_name[IFNAMSIZ];
+       void *arg;
+-      struct scc_channel *scc;
+       
+       scc = (struct scc_channel *) dev->priv;
+       arg = (void *) ifr->ifr_data;
+@@ -1828,8 +1823,10 @@
+                               {
+                                       request_region(SCC_Info[2*Nchips+chan].ctrl, 1, "scc ctrl");
+                                       request_region(SCC_Info[2*Nchips+chan].data, 1, "scc data");
+-                                      if (Nchips+chan != 0)
+-                                              scc_net_setup(&SCC_Info[2*Nchips+chan], device_name, 1);
++                                      if (Nchips+chan != 0 &&
++                                          scc_net_alloc(device_name, 
++                                                        &SCC_Info[2*Nchips+chan]))
++                                          return -EINVAL;
+                               }
+                       }
+                       
+@@ -1978,39 +1975,58 @@
+ /* *          dump statistics to /proc/net/z8530drv                 * */
+ /* ******************************************************************** */
++#ifdef CONFIG_PROC_FS
+-static int scc_net_get_info(char *buffer, char **start, off_t offset, int length)
++static inline struct scc_channel *scc_net_seq_idx(loff_t pos)
+ {
+-      struct scc_channel *scc;
+-      struct scc_kiss *kiss;
+-      struct scc_stat *stat;
+-      int len = 0;
+-      off_t pos = 0;
+-      off_t begin = 0;
+       int k;
+-      len += sprintf(buffer, "z8530drv-"VERSION"\n");
+-
+-      if (!Driver_Initialized)
+-      {
+-              len += sprintf(buffer+len, "not initialized\n");
+-              goto done;
++      for (k = 0; k < Nchips*2; ++k) {
++              if (!SCC_Info[k].init) 
++                      continue;
++              if (pos-- == 0)
++                      return &SCC_Info[k];
+       }
++      return NULL;
++}
+-      if (!Nchips)
+-      {
+-              len += sprintf(buffer+len, "chips missing\n");
+-              goto done;
++static void *scc_net_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      return *pos ? scc_net_seq_idx(*pos - 1) : SEQ_START_TOKEN;
++      
++}
++
++static void *scc_net_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      unsigned k;
++      struct scc_channel *scc = v;
++      ++*pos;
++      
++      for (k = (v == SEQ_START_TOKEN) ? 0 : (scc - SCC_Info)+1;
++           k < Nchips*2; ++k) {
++              if (SCC_Info[k].init) 
++                      return &SCC_Info[k];
+       }
++      return NULL;
++}
+-      for (k = 0; k < Nchips*2; k++)
+-      {
+-              scc = &SCC_Info[k];
+-              stat = &scc->stat;
+-              kiss = &scc->kiss;
++static void scc_net_seq_stop(struct seq_file *seq, void *v)
++{
++}
++
++static int scc_net_seq_show(struct seq_file *seq, void *v)
++{
++      if (v == SEQ_START_TOKEN) {
++              seq_puts(seq, "z8530drv-"VERSION"\n");
++      } else if (!Driver_Initialized) {
++              seq_puts(seq, "not initialized\n");
++      } else if (!Nchips) {
++              seq_puts(seq, "chips missing\n");
++      } else {
++              const struct scc_channel *scc = v;
++              const struct scc_stat *stat = &scc->stat;
++              const struct scc_kiss *kiss = &scc->kiss;
+-              if (!scc->init)
+-                      continue;
+               /* dev  data ctrl irq clock brand enh vector special option 
+                *      baud nrz clocksrc softdcd bufsize
+@@ -2021,24 +2037,24 @@
+                *      R ## ## XX ## ## ## ## ## XX ## ## ## ## ## ## ##
+                */
+-              len += sprintf(buffer+len, "%s\t%3.3lx %3.3lx %d %lu %2.2x %d %3.3lx %3.3lx %d\n",
++              seq_printf(seq, "%s\t%3.3lx %3.3lx %d %lu %2.2x %d %3.3lx %3.3lx %d\n",
+                               scc->dev->name,
+                               scc->data, scc->ctrl, scc->irq, scc->clock, scc->brand,
+                               scc->enhanced, Vector_Latch, scc->special,
+                               scc->option);
+-              len += sprintf(buffer+len, "\t%lu %d %d %d %d\n",
++              seq_printf(seq, "\t%lu %d %d %d %d\n",
+                               scc->modem.speed, scc->modem.nrz,
+                               scc->modem.clocksrc, kiss->softdcd,
+                               stat->bufsize);
+-              len += sprintf(buffer+len, "\t%lu %lu %lu %lu\n",
++              seq_printf(seq, "\t%lu %lu %lu %lu\n",
+                               stat->rxints, stat->txints, stat->exints, stat->spints);
+-              len += sprintf(buffer+len, "\t%lu %lu %d / %lu %lu %d / %d %d\n",
++              seq_printf(seq, "\t%lu %lu %d / %lu %lu %d / %d %d\n",
+                               stat->rxframes, stat->rxerrs, stat->rx_over,
+                               stat->txframes, stat->txerrs, stat->tx_under,
+                               stat->nospace,  stat->tx_state);
+ #define K(x) kiss->x
+-              len += sprintf(buffer+len, "\t%d %d %d %d %d %d %d %d %d %d %d %d\n",
++              seq_printf(seq, "\t%d %d %d %d %d %d %d %d %d %d %d %d\n",
+                               K(txdelay), K(persist), K(slottime), K(tailtime),
+                               K(fulldup), K(waittime), K(mintime), K(maxkeyup),
+                               K(idletime), K(maxdefer), K(tx_inhibit), K(group));
+@@ -2047,43 +2063,49 @@
+               {
+                       int reg;
+-              len += sprintf(buffer+len, "\tW ");
++              seq_printf(seq, "\tW ");
+                       for (reg = 0; reg < 16; reg++)
+-                              len += sprintf(buffer+len, "%2.2x ", scc->wreg[reg]);
+-                      len += sprintf(buffer+len, "\n");
++                              seq_printf(seq, "%2.2x ", scc->wreg[reg]);
++                      seq_printf(seq, "\n");
+                       
+-              len += sprintf(buffer+len, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1));
++              seq_printf(seq, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1));
+                       for (reg = 3; reg < 8; reg++)
+-                              len += sprintf(buffer+len, "%2.2x ", InReg(scc->ctrl, reg));
+-                      len += sprintf(buffer+len, "XX ");
++                              seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
++                      seq_printf(seq, "XX ");
+                       for (reg = 9; reg < 16; reg++)
+-                              len += sprintf(buffer+len, "%2.2x ", InReg(scc->ctrl, reg));
+-                      len += sprintf(buffer+len, "\n");
++                              seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg));
++                      seq_printf(seq, "\n");
+               }
+ #endif
+-              len += sprintf(buffer+len, "\n");
+-
+-                pos = begin + len;
+-
+-                if (pos < offset) {
+-                        len   = 0;
+-                        begin = pos;
+-                }
+-
+-                if (pos > offset + length)
+-                        break;
++              seq_putc(seq, '\n');
+       }
+-done:
++        return 0;
++}
+-        *start = buffer + (offset - begin);
+-        len   -= (offset - begin);
++static struct seq_operations scc_net_seq_ops = {
++      .start  = scc_net_seq_start,
++      .next   = scc_net_seq_next,
++      .stop   = scc_net_seq_stop,
++      .show   = scc_net_seq_show,
++};
+-        if (len > length) len = length;
+-        return len;
++static int scc_net_seq_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &scc_net_seq_ops);
+ }
++static struct file_operations scc_net_seq_fops = {
++      .owner   = THIS_MODULE,
++      .open    = scc_net_seq_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = seq_release_private,
++};
++
++#endif /* CONFIG_PROC_FS */
++
+  
+ /* ******************************************************************** */
+ /* *                  Init SCC driver                               * */
+@@ -2091,23 +2113,18 @@
+ static int __init scc_init_driver (void)
+ {
+-      int result;
+-      char devname[10];
++      char devname[IFNAMSIZ];
+       
+       printk(banner);
+       
+-      spin_lock_init(&iolock);
+-      
+       sprintf(devname,"%s0", SCC_DriverName);
+       
+-      result = scc_net_setup(SCC_Info, devname, 0);
+-      if (result)
+-      {
++      if (scc_net_alloc(devname, SCC_Info)) {
+               printk(KERN_ERR "z8530drv: cannot initialize module\n");
+-              return result;
++              return -EIO;
+       }
+-      proc_net_create("z8530drv", 0, scc_net_get_info);
++      proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops);
+       return 0;
+ }
+@@ -2117,11 +2134,12 @@
+       io_port ctrl;
+       int k;
+       struct scc_channel *scc;
++      struct net_device *dev;
+       
+-      if (Nchips == 0)
++      if (Nchips == 0 && (dev = SCC_Info[0].dev)) 
+       {
+-              unregister_netdev(SCC_Info[0].dev);
+-              free_netdev(SCC_Info[0].dev);
++              unregister_netdev(dev);
++              free_netdev(dev);
+       }
+       /* Guard against chip prattle */
+Index: linux-2.6.0-test5/drivers/net/hamradio/yam.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hamradio/yam.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hamradio/yam.c       2003-09-27 11:38:26.618481760 +0800
+@@ -74,7 +74,6 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/drivers/net/hp100.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/hp100.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/hp100.c      2003-09-27 11:38:26.661475224 +0800
+@@ -104,6 +104,7 @@
+ #include <linux/ioport.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
++#include <linux/eisa.h>
+ #include <linux/pci.h>
+ #include <linux/spinlock.h>
+ #include <linux/netdevice.h>
+@@ -284,7 +285,7 @@
+ #define HP100_PCI_IDS_SIZE    (sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))
+-static struct pci_device_id hp100_pci_tbl[] __initdata = {
++static struct pci_device_id hp100_pci_tbl[] = {
+       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
+       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
+       {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID,},
+Index: linux-2.6.0-test5/drivers/net/ibmlana.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ibmlana.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ibmlana.c    2003-09-27 11:38:26.669474008 +0800
+@@ -74,7 +74,6 @@
+  *************************************************************************/
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/errno.h>
+Index: linux-2.6.0-test5/drivers/net/irda/ali-ircc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/ali-ircc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/ali-ircc.c      2003-09-27 11:38:26.685471576 +0800
+@@ -89,7 +89,6 @@
+ static int  ali_ircc_setup(chipio_t *info);
+ static int  ali_ircc_is_receiving(struct ali_ircc_cb *self);
+-static int  ali_ircc_net_init(struct net_device *dev);
+ static int  ali_ircc_net_open(struct net_device *dev);
+ static int  ali_ircc_net_close(struct net_device *dev);
+ static int  ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -255,14 +254,14 @@
+       if ((ali_ircc_setup(info)) == -1)
+               return -1;
+               
+-      /* Allocate new instance of the driver */
+-      self = kmalloc(sizeof(struct ali_ircc_cb), GFP_KERNEL);
+-      if (self == NULL) 
+-      {
++      dev = alloc_netdev(sizeof(*self), "irda%d", irda_device_setup);
++      if (dev == NULL) {
+               ERROR("%s(), can't allocate memory for control block!\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+-      memset(self, 0, sizeof(struct ali_ircc_cb));
++
++      self = dev->priv;
++      self->netdev = dev;
+       spin_lock_init(&self->lock);
+    
+       /* Need to store self somewhere */
+@@ -282,9 +281,8 @@
+       if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) {
+               WARNING("%s(), can't get iobase of 0x%03x\n", __FUNCTION__,
+                       self->io.fir_base);
+-              dev_self[i] = NULL;
+-              kfree(self);
+-              return -ENODEV;
++              err = -ENODEV;
++              goto err_out1;
+       }
+       /* Initialize QoS for this device */
+@@ -307,19 +305,17 @@
+       /* Allocate memory if needed */
+       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+                                             GFP_KERNEL |GFP_DMA); 
+-      if (self->rx_buff.head == NULL) 
+-      {
+-              kfree(self);
+-              return -ENOMEM;
++      if (self->rx_buff.head == NULL) {
++              err = -ENOMEM;
++              goto err_out2;
+       }
+       memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+       
+       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+                                             GFP_KERNEL|GFP_DMA); 
+       if (self->tx_buff.head == NULL) {
+-              kfree(self->rx_buff.head);
+-              kfree(self);
+-              return -ENOMEM;
++              err = -ENOMEM;
++              goto err_out3;
+       }
+       memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+@@ -332,28 +328,21 @@
+       self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+       self->tx_fifo.tail = self->tx_buff.head;
+-      if (!(dev = dev_alloc("irda%d", &err))) {
+-              ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+-              return -ENOMEM;
+-      }
+-
+-      dev->priv = (void *) self;
+-      self->netdev = dev;
+       
++      /* Keep track of module usage */
++      SET_MODULE_OWNER(dev);
++
+       /* Override the network functions we need to use */
+-      dev->init            = ali_ircc_net_init;
+       dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
+       dev->open            = ali_ircc_net_open;
+       dev->stop            = ali_ircc_net_close;
+       dev->do_ioctl        = ali_ircc_net_ioctl;
+       dev->get_stats       = ali_ircc_net_get_stats;
+-      rtnl_lock();
+-      err = register_netdevice(dev);
+-      rtnl_unlock();
++      err = register_netdev(dev);
+       if (err) {
+               ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+-              return -1;
++              goto err_out4;
+       }
+       MESSAGE("IrDA: Registered device %s\n", dev->name);
+@@ -370,6 +359,17 @@
+       IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__);
+       
+       return 0;
++
++ err_out4:
++      kfree(self->tx_buff.head);
++ err_out3:
++      kfree(self->rx_buff.head);
++ err_out2:
++      release_region(self->io.fir_base, self->io.fir_ext);
++ err_out1:
++      dev_self[i] = NULL;
++      free_netdev(dev);
++      return err;
+ }
+@@ -390,8 +390,7 @@
+         iobase = self->io.fir_base;
+       /* Remove netdevice */
+-      if (self->netdev)
+-              unregister_netdev(self->netdev);
++      unregister_netdev(self->netdev);
+       /* Release the PORT that this driver is using */
+       IRDA_DEBUG(4, "%s(), Releasing Region %03x\n", __FUNCTION__, self->io.fir_base);
+@@ -404,7 +403,7 @@
+               kfree(self->rx_buff.head);
+       dev_self[self->index] = NULL;
+-      kfree(self);
++      free_netdev(self->netdev);
+       
+       IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__);
+       
+@@ -1291,29 +1290,6 @@
+ }
+ /*
+- * Function ali_ircc_net_init (dev)
+- *
+- *    Initialize network device
+- *
+- */
+-static int ali_ircc_net_init(struct net_device *dev)
+-{
+-      IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
+-      
+-      /* Keep track of module usage */
+-      SET_MODULE_OWNER(dev);
+-
+-      /* Setup to be a normal IrDA network device driver */
+-      irda_device_setup(dev);
+-
+-      /* Insert overrides below this line! */
+-
+-      IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );       
+-      
+-      return 0;
+-}
+-
+-/*
+  * Function ali_ircc_net_open (dev)
+  *
+  *    Start the device
+Index: linux-2.6.0-test5/drivers/net/irda/donauboe.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/donauboe.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/donauboe.c      2003-09-27 11:38:26.699469448 +0800
+@@ -1396,20 +1396,6 @@
+   return IRQ_HANDLED;
+ }
+-static int
+-toshoboe_net_init (struct net_device *dev)
+-{
+-  IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
+-
+-  /* Keep track of module usage */
+-  SET_MODULE_OWNER(dev);
+-
+-  /* Setup to be a normal IrDA network device driver */
+-  irda_device_setup (dev);
+-
+-  /* Insert overrides below this line! */
+-  return 0;
+-}
+ static int
+ toshoboe_net_open (struct net_device *dev)
+@@ -1589,14 +1575,13 @@
+       self->rx_bufs[i] = NULL;
+     }
+-  if (self->netdev)
+-      unregister_netdev(self->netdev);
++  unregister_netdev(self->netdev);
+   kfree (self->ringbuf);
+   self->ringbuf = NULL;
+   self->ring = NULL;
+-  return;
++  free_netdev(self->netdev);
+ }
+ static int
+@@ -1613,17 +1598,17 @@
+   if ((err=pci_enable_device(pci_dev)))
+     return err;
+-  self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL);
+-
+-  if (self == NULL)
++  dev = alloc_netdev(sizeof (struct toshoboe_cb), "irda%d",
++                   irda_device_setup);
++  if (dev == NULL)
+     {
+       printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
+               "IrDA control block\n");
+       return -ENOMEM;
+     }
+-  memset (self, 0, sizeof (struct toshoboe_cb));
+-
++  self = dev->priv;
++  self->netdev = dev;
+   self->pdev = pci_dev;
+   self->base = pci_resource_start(pci_dev,0);
+@@ -1732,33 +1717,20 @@
+       }
+ #endif
+-  if (!(dev = dev_alloc ("irda%d", &err)))
+-    {
+-      printk (KERN_ERR DRIVER_NAME ": dev_alloc() failed\n");
+-      err = -ENOMEM;
+-      goto freebufs;
+-    }
+-
+-  dev->priv = (void *) self;
+-  self->netdev = dev;
+-
+-  printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
+-
+-  dev->init = toshoboe_net_init;
++  SET_MODULE_OWNER(dev);
+   dev->hard_start_xmit = toshoboe_hard_xmit;
+   dev->open = toshoboe_net_open;
+   dev->stop = toshoboe_net_close;
+   dev->do_ioctl = toshoboe_net_ioctl;
+-  rtnl_lock ();
+-  err = register_netdevice (dev);
+-  rtnl_unlock ();
++  err = register_netdev(dev);
+   if (err)
+     {
+       printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
+       err = -ENOMEM;
+       goto freebufs;
+     }
++  printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
+   pci_set_drvdata(pci_dev,self);
+@@ -1779,7 +1751,7 @@
+   release_region (self->io.fir_base, self->io.fir_ext);
+ freeself:
+-  kfree (self);
++  free_netdev(dev);
+   return err;
+ }
+Index: linux-2.6.0-test5/drivers/net/irda/irda-usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/irda-usb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/irda-usb.c      2003-09-27 11:38:26.713467320 +0800
+@@ -112,7 +112,6 @@
+ static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs);
+ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs);
+ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs);
+-static int irda_usb_net_init(struct net_device *dev);
+ static int irda_usb_net_open(struct net_device *dev);
+ static int irda_usb_net_close(struct net_device *dev);
+ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -901,24 +900,6 @@
+  * be dealt with below...
+  */
+-/*------------------------------------------------------------------*/
+-/*
+- * Callback when a new IrDA device is created.
+- */
+-static int irda_usb_net_init(struct net_device *dev)
+-{
+-      IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
+-      
+-      /* 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;
+-}
+ /*------------------------------------------------------------------*/
+ /*
+@@ -1195,15 +1176,18 @@
+       memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);
+       /* Create a network device for us */
+-      if (!(netdev = dev_alloc("irda%d", &err))) {
+-              ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+-              return -1;
++      netdev = alloc_netdev(0, "irda%d",  irda_device_setup);
++      if (!netdev) {
++              ERROR("%s(), alloc_net_dev() failed!\n", __FUNCTION__);
++              return -ENOMEM;
+       }
++
++      SET_MODULE_OWNER(dev);
++
+       self->netdev = netdev;
+       netdev->priv = (void *) self;
+       /* Override the network functions we need to use */
+-      netdev->init            = irda_usb_net_init;
+       netdev->hard_start_xmit = irda_usb_hard_xmit;
+       netdev->tx_timeout      = irda_usb_net_timeout;
+       netdev->watchdog_timeo  = 250*HZ/1000;  /* 250 ms > USB timeout */
+@@ -1212,12 +1196,12 @@
+       netdev->get_stats       = irda_usb_net_get_stats;
+       netdev->do_ioctl        = irda_usb_net_ioctl;
+-      rtnl_lock();
+-      err = register_netdevice(netdev);
+-      rtnl_unlock();
++      err = register_netdev(netdev);
+       if (err) {
+               ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+-              return -1;
++              self->netdev = NULL;
++              free_netdev(netdev);
++              return err;
+       }
+       MESSAGE("IrDA: Registered device %s\n", netdev->name);
+@@ -1236,9 +1220,11 @@
+       ASSERT(self != NULL, return -1;);
+       /* Remove netdevice */
+-      if (self->netdev)
++      if (self->netdev) {
+               unregister_netdev(self->netdev);
+-      self->netdev = NULL;
++              free_netdev(self->netdev);
++              self->netdev = NULL;
++      }
+       /* Remove the speed buffer */
+       if (self->speed_buff != NULL) {
+Index: linux-2.6.0-test5/drivers/net/irda/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/Kconfig    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/Kconfig 2003-09-27 11:38:26.717466712 +0800
+@@ -254,18 +254,6 @@
+         <file:Documentation/modules.txt>.  The module will be called
+         w83977af_ir.
+-config TOSHIBA_OLD
+-      tristate "Toshiba Type-O IR Port (old driver)"
+-      depends on IRDA && BROKEN_ON_SMP
+-      help
+-        Say Y here if you want to build support for the Toshiba Type-O IR
+-        chipset.  This chipset is used by the Toshiba Libretto 100CT, and
+-        many more laptops. This driver is obsolete, will no more be
+-        maintained and will be removed in favor of the new driver.
+-        If you want to compile it as a module, say M here and read
+-        <file:Documentation/modules.txt>.
+-        The module will be called toshoboe.
+-
+ config TOSHIBA_FIR
+       tristate "Toshiba Type-O IR Port"
+       depends on IRDA
+@@ -281,18 +269,6 @@
+       tristate "Alchemy Au1000 SIR/FIR"
+       depends on MIPS_AU1000 && IRDA
+-config SMC_IRCC_OLD
+-      tristate "SMC IrCC (old driver) (EXPERIMENTAL)"
+-      depends on EXPERIMENTAL && IRDA && ISA
+-      help
+-        Say Y here if you want to build support for the SMC Infrared
+-        Communications Controller.  It is used in the Fujitsu Lifebook 635t
+-        and Sony PCG-505TX.  This driver is obsolete, will no more be
+-        maintained and will be removed in favor of the new driver.
+-        If you want to compile it as a module, say M here and read
+-        <file:Documentation/modules.txt>.  The module will be
+-        called smc-ircc.
+-
+ config SMC_IRCC_FIR
+       tristate "SMSC IrCC (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && IRDA && ISA
+Index: linux-2.6.0-test5/drivers/net/irda/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/Makefile   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/Makefile        2003-09-27 11:38:26.719466408 +0800
+@@ -12,9 +12,7 @@
+ obj-$(CONFIG_NSC_FIR)         += nsc-ircc.o
+ obj-$(CONFIG_WINBOND_FIR)     += w83977af_ir.o
+ obj-$(CONFIG_SA1100_FIR)      += sa1100_ir.o
+-obj-$(CONFIG_TOSHIBA_OLD)     += toshoboe.o
+ obj-$(CONFIG_TOSHIBA_FIR)     += donauboe.o
+-obj-$(CONFIG_SMC_IRCC_OLD)    += smc-ircc.o   irport.o
+ obj-$(CONFIG_SMC_IRCC_FIR)    += smsc-ircc2.o
+ obj-$(CONFIG_ALI_FIR)         += ali-ircc.o
+ obj-$(CONFIG_VLSI_FIR)                += vlsi_ir.o
+Index: linux-2.6.0-test5/drivers/net/irda/nsc-ircc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/nsc-ircc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/nsc-ircc.c      2003-09-27 11:38:26.734464128 +0800
+@@ -143,7 +143,6 @@
+ static int  nsc_ircc_read_dongle_id (int iobase);
+ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id);
+-static int  nsc_ircc_net_init(struct net_device *dev);
+ static int  nsc_ircc_net_open(struct net_device *dev);
+ static int  nsc_ircc_net_close(struct net_device *dev);
+ static int  nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -261,14 +260,16 @@
+       MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);
+-      /* Allocate new instance of the driver */
+-      self = kmalloc(sizeof(struct nsc_ircc_cb), GFP_KERNEL);
+-      if (self == NULL) {
++      dev = alloc_netdev(sizeof(struct nsc_ircc_cb), "irda%d",
++                         irda_device_setup);
++      if (dev == NULL) {
+               ERROR("%s(), can't allocate memory for "
+                      "control block!\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+-      memset(self, 0, sizeof(struct nsc_ircc_cb));
++
++      self = dev->priv;
++      self->netdev = dev;
+       spin_lock_init(&self->lock);
+    
+       /* Need to store self somewhere */
+@@ -288,9 +289,8 @@
+       if (!ret) {
+               WARNING("%s(), can't get iobase of 0x%03x\n",
+                       __FUNCTION__, self->io.fir_base);
+-              dev_self[i] = NULL;
+-              kfree(self);
+-              return -ENODEV;
++              err = -ENODEV;
++              goto out1;
+       }
+       /* Initialize QoS for this device */
+@@ -313,17 +313,17 @@
+       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->rx_buff.head == NULL) {
+-              kfree(self);
+-              return -ENOMEM;
++              err = -ENOMEM;
++              goto out2;
++
+       }
+       memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+       
+       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->tx_buff.head == NULL) {
+-              kfree(self->rx_buff.head);
+-              kfree(self);
+-              return -ENOMEM;
++              err = -ENOMEM;
++              goto out3;
+       }
+       memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+@@ -336,28 +336,18 @@
+       self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+       self->tx_fifo.tail = self->tx_buff.head;
+-      if (!(dev = dev_alloc("irda%d", &err))) {
+-              ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+-              return -ENOMEM;
+-      }
+-
+-      dev->priv = (void *) self;
+-      self->netdev = dev;
+-
+       /* Override the network functions we need to use */
+-      dev->init            = nsc_ircc_net_init;
++      SET_MODULE_OWNER(dev);
+       dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
+       dev->open            = nsc_ircc_net_open;
+       dev->stop            = nsc_ircc_net_close;
+       dev->do_ioctl        = nsc_ircc_net_ioctl;
+       dev->get_stats       = nsc_ircc_net_get_stats;
+-      rtnl_lock();
+-      err = register_netdevice(dev);
+-      rtnl_unlock();
++      err = register_netdev(dev);
+       if (err) {
+               ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+-              return -1;
++              goto out4;
+       }
+       MESSAGE("IrDA: Registered device %s\n", dev->name);
+@@ -380,6 +370,16 @@
+                 pmdev->data = self;
+       return 0;
++ out4:
++      kfree(self->tx_buff.head);
++ out3:
++      kfree(self->rx_buff.head);
++ out2:
++      release_region(self->io.fir_base, self->io.fir_ext);
++ out1:
++      free_netdev(dev);
++      dev_self[i] = NULL;
++      return err;
+ }
+ /*
+@@ -399,8 +399,7 @@
+         iobase = self->io.fir_base;
+       /* Remove netdevice */
+-      if (self->netdev)
+-              unregister_netdev(self->netdev);
++      unregister_netdev(self->netdev);
+       /* Release the PORT that this driver is using */
+       IRDA_DEBUG(4, "%s(), Releasing Region %03x\n", 
+@@ -414,7 +413,7 @@
+               kfree(self->rx_buff.head);
+       dev_self[self->index] = NULL;
+-      kfree(self);
++      free_netdev(self->netdev);
+       
+       return 0;
+ }
+@@ -1991,27 +1990,6 @@
+ }
+ /*
+- * Function nsc_ircc_net_init (dev)
+- *
+- *    Initialize network device
+- *
+- */
+-static int nsc_ircc_net_init(struct net_device *dev)
+-{
+-      IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+-
+-      /* Keep track of module usage */
+-      SET_MODULE_OWNER(dev);
+-
+-      /* Setup to be a normal IrDA network device driver */
+-      irda_device_setup(dev);
+-
+-      /* Insert overrides below this line! */
+-
+-      return 0;
+-}
+-
+-/*
+  * Function nsc_ircc_net_open (dev)
+  *
+  *    Start the device
+Index: linux-2.6.0-test5/drivers/net/irda/sir_kthread.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/sir_kthread.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/sir_kthread.c   2003-09-27 11:38:26.738463520 +0800
+@@ -132,7 +132,7 @@
+               if (list_empty(&irda_rq_queue.request_list))
+                       schedule();
+               else
+-                      set_task_state(current, TASK_RUNNING);
++                      __set_task_state(current, TASK_RUNNING);
+               remove_wait_queue(&irda_rq_queue.kick, &wait);
+               /* make swsusp happy with our thread */
+@@ -165,7 +165,7 @@
+               if (atomic_read(&irda_rq_queue.num_pending))
+                       schedule();
+               else
+-                      set_task_state(current, TASK_RUNNING);
++                      __set_task_state(current, TASK_RUNNING);
+               remove_wait_queue(&irda_rq_queue.done, &wait);
+       }
+ }
+Index: linux-2.6.0-test5/drivers/net/irda/via-ircc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/via-ircc.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/via-ircc.c      2003-09-27 11:38:26.749461848 +0800
+@@ -94,7 +94,6 @@
+ static int via_ircc_is_receiving(struct via_ircc_cb *self);
+ static int via_ircc_read_dongle_id(int iobase);
+-static int via_ircc_net_init(struct net_device *dev);
+ static int via_ircc_net_open(struct net_device *dev);
+ static int via_ircc_net_close(struct net_device *dev);
+ static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq,
+@@ -107,7 +106,7 @@
+ void hwreset(struct via_ircc_cb *self);
+ static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase);
+ static int upload_rxdata(struct via_ircc_cb *self, int iobase);
+-static int __init via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id);
++static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id);
+ static void __exit via_remove_one (struct pci_dev *pdev);
+ /* Should use udelay() instead, even if we are x86 only - Jean II */
+@@ -121,7 +120,7 @@
+       }
+ }
+-static struct pci_device_id via_pci_tbl[] __initdata = {
++static struct pci_device_id via_pci_tbl[] = {
+       { PCI_VENDOR_ID_VIA, DeviceID1, PCI_ANY_ID, PCI_ANY_ID,0,0,0 },
+       { PCI_VENDOR_ID_VIA, DeviceID2, PCI_ANY_ID, PCI_ANY_ID,0,0,1 },
+       { PCI_VENDOR_ID_VIA, DeviceID3, PCI_ANY_ID, PCI_ANY_ID,0,0,2 },
+@@ -168,7 +167,7 @@
+ }
+-static int __init via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id)
++static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id)
+ {
+       int rc;
+         u8 temp,oldPCI_40,oldPCI_44,bTmp,bTmp1;
+@@ -326,22 +325,23 @@
+  *    Open driver instance
+  *
+  */
+-static __init int via_ircc_open(int i, chipio_t * info, unsigned int id)
++static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
+ {
+       struct net_device *dev;
+       struct via_ircc_cb *self;
+-      int ret;
+       int err;
+       if ((via_ircc_setup(info, id)) == -1)
+               return -1;
+       /* Allocate new instance of the driver */
+-      self = kmalloc(sizeof(struct via_ircc_cb), GFP_KERNEL);
+-      if (self == NULL) {
++      dev = alloc_netdev(sizeof(struct via_ircc_cb), "irda%d",
++                         irda_device_setup);
++      if (dev == NULL) 
+               return -ENOMEM;
+-      }
+-      memset(self, 0, sizeof(struct via_ircc_cb));
++
++      self = dev->priv;
++      self->netdev = dev;
+       spin_lock_init(&self->lock);
+       /* Need to store self somewhere */
+@@ -360,14 +360,12 @@
+       self->RxDataReady = 0;
+       /* Reserve the ioports that we need */
+-      ret = check_region(self->io.fir_base, self->io.fir_ext);
+-      if (ret < 0) {
++      if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) {
+ //              WARNING(__FUNCTION__ "(), can't get iobase of 0x%03x\n",self->io.fir_base);
+-              dev_self[i] = NULL;
+-              kfree(self);
+-              return -ENODEV;
++              err = -ENODEV;
++              goto err_out1;
+       }
+-      request_region(self->io.fir_base, self->io.fir_ext, driver_name);
++      
+       /* Initialize QoS for this device */
+       irda_init_max_qos_capabilies(&self->qos);
+       /* The only value we must override it the baudrate */
+@@ -391,17 +389,16 @@
+       self->rx_buff.head =
+           (__u8 *) kmalloc(self->rx_buff.truesize, GFP_KERNEL | GFP_DMA);
+       if (self->rx_buff.head == NULL) {
+-              kfree(self);
+-              return -ENOMEM;
++              err = -ENOMEM;
++              goto err_out2;
+       }
+       memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+       self->tx_buff.head =
+           (__u8 *) kmalloc(self->tx_buff.truesize, GFP_KERNEL | GFP_DMA);
+       if (self->tx_buff.head == NULL) {
+-              kfree(self->rx_buff.head);
+-              kfree(self);
+-              return -ENOMEM;
++              err = -ENOMEM;
++              goto err_out3;
+       }
+       memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+@@ -414,30 +411,20 @@
+       self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+       self->tx_fifo.tail = self->tx_buff.head;
+-      if (!(dev = dev_alloc("irda%d", &err))) {
+-              kfree(self->tx_buff.head);
+-              kfree(self->rx_buff.head);
+-              kfree(self);
+-              return -ENOMEM;
+-      }
+-
+-      dev->priv = (void *) self;
+-      self->netdev = dev;
++      /* Keep track of module usage */
++      SET_MODULE_OWNER(dev);
+       /* Override the network functions we need to use */
+-      dev->init = via_ircc_net_init;
+       dev->hard_start_xmit = via_ircc_hard_xmit_sir;
+       dev->open = via_ircc_net_open;
+       dev->stop = via_ircc_net_close;
+       dev->do_ioctl = via_ircc_net_ioctl;
+       dev->get_stats = via_ircc_net_get_stats;
+-      rtnl_lock();
+-      err = register_netdevice(dev);
+-      rtnl_unlock();
+-      if (err) {
+-              return -1;
+-      }
++      err = register_netdev(dev);
++      if (err)
++              goto err_out4;
++
+       MESSAGE("IrDA: Registered device %s\n", dev->name);
+       /* Check if user has supplied the dongle id or not */
+@@ -448,6 +435,16 @@
+                                    self->io.dongle_id);
+       return 0;
++ err_out4:
++      kfree(self->tx_buff.head);
++ err_out3:
++      kfree(self->rx_buff.head);
++ err_out2:
++      release_region(self->io.fir_base, self->io.fir_ext);
++ err_out1:
++      free_netdev(dev);
++      dev_self[i] = NULL;
++      return err;
+ }
+ /*
+@@ -468,11 +465,7 @@
+       ResetChip(iobase, 5);   //hardware reset.
+       /* Remove netdevice */
+-      if (self->netdev) {
+-              rtnl_lock();
+-              unregister_netdevice(self->netdev);
+-              rtnl_unlock();
+-      }
++      unregister_netdev(self->netdev);
+       /* Release the PORT that this driver is using */
+       IRDA_DEBUG(4, "%s(), Releasing Region %03x\n",
+@@ -483,7 +476,8 @@
+       if (self->rx_buff.head)
+               kfree(self->rx_buff.head);
+       dev_self[self->index] = NULL;
+-      kfree(self);
++
++      free_netdev(self->netdev);
+       return 0;
+ }
+@@ -1456,26 +1450,6 @@
+       return status;
+ }
+-/*
+- * Function via_ircc_net_init (dev)
+- *
+- *    Initialize network device
+- *
+- */
+-static int via_ircc_net_init(struct net_device *dev)
+-{
+-      IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+-
+-      /* Keep track of module usage */
+-      SET_MODULE_OWNER(dev);
+-
+-      /* Setup to be a normal IrDA network device driver */
+-      irda_device_setup(dev);
+-
+-      /* Insert overrides below this line! */
+-
+-      return 0;
+-}
+ /*
+  * Function via_ircc_net_open (dev)
+Index: linux-2.6.0-test5/drivers/net/irda/w83977af_ir.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/irda/w83977af_ir.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/irda/w83977af_ir.c   2003-09-27 11:38:26.758460480 +0800
+@@ -99,7 +99,6 @@
+ static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed);
+ static int  w83977af_is_receiving(struct w83977af_ir *self);
+-static int  w83977af_net_init(struct net_device *dev);
+ static int  w83977af_net_open(struct net_device *dev);
+ static int  w83977af_net_close(struct net_device *dev);
+ static int  w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -171,14 +170,16 @@
+       /*
+        *  Allocate new instance of the driver
+        */
+-      self = kmalloc(sizeof(struct w83977af_ir), GFP_KERNEL);
+-      if (self == NULL) {
++      dev = alloc_netdev(sizeof(struct w83977af_ir), "irda%d",
++                         irda_device_setup);
++      if (dev == NULL) {
+               printk( KERN_ERR "IrDA: Can't allocate memory for "
+                       "IrDA control block!\n");
+               err = -ENOMEM;
+               goto err_out;
+       }
+-      memset(self, 0, sizeof(struct w83977af_ir));
++
++      self = dev->priv;
+       spin_lock_init(&self->lock);
+    
+@@ -230,29 +231,21 @@
+       self->rx_buff.state = OUTSIDE_FRAME;
+       self->tx_buff.data = self->tx_buff.head;
+       self->rx_buff.data = self->rx_buff.head;
+-      
+-      if (!(dev = dev_alloc("irda%d", &err))) {
+-              ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+-              err = -ENOMEM;
+-              goto err_out3;
+-      }
+-      dev->priv = (void *) self;
+       self->netdev = dev;
++      /* Keep track of module usage */
++      SET_MODULE_OWNER(dev);
++
+       /* Override the network functions we need to use */
+-      dev->init            = w83977af_net_init;
+       dev->hard_start_xmit = w83977af_hard_xmit;
+       dev->open            = w83977af_net_open;
+       dev->stop            = w83977af_net_close;
+       dev->do_ioctl        = w83977af_net_ioctl;
+       dev->get_stats       = w83977af_net_get_stats;
+-      rtnl_lock();
+-      err = register_netdevice(dev);
+-      rtnl_unlock();
++      err = register_netdev(dev);
+       if (err) {
+               ERROR("%s(), register_netdevice() failed!\n", __FUNCTION__);
+-              err = -1;
+               goto err_out3;
+       }
+       MESSAGE("IrDA: Registered device %s\n", dev->name);
+@@ -266,7 +259,7 @@
+ err_out2:     
+       kfree(self->rx_buff.head);
+ err_out1:
+-      kfree(self);
++      free_netdev(dev);
+ err_out:
+       release_region(iobase, CHIP_IO_EXTENT);
+       return err;
+@@ -299,8 +292,7 @@
+ #endif /* CONFIG_USE_W977_PNP */
+       /* Remove netdevice */
+-      if (self->netdev)
+-              unregister_netdev(self->netdev);
++      unregister_netdev(self->netdev);
+       /* Release the PORT that this driver is using */
+       IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n", 
+@@ -313,7 +305,7 @@
+       if (self->rx_buff.head)
+               kfree(self->rx_buff.head);
+-      kfree(self);
++      free_netdev(self->netdev);
+       return 0;
+ }
+@@ -1187,28 +1179,6 @@
+ }
+ /*
+- * Function w83977af_net_init (dev)
+- *
+- *    
+- *
+- */
+-static int w83977af_net_init(struct net_device *dev)
+-{
+-      IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
+-
+-      /* 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 w83977af_net_open (dev)
+  *
+  *    Start the device
+Index: linux-2.6.0-test5/drivers/net/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Kconfig      2003-09-27 11:38:26.785456376 +0800
+@@ -2715,6 +2715,9 @@
+         module, say M here and read <file:Documentation/modules.txt>.  If
+         unsure, say N.
++config NET_POLL_CONTROLLER
++      def_bool KGDB
++
+ source "drivers/net/wan/Kconfig"
+ source "drivers/net/pcmcia/Kconfig"
+Index: linux-2.6.0-test5/drivers/net/kgdb_eth.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/kgdb_eth.c      2003-09-27 11:38:18.455722688 +0800
++++ linux-2.6.0-test5/drivers/net/kgdb_eth.c   2003-09-27 11:38:26.787456072 +0800
+@@ -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);
+Index: linux-2.6.0-test5/drivers/net/lance.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/lance.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/lance.c      2003-09-27 11:38:26.797454552 +0800
+@@ -543,7 +543,7 @@
+       if (dev->irq >= 2)
+               printk(" assigned IRQ %d", dev->irq);
+       else if (lance_version != 0)  { /* 7990 boards need DMA detection first. */
+-              unsigned long irq_mask, delay;
++              unsigned long irq_mask;
+               /* To auto-IRQ we enable the initialization-done and DMA error
+                  interrupts. For ISA boards we get a DMA error, but VLB and PCI
+@@ -553,8 +553,7 @@
+               /* Trigger an initialization just for the interrupt. */
+               outw(0x0041, ioaddr+LANCE_DATA);
+-              delay = jiffies + HZ/50;
+-              while (time_before(jiffies, delay)) ;
++              mdelay(20);
+               dev->irq = probe_irq_off(irq_mask);
+               if (dev->irq)
+                       printk(", probed IRQ %d", dev->irq);
+@@ -621,13 +620,12 @@
+       if (lance_version == 0 && dev->irq == 0) {
+               /* We may auto-IRQ now that we have a DMA channel. */
+               /* Trigger an initialization just for the interrupt. */
+-              unsigned long irq_mask, delay;
++              unsigned long irq_mask;
+               irq_mask = probe_irq_on();
+               outw(0x0041, ioaddr+LANCE_DATA);
+-              delay = jiffies + HZ/25;
+-              while (time_before(jiffies, delay)) ;
++              mdelay(40);
+               dev->irq = probe_irq_off(irq_mask);
+               if (dev->irq == 0) {
+                       printk("  Failed to detect the 7990 IRQ line.\n");
+Index: linux-2.6.0-test5/drivers/net/lne390.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/lne390.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/lne390.c     2003-09-27 11:38:26.812452272 +0800
+@@ -35,6 +35,7 @@
+       "lne390.c: Driver revision v0.99.1, 01/09/2000\n";
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/mace.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/mace.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/mace.c       2003-09-27 11:38:26.819451208 +0800
+@@ -7,7 +7,6 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+Index: linux-2.6.0-test5/drivers/net/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Makefile        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Makefile     2003-09-27 11:38:26.821450904 +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-test5/drivers/net/ne2.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ne2.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ne2.c        2003-09-27 11:38:26.828449840 +0800
+@@ -60,7 +60,6 @@
+ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.org>\n";
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+Index: linux-2.6.0-test5/drivers/net/ne3210.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ne3210.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ne3210.c     2003-09-27 11:38:26.836448624 +0800
+@@ -29,6 +29,7 @@
+       "ne3210.c: Driver revision v0.03, 30/09/98\n";
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/net_init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/net_init.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/net_init.c   2003-09-27 11:38:26.841447864 +0800
+@@ -381,7 +381,7 @@
+       dev->hard_header_len    = ETH_HLEN;
+       dev->mtu                = 1500; /* eth_mtu */
+       dev->addr_len           = ETH_ALEN;
+-      dev->tx_queue_len       = 100;  /* Ethernet wants good queues */        
++      dev->tx_queue_len       = 1000; /* Ethernet wants good queues */        
+       
+       memset(dev->broadcast,0xFF, ETH_ALEN);
+Index: linux-2.6.0-test5/drivers/net/ni5010.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ni5010.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ni5010.c     2003-09-27 11:38:26.848446800 +0800
+@@ -255,14 +255,13 @@
+       if (dev->irq == 0xff)
+               ;
+       else if (dev->irq < 2) {
+-              unsigned long irq_mask, delay;
++              unsigned long irq_mask;
+               PRINTK2((KERN_DEBUG "%s: I/O #5 passed!\n", dev->name));
+               irq_mask = probe_irq_on();
+               trigger_irq(ioaddr);
+-              delay = jiffies + HZ/50;
+-              while (time_before(jiffies, delay)) ;
++              mdelay(20);
+               dev->irq = probe_irq_off(irq_mask);
+               PRINTK2((KERN_DEBUG "%s: I/O #6 passed!\n", dev->name));
+Index: linux-2.6.0-test5/drivers/net/ni52.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ni52.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ni52.c       2003-09-27 11:38:26.858445280 +0800
+@@ -492,14 +492,13 @@
+       if(dev->irq < 2)
+       {
+-              unsigned long irq_mask, delay;
++              unsigned long irq_mask;
+               irq_mask = probe_irq_on();
+               ni_reset586();
+               ni_attn586();
+-              delay = jiffies + HZ/50;
+-              while (time_before(jiffies, delay)) ;
++              mdelay(20);
+               dev->irq = probe_irq_off(irq_mask);
+               if(!dev->irq)
+               {
+Index: linux-2.6.0-test5/drivers/net/ni65.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ni65.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ni65.c       2003-09-27 11:38:26.866444064 +0800
+@@ -72,7 +72,6 @@
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <asm/bitops.h>
+Index: linux-2.6.0-test5/drivers/net/ns83820.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ns83820.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ns83820.c    2003-09-27 11:38:26.881441784 +0800
+@@ -1833,13 +1833,13 @@
+       if (err) {
+               printk(KERN_INFO "ns83820: unable to register irq %d\n",
+                       pci_dev->irq);
+-              goto out_unmap;
++              goto out_disable;
+       }
+       err = register_netdev(&dev->net_dev);
+       if (err) {
+               printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err);
+-              goto out_unmap;
++              goto out_free_irq;
+       }
+       printk("%s: ns83820.c: 0x22c: %08x, subsystem: %04x:%04x\n",
+@@ -2025,9 +2025,11 @@
+       return 0;
+-out_unmap:
+-      iounmap(dev->base);
++out_free_irq:
++      free_irq(pci_dev->irq, dev);
+ out_disable:
++      if (dev->base)
++              iounmap(dev->base);
+       pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_TX_DESC, dev->tx_descs, dev->tx_phy_descs);
+       pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_RX_DESC, dev->rx_info.descs, dev->rx_info.phy_descs);
+       pci_disable_device(pci_dev);
+Index: linux-2.6.0-test5/drivers/net/pcmcia/3c574_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/3c574_cs.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/3c574_cs.c    2003-09-27 11:38:26.891440264 +0800
+@@ -263,16 +263,6 @@
+ static dev_link_t *dev_list;
+-static void flush_stale_links(void)
+-{
+-      dev_link_t *link, *next;
+-      for (link = dev_list; link; link = next) {
+-              next = link->next;
+-              if (link->state & DEV_STALE_LINK)
+-                      tc574_detach(link);
+-      }
+-}
+-
+ /*
+       tc574_attach() creates an "instance" of the driver, allocating
+       local data structures for one device.  The device is registered
+@@ -288,7 +278,6 @@
+       int i, ret;
+       DEBUG(0, "3c574_attach()\n");
+-      flush_stale_links();
+       /* Create the PC card device object. */
+       dev = alloc_etherdev(sizeof(struct el3_private));
+@@ -375,10 +364,8 @@
+       if (link->state & DEV_CONFIG) {
+               tc574_release(link);
+-              if (link->state & DEV_STALE_CONFIG) {
+-                      link->state |= DEV_STALE_LINK;
++              if (link->state & DEV_STALE_CONFIG)
+                       return;
+-              }
+       }
+       if (link->handle)
+@@ -583,7 +570,9 @@
+       link->state &= ~DEV_CONFIG;
+-} /* tc574_release */
++      if (link->state & DEV_STALE_CONFIG)
++              tc574_detach(link);
++}
+ /*
+       The card status event handler.  Mostly, this schedules other
+Index: linux-2.6.0-test5/drivers/net/pcmcia/3c589_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/3c589_cs.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/3c589_cs.c    2003-09-27 11:38:26.900438896 +0800
+@@ -176,24 +176,6 @@
+ /*======================================================================
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-    
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          tc589_detach(link);
+-    }
+-}
+-
+-/*======================================================================
+-
+     tc589_attach() creates an "instance" of the driver, allocating
+     local data structures for one device.  The device is registered
+     with Card Services.
+@@ -209,7 +191,6 @@
+     int i, ret;
+     DEBUG(0, "3c589_attach()\n");
+-    flush_stale_links();
+     
+     /* Create new ethernet device */
+     dev = alloc_etherdev(sizeof(struct el3_private));
+@@ -297,10 +278,8 @@
+     if (link->state & DEV_CONFIG) {
+       tc589_release(link);
+-      if (link->state & DEV_STALE_CONFIG) {
+-          link->state |= DEV_STALE_LINK;
++      if (link->state & DEV_STALE_CONFIG)
+           return;
+-      }
+     }
+     
+     if (link->handle)
+@@ -466,8 +445,10 @@
+     CardServices(ReleaseIRQ, link->handle, &link->irq);
+     
+     link->state &= ~DEV_CONFIG;
+-    
+-} /* tc589_release */
++
++    if (link->state & DEV_STALE_CONFIG)
++          tc589_detach(link);
++}
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/net/pcmcia/axnet_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/axnet_cs.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/axnet_cs.c    2003-09-27 11:38:26.916436464 +0800
+@@ -142,24 +142,6 @@
+ /*======================================================================
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-    
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          axnet_detach(link);
+-    }
+-}
+-
+-/*======================================================================
+-
+     We never need to do anything when a axnet device is "initialized"
+     by the net software, because we only register already-found cards.
+@@ -187,7 +169,6 @@
+     int i, ret;
+     DEBUG(0, "axnet_attach()\n");
+-    flush_stale_links();
+     /* Create new ethernet device */
+     info = kmalloc(sizeof(*info), GFP_KERNEL);
+@@ -258,10 +239,8 @@
+     if (link->state & DEV_CONFIG) {
+       axnet_release(link);
+-      if (link->state & DEV_STALE_CONFIG) {
+-          link->state |= DEV_STALE_LINK;
++      if (link->state & DEV_STALE_CONFIG)
+           return;
+-      }
+     }
+     if (link->handle)
+@@ -547,7 +526,9 @@
+     link->state &= ~DEV_CONFIG;
+-} /* axnet_release */
++    if (link->state & DEV_STALE_CONFIG)
++          axnet_detach(link);
++}
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/net/pcmcia/com20020_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/com20020_cs.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/com20020_cs.c 2003-09-27 11:38:26.921435704 +0800
+@@ -145,22 +145,18 @@
+     dev_node_t          node;
+ } com20020_dev_t;
+-/*======================================================================
++static void com20020_setup(struct net_device *dev)
++{
++      struct arcnet_local *lp = dev->priv;
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-    
+-======================================================================*/
++      lp->timeout = timeout;
++      lp->backplane = backplane;
++      lp->clockp = clockp;
++      lp->clockm = clockm & 3;
++      lp->hw.owner = THIS_MODULE;
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          com20020_detach(link);
+-    }
++      /* fill in our module parameters as defaults */
++      dev->dev_addr[0] = node;
+ }
+ /*======================================================================
+@@ -181,7 +177,6 @@
+     struct arcnet_local *lp;
+     
+     DEBUG(0, "com20020_attach()\n");
+-    flush_stale_links();
+     /* Create new network device */
+     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+@@ -192,18 +187,14 @@
+     if (!info)
+       goto fail_alloc_info;
+-    lp =  kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+-    if (!lp)
+-      goto fail_alloc_lp;
+-
+-    dev = dev_alloc("arc%d", &ret);
++    dev = alloc_netdev(sizeof(struct arcnet_local), "arc%d",
++                     com20020_setup);
+     if (!dev)
+       goto fail_alloc_dev;
+     memset(info, 0, sizeof(struct com20020_dev_t));
+-    memset(lp, 0, sizeof(struct arcnet_local));
+     memset(link, 0, sizeof(struct dev_link_t));
+-    dev->priv = lp;
++    lp = dev->priv;
+     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+     link->io.NumPorts1 = 16;
+@@ -220,13 +211,6 @@
+     link->conf.IntType = INT_MEMORY_AND_IO;
+     link->conf.Present = PRESENT_OPTION;
+-    /* fill in our module parameters as defaults */
+-    dev->dev_addr[0] = node;
+-    lp->timeout = timeout;
+-    lp->backplane = backplane;
+-    lp->clockp = clockp;
+-    lp->clockm = clockm & 3;
+-    lp->hw.owner = THIS_MODULE;
+     link->irq.Instance = info->dev = dev;
+     link->priv = info;
+@@ -253,8 +237,6 @@
+     return link;
+ fail_alloc_dev:
+-    kfree(lp);
+-fail_alloc_lp:
+     kfree(info);
+ fail_alloc_info:
+     kfree(link);
+@@ -290,10 +272,8 @@
+     if (link->state & DEV_CONFIG) {
+         com20020_release(link);
+-        if (link->state & DEV_STALE_CONFIG) {
+-            link->state |= DEV_STALE_LINK;
++        if (link->state & DEV_STALE_CONFIG)
+             return;
+-        }
+     }
+     if (link->handle)
+@@ -324,11 +304,9 @@
+               /* ...but I/O ports are done automatically by card services */
+               
+               unregister_netdev(dev);
+-              MOD_DEC_USE_COUNT;
+           }
+           
+           DEBUG(1,"kfree...\n");
+-          kfree(dev->priv);
+           free_netdev(dev);
+       }
+       DEBUG(1,"kfree2...\n");
+@@ -382,7 +360,6 @@
+     /* Configure card */
+     link->state |= DEV_CONFIG;
+-    strcpy(info->node.dev_name, dev->name);
+     DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
+     i = !CS_SUCCESS;
+@@ -428,13 +405,11 @@
+       goto failed;
+     }
+     
+-    MOD_INC_USE_COUNT;
+-
+     lp = dev->priv;
+     lp->card_name = "PCMCIA COM20020";
+     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
+-    i = com20020_found(dev, 0);
++    i = com20020_found(dev, 0);       /* calls register_netdev */
+     
+     if (i != 0) {
+       DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
+@@ -442,6 +417,7 @@
+     }
+     info->dev_configured = 1;
++    strcpy(info->node.dev_name, dev->name);
+     link->dev = &info->node;
+     link->state &= ~DEV_CONFIG_PENDING;
+@@ -484,7 +460,9 @@
+     link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
+-} /* com20020_release */
++    if (link->state & DEV_STALE_CONFIG)
++          com20020_detach(link);
++}
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/net/pcmcia/fmvj18x_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/fmvj18x_cs.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/fmvj18x_cs.c  2003-09-27 11:38:26.931434184 +0800
+@@ -242,24 +242,6 @@
+ #define BANK_1U              0x24 /* bank 1 (CONFIG_1) */
+ #define BANK_2U              0x28 /* bank 2 (CONFIG_1) */
+-/*======================================================================
+-
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-    
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          fmvj18x_detach(link);
+-    }
+-}
+-
+ static dev_link_t *fmvj18x_attach(void)
+ {
+     local_info_t *lp;
+@@ -269,7 +251,6 @@
+     int i, ret;
+     
+     DEBUG(0, "fmvj18x_attach()\n");
+-    flush_stale_links();
+     /* Make up a FMVJ18x specific data structure */
+     dev = alloc_etherdev(sizeof(local_info_t));
+@@ -353,10 +334,8 @@
+     if (link->state & DEV_CONFIG) {
+       fmvj18x_release(link);
+-      if (link->state & DEV_STALE_CONFIG) {
+-          link->state |= DEV_STALE_LINK;
++      if (link->state & DEV_STALE_CONFIG)
+           return;
+-      }
+     }
+     /* Break the link with Card Services */
+@@ -762,8 +741,10 @@
+     CardServices(ReleaseIRQ, link->handle, &link->irq);
+     
+     link->state &= ~DEV_CONFIG;
+-    
+-} /* fmvj18x_release */
++
++    if (link->state & DEV_STALE_CONFIG)
++          fmvj18x_detach(link);
++}
+ /*====================================================================*/
+Index: linux-2.6.0-test5/drivers/net/pcmcia/ibmtr_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/ibmtr_cs.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/ibmtr_cs.c    2003-09-27 11:38:26.936433424 +0800
+@@ -139,24 +139,6 @@
+     struct tok_info   ti;
+ } ibmtr_dev_t;
+-/*======================================================================
+-
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-    
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          ibmtr_detach(link);
+-    }
+-}
+-
+ static void netdev_get_drvinfo(struct net_device *dev,
+                              struct ethtool_drvinfo *info)
+ {
+@@ -184,7 +166,6 @@
+     int i, ret;
+     
+     DEBUG(0, "ibmtr_attach()\n");
+-    flush_stale_links();
+     /* Create new token-ring device */
+     dev = alloc_trdev(sizeof(*info));
+@@ -273,10 +254,8 @@
+     }
+     if (link->state & DEV_CONFIG) {
+         ibmtr_release(link);
+-        if (link->state & DEV_STALE_CONFIG) {
+-            link->state |= DEV_STALE_LINK;
++        if (link->state & DEV_STALE_CONFIG)
+             return;
+-        }
+     }
+     if (link->handle)
+@@ -446,7 +425,9 @@
+     link->state &= ~DEV_CONFIG;
+-} /* ibmtr_release */
++    if (link->state & DEV_STALE_CONFIG)
++          ibmtr_detach(link);
++}
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/net/pcmcia/nmclan_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/nmclan_cs.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/nmclan_cs.c   2003-09-27 11:38:26.950431296 +0800
+@@ -449,21 +449,6 @@
+ static void nmclan_detach(dev_link_t *);
+ /* ----------------------------------------------------------------------------
+-flush_stale_links
+-      Clean up stale device structures
+----------------------------------------------------------------------------- */
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          nmclan_detach(link);
+-    }
+-}
+-
+-/* ----------------------------------------------------------------------------
+ nmclan_attach
+       Creates an "instance" of the driver, allocating local data
+       structures for one device.  The device is registered with Card
+@@ -480,7 +465,6 @@
+     DEBUG(0, "nmclan_attach()\n");
+     DEBUG(1, "%s\n", rcsid);
+-    flush_stale_links();
+     /* Create new ethernet device */
+     dev = alloc_etherdev(sizeof(mace_private));
+@@ -569,10 +553,8 @@
+     if (link->state & DEV_CONFIG) {
+       nmclan_release(link);
+-      if (link->state & DEV_STALE_CONFIG) {
+-          link->state |= DEV_STALE_LINK;
++      if (link->state & DEV_STALE_CONFIG)
+           return;
+-      }
+     }
+     if (link->handle)
+@@ -843,7 +825,9 @@
+   link->state &= ~DEV_CONFIG;
+-} /* nmclan_release */
++  if (link->state & DEV_STALE_CONFIG)
++        nmclan_detach(link);
++}
+ /* ----------------------------------------------------------------------------
+ nmclan_event
+Index: linux-2.6.0-test5/drivers/net/pcmcia/pcnet_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/pcnet_cs.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/pcnet_cs.c    2003-09-27 11:38:26.964429168 +0800
+@@ -239,24 +239,6 @@
+ /*======================================================================
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-    
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          pcnet_detach(link);
+-    }
+-}
+-
+-/*======================================================================
+-
+     We never need to do anything when a pcnet device is "initialized"
+     by the net software, because we only register already-found cards.
+@@ -284,7 +266,6 @@
+     int i, ret;
+     DEBUG(0, "pcnet_attach()\n");
+-    flush_stale_links();
+     /* Create new ethernet device */
+     info = kmalloc(sizeof(*info), GFP_KERNEL);
+@@ -356,10 +337,8 @@
+     if (link->state & DEV_CONFIG) {
+       pcnet_release(link);
+-      if (link->state & DEV_STALE_CONFIG) {
+-          link->state |= DEV_STALE_LINK;
++      if (link->state & DEV_STALE_CONFIG)
+           return;
+-      }
+     }
+     if (link->handle)
+@@ -821,7 +800,9 @@
+     link->state &= ~DEV_CONFIG;
+-} /* pcnet_release */
++    if (link->state & DEV_STALE_CONFIG)
++          pcnet_detach(link);
++}
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/net/pcmcia/smc91c92_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/smc91c92_cs.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/smc91c92_cs.c 2003-09-27 11:38:26.982426432 +0800
+@@ -307,24 +307,6 @@
+ /*======================================================================
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          smc91c92_detach(link);
+-    }
+-}
+-
+-/*======================================================================
+-
+   smc91c92_attach() creates an "instance" of the driver, allocating
+   local data structures for one device.  The device is registered
+   with Card Services.
+@@ -340,7 +322,6 @@
+     int i, ret;
+     DEBUG(0, "smc91c92_attach()\n");
+-    flush_stale_links();
+     /* Create new ethernet device */
+     dev = alloc_etherdev(sizeof(struct smc_private));
+@@ -432,10 +413,8 @@
+     if (link->state & DEV_CONFIG) {
+       smc91c92_release(link);
+-      if (link->state & DEV_STALE_CONFIG) {
+-          link->state |= DEV_STALE_LINK;
++      if (link->state & DEV_STALE_CONFIG)
+           return;
+-      }
+     }
+     if (link->handle)
+@@ -1103,7 +1082,9 @@
+     link->state &= ~DEV_CONFIG;
+-} /* smc91c92_release */
++    if (link->state & DEV_STALE_CONFIG)
++          smc91c92_detach(link);
++}
+ /*======================================================================
+Index: linux-2.6.0-test5/drivers/net/pcmcia/xirc2ps_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pcmcia/xirc2ps_cs.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pcmcia/xirc2ps_cs.c  2003-09-27 11:38:26.999423848 +0800
+@@ -390,17 +390,6 @@
+ static int do_stop(struct net_device *dev);
+ /*=============== Helper functions =========================*/
+-static void
+-flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          xirc2ps_detach(link);
+-    }
+-}
+-
+ static int
+ get_tuple_data(int fn, client_handle_t handle, tuple_t *tuple)
+ {
+@@ -602,7 +591,6 @@
+     int err;
+     DEBUG(0, "attach()\n");
+-    flush_stale_links();
+     /* Allocate the device structure */
+     dev = alloc_etherdev(sizeof(local_info_t));
+@@ -687,13 +675,8 @@
+      * the release() function is called, that will trigger a proper
+      * detach().
+      */
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+       xirc2ps_release(link);
+-      if (link->state & DEV_STALE_CONFIG) {
+-              link->state |= DEV_STALE_LINK;
+-              return;
+-      }
+-    }
+     /* Break the link with Card Services */
+     if (link->handle)
+@@ -1183,19 +1166,6 @@
+     DEBUG(0, "release(0x%p)\n", link);
+-#if 0
+-    /*
+-     * If the device is currently in use, we won't release until it
+-     * is actually closed.
+-     */
+-    if (link->open) {
+-      DEBUG(0, "release postponed, '%s' "
+-            "still open\n", link->dev->dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-#endif
+-
+     if (link->win) {
+       struct net_device *dev = link->priv;
+       local_info_t *local = dev->priv;
+@@ -2030,9 +2000,6 @@
+     SelectPage(0);
+     link->open--;
+-    if (link->state & DEV_STALE_CONFIG)
+-          xirc2ps_release(link);
+-
+     return 0;
+ }
+Index: linux-2.6.0-test5/drivers/net/ppp_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/ppp_generic.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/ppp_generic.c        2003-09-27 11:38:27.016421264 +0800
+@@ -792,7 +792,7 @@
+ /* Called at boot time if ppp is compiled into the kernel,
+    or at module load time (from init_module) if compiled as a module. */
+-int __init ppp_init(void)
++static int __init ppp_init(void)
+ {
+       int err;
+@@ -801,6 +801,8 @@
+       if (!err) {
+               err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
+                               S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
++              if (err)
++                      unregister_chrdev(PPP_MAJOR, "ppp");
+       }
+       if (err)
+Index: linux-2.6.0-test5/drivers/net/pppoe.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/pppoe.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/pppoe.c      2003-09-27 11:38:27.023420200 +0800
+@@ -986,7 +986,7 @@
+       struct pppox_opt *po;
+       char *dev_name;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Id       Address              Device\n");
+               goto out;
+       }
+@@ -1025,7 +1025,7 @@
+       loff_t l = *pos;
+       read_lock_bh(&pppoe_hash_lock);
+-      return l ? pppoe_get_idx(--l) : (void *)1;
++      return l ? pppoe_get_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -1033,7 +1033,7 @@
+       struct pppox_opt *po;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               po = pppoe_get_idx(0);
+               goto out;
+       }
+Index: linux-2.6.0-test5/drivers/net/rcpci45.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/rcpci45.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/rcpci45.c    2003-09-27 11:38:27.030419136 +0800
+@@ -259,10 +259,12 @@
+       dev->set_config = &RCconfig;
+       if ((error = register_netdev(dev)))
+-              goto err_out_free_region;
++              goto err_out_iounmap;
+       return 0;               /* success */
++err_out_iounmap:
++      iounmap((void *) dev->base_addr);
+ err_out_free_region:
+       pci_release_regions (pdev);
+ err_out_free_msgbuf:
+Index: linux-2.6.0-test5/drivers/net/rrunner.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/rrunner.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/rrunner.c    2003-09-27 11:38:27.042417312 +0800
+@@ -30,7 +30,6 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/errno.h>
+ #include <linux/ioport.h>
+@@ -124,7 +123,6 @@
+       rrpriv->pci_dev = pdev;
+       spin_lock_init(&rrpriv->lock);
+-      sprintf(rrpriv->name, "RoadRunner serial HIPPI");
+       dev->irq = pdev->irq;
+       dev->open = &rr_open;
+@@ -228,7 +226,7 @@
+               pci_set_drvdata(pdev, NULL);
+       }
+  out2:
+-      kfree(dev);
++      free_netdev(dev);
+  out3:
+       return ret;
+ }
+@@ -236,9 +234,10 @@
+ static void __devexit rr_remove_one (struct pci_dev *pdev)
+ {
+       struct net_device *dev = pci_get_drvdata(pdev);
+-      struct rr_private *rr = (struct rr_private *)dev->priv;
+       if (dev) {
++              struct rr_private *rr = dev->priv;
++
+               if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)){
+                       printk(KERN_ERR "%s: trying to unload running NIC\n",
+                              dev->name);
+@@ -721,7 +720,8 @@
+        * Give the FirmWare time to chew on the `get running' command.
+        */
+       myjif = jiffies + 5 * HZ;
+-      while (time_before(jiffies, myjif) && !rrpriv->fw_running);
++      while (time_before(jiffies, myjif) && !rrpriv->fw_running)
++              cpu_relax();
+       netif_start_queue(dev);
+@@ -1201,8 +1201,7 @@
+       readl(&regs->HostCtrl);
+       spin_unlock_irqrestore(&rrpriv->lock, flags);
+-      if (request_irq(dev->irq, rr_interrupt, SA_SHIRQ, rrpriv->name, dev))
+-      {
++      if (request_irq(dev->irq, rr_interrupt, SA_SHIRQ, dev->name, dev)) {
+               printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
+                      dev->name, dev->irq);
+               ecode = -EAGAIN;
+@@ -1222,7 +1221,6 @@
+       netif_start_queue(dev);
+-      MOD_INC_USE_COUNT;
+       return ecode;
+  error:
+@@ -1414,7 +1412,6 @@
+       free_irq(dev->irq, dev);
+       spin_unlock_irqrestore(&rrpriv->lock, flags);
+-      MOD_DEC_USE_COUNT;
+       return 0;
+ }
+@@ -1727,7 +1724,7 @@
+       .name           = "rrunner",
+       .id_table       = rr_pci_tbl,
+       .probe          = rr_init_one,
+-      .remove         = rr_remove_one,
++      .remove         = __devexit_p(rr_remove_one),
+ };
+ static int __init rr_init_module(void)
+Index: linux-2.6.0-test5/drivers/net/rrunner.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/rrunner.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/rrunner.h    2003-09-27 11:38:27.046416704 +0800
+@@ -820,7 +820,6 @@
+       u32                     tx_full;
+       u32                     fw_rev;
+       volatile short          fw_running;
+-      char                    name[24];       /* The assigned name */
+       struct net_device_stats stats;
+       struct pci_dev          *pci_dev;
+ };
+Index: linux-2.6.0-test5/drivers/net/sb1000.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sb1000.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sb1000.c     2003-09-27 11:38:27.055415336 +0800
+@@ -35,7 +35,6 @@
+ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/interrupt.h>
+Index: linux-2.6.0-test5/drivers/net/sis900.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sis900.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sis900.c     2003-09-27 11:38:27.073412600 +0800
+@@ -47,7 +47,6 @@
+ */
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/timer.h>
+Index: linux-2.6.0-test5/drivers/net/sk98lin/h/skdrv1st.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sk98lin/h/skdrv1st.h    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sk98lin/h/skdrv1st.h 2003-09-27 11:38:27.075412296 +0800
+@@ -107,9 +107,6 @@
+ #ifndef __INC_SKDRV1ST_H
+ #define __INC_SKDRV1ST_H
+-/* Check kernel version */
+-#include <linux/version.h>
+-
+ typedef struct s_AC   SK_AC;
+ /* Set card versions */
+@@ -135,7 +132,6 @@
+ #error You must compile this driver with "-O".
+ #endif
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/sk98lin/skge.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sk98lin/skge.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sk98lin/skge.c       2003-09-27 11:38:27.378366240 +0800
+@@ -361,7 +361,6 @@
+  *    <linux/module.h>
+  *
+  *    "h/skdrv1st.h"
+- *            <linux/version.h>
+  *            <linux/types.h>
+  *            <linux/kernel.h>
+  *            <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/skfp/h/targetos.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/skfp/h/targetos.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/skfp/h/targetos.h    2003-09-27 11:38:27.479350888 +0800
+@@ -43,7 +43,6 @@
+ #undef ADDR
+-#include <linux/version.h>
+ #include <asm/io.h>
+ #include <linux/netdevice.h>
+ #include <linux/fddidevice.h>
+Index: linux-2.6.0-test5/drivers/net/skfp/skfddi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/skfp/skfddi.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/skfp/skfddi.c        2003-09-27 11:38:27.569337208 +0800
+@@ -182,7 +182,7 @@
+ extern void enable_tx_irq(struct s_smc *smc, u_short queue);
+ extern void mac_drv_clear_txd(struct s_smc *smc);
+-static struct pci_device_id skfddi_pci_tbl[] __initdata = {
++static struct pci_device_id skfddi_pci_tbl[] = {
+       { PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },
+       { }                     /* Terminating entry */
+ };
+Index: linux-2.6.0-test5/drivers/net/sk_mca.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sk_mca.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sk_mca.h     2003-09-27 11:38:27.916284464 +0800
+@@ -1,3 +1,5 @@
++#include <linux/version.h>
++
+ #ifndef _SK_MCA_INCLUDE_
+ #define _SK_MCA_INCLUDE_
+Index: linux-2.6.0-test5/drivers/net/slip.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/slip.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/slip.c       2003-09-27 11:38:27.925283096 +0800
+@@ -869,12 +869,12 @@
+       /* OK.  Find a free SLIP channel to use. */
+       err = -ENFILE;
+-      if ((sl = sl_alloc(tty->device)) == NULL)
++      if ((sl = sl_alloc(tty_devnum(tty))) == NULL)
+               goto err_exit;
+       sl->tty = tty;
+       tty->disc_data = sl;
+-      sl->line = tty->device;
++      sl->line = tty_devnum(tty);
+       sl->pid = current->pid;
+       if (tty->driver->flush_buffer)
+               tty->driver->flush_buffer(tty);
+@@ -1389,9 +1389,8 @@
+        */
+       do {
+               if (busy) {
+-                      current->state = TASK_INTERRUPTIBLE;
++                      set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(HZ / 10);
+-                      current->state = TASK_RUNNING;
+               }
+               busy = 0;
+Index: linux-2.6.0-test5/drivers/net/smc9194.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/smc9194.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/smc9194.c    2003-09-27 11:38:27.936281424 +0800
+@@ -58,7 +58,6 @@
+       "smc9194.c:v0.14 12/15/00 by Erik Stahlman (erik@vt.edu)\n";
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+Index: linux-2.6.0-test5/drivers/net/smc-ultra32.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/smc-ultra32.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/smc-ultra32.c        2003-09-27 11:38:27.940280816 +0800
+@@ -47,6 +47,7 @@
+ #include <linux/module.h>
++#include <linux/eisa.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/net/Space.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Space.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Space.c      2003-09-27 11:38:27.945280056 +0800
+@@ -58,7 +58,6 @@
+ extern int at1700_probe(struct net_device *);
+ extern int fmv18x_probe(struct net_device *);
+ extern int eth16i_probe(struct net_device *);
+-extern int depca_probe(struct net_device *);
+ extern int i82596_probe(struct net_device *);
+ extern int ewrk3_probe(struct net_device *);
+ extern int el1_probe(struct net_device *);
+@@ -97,7 +96,6 @@
+ extern int mac8390_probe(struct net_device *dev);
+ extern int mac89x0_probe(struct net_device *dev);
+ extern int mc32_probe(struct net_device *dev);
+-extern struct net_device *sdla_init(void);
+ extern struct net_device *cops_probe(int unit);
+ extern struct net_device *ltpc_probe(void);
+   
+@@ -253,9 +251,6 @@
+ #ifdef CONFIG_EEXPRESS_PRO    /* Intel EtherExpress Pro/10 */
+       {eepro_probe, 0},
+ #endif
+-#ifdef CONFIG_DEPCA           /* DEC DEPCA */
+-      {depca_probe, 0},
+-#endif
+ #ifdef CONFIG_EWRK3             /* DEC EtherWORKS 3 */
+       {ewrk3_probe, 0},
+ #endif
+@@ -470,10 +465,6 @@
+ #ifdef CONFIG_LTPC
+       ltpc_probe();
+ #endif
+-#ifdef CONFIG_SDLA
+-      sdla_init();
+-#endif
+-
+ }
+ /*
+Index: linux-2.6.0-test5/drivers/net/sunhme.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/sunhme.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/sunhme.c     2003-09-27 11:38:27.976275344 +0800
+@@ -179,7 +179,7 @@
+    where it could be referenced at any time due to hot plugging,
+    the __initdata reference should be removed. */
+-struct pci_device_id happymeal_pci_ids[] __initdata = {
++struct pci_device_id happymeal_pci_ids[] = {
+       {
+         .vendor       = PCI_VENDOR_ID_SUN,
+         .device       = PCI_DEVICE_ID_SUN_HAPPYMEAL,
+Index: linux-2.6.0-test5/drivers/net/tc35815.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tc35815.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tc35815.c    2003-09-27 11:38:27.991273064 +0800
+@@ -448,7 +448,7 @@
+ /* Index to functions, as function prototypes. */
+-static int __init tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq);
++static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq);
+ static int    tc35815_open(struct net_device *dev);
+ static int    tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
+@@ -526,7 +526,7 @@
+       return -ENODEV;
+ }
+-static int __init tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq)
++static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq)
+ {
+       static unsigned version_printed = 0;
+       int i;
+Index: linux-2.6.0-test5/drivers/net/tg3.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tg3.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tg3.c        2003-09-27 11:42:33.530945360 +0800
+@@ -33,6 +33,7 @@
+ #include <asm/io.h>
+ #include <asm/byteorder.h>
+ #include <asm/uaccess.h>
++#include <asm/kgdb.h>
+ #ifdef CONFIG_SPARC64
+ #include <asm/idprom.h>
+@@ -2453,9 +2454,9 @@
+               tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+               sblk->status &= ~SD_STATUS_UPDATED;
+-              if (likely(tg3_has_work(dev, tp)))
++              if (likely(tg3_has_work(dev, tp))) {
+                       netif_rx_schedule(dev);         /* schedule NAPI poll */
+-              else {
++              } else {
+                       /* no work, shared interrupt perhaps?  re-enable
+                        * interrupts, and flush that PCI write
+                        */
+Index: linux-2.6.0-test5/drivers/net/tlan.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tlan.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tlan.c       2003-09-27 11:38:28.078259840 +0800
+@@ -169,6 +169,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/eisa.h>
+ #include <linux/pci.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+@@ -296,6 +297,7 @@
+ 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 );
+@@ -452,6 +454,25 @@
+       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,
+@@ -892,6 +913,9 @@
+       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;
+Index: linux-2.6.0-test5/drivers/net/tokenring/abyss.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/abyss.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/abyss.c    2003-09-27 11:38:28.082259232 +0800
+@@ -40,7 +40,7 @@
+ #include "tms380tr.h"
+ #include "abyss.h"            /* Madge-specific constants */
+-static char version[] __initdata =
++static char version[] __devinitdata =
+ "abyss.c: v1.02 23/11/2000 by Adam Fritzler\n";
+ #define ABYSS_IO_EXTENT 64
+@@ -92,7 +92,7 @@
+       outw(val, dev->base_addr + reg);
+ }
+-static int __init abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
++static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {     
+       static int versionprinted;
+       struct net_device *dev;
+Index: linux-2.6.0-test5/drivers/net/tokenring/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/Kconfig       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/Kconfig    2003-09-27 11:38:28.085258776 +0800
+@@ -2,13 +2,14 @@
+ # Token Ring driver configuration
+ #
+-menu "Token Ring devices (depends on LLC=y)"
++menu "Token Ring devices"
+       depends on NETDEVICES
+ # So far, we only have PCI, ISA, and MCA token ring devices
+ config TR
+       bool "Token Ring driver support"
+-      depends on (PCI || ISA || MCA || CCW) && LLC=y
++      depends on (PCI || ISA || MCA || CCW)
++      select LLC
+       help
+         Token Ring is IBM's way of communication on a local network; the
+         rest of the world uses Ethernet. To participate on a Token Ring
+Index: linux-2.6.0-test5/drivers/net/tokenring/lanstreamer.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/lanstreamer.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/lanstreamer.h      2003-09-27 11:38:28.088258320 +0800
+@@ -60,6 +60,8 @@
+  *
+  */
++#include <linux/version.h>
++
+ #if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ #include <asm/ioctl.h>
+ #define IOCTL_PRINT_RX_BUFS   SIOCDEVPRIVATE
+Index: linux-2.6.0-test5/drivers/net/tokenring/olympic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/olympic.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/olympic.c  2003-09-27 11:38:28.106255584 +0800
+@@ -210,14 +210,13 @@
+       pci_set_master(pdev);
+       if ((i = pci_request_regions(pdev,"olympic"))) { 
+-              return i ; 
+-      } ; 
++              goto op_disable_dev;
++      }
+  
+       dev = alloc_trdev(sizeof(struct olympic_private)) ; 
+-
+       if (!dev) {
+-              pci_release_regions(pdev) ; 
+-              return -ENOMEM ; 
++              i = -ENOMEM; 
++              goto op_free_dev;
+       }
+       olympic_priv = dev->priv ;
+@@ -231,10 +230,12 @@
+       dev->base_addr=pci_resource_start(pdev, 0);
+       dev->init=NULL; /* Must be NULL otherwise we get called twice */
+       olympic_priv->olympic_card_name = pci_name(pdev);
++      olympic_priv->pdev = pdev; 
+       olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
+       olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048);
+-#warning check ioremap return value
+-      olympic_priv->pdev = pdev ; 
++      if (!olympic_priv->olympic_mmio || !olympic_priv->olympic_lap) {
++              goto op_free_iomap;
++      }
+                               
+       if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
+               olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; 
+@@ -246,12 +247,8 @@
+       olympic_priv->olympic_message_level = message_level[card_no] ; 
+       olympic_priv->olympic_network_monitor = network_monitor[card_no];
+       
+-      if((i = olympic_init(dev))) {
+-              iounmap(olympic_priv->olympic_mmio) ; 
+-              iounmap(olympic_priv->olympic_lap) ; 
+-              kfree(dev) ; 
+-              pci_release_regions(pdev) ; 
+-              return i ; 
++      if ((i = olympic_init(dev))) {
++              goto op_free_iomap;
+       }                               
+       dev->open=&olympic_open;
+@@ -275,6 +272,20 @@
+               printk("Olympic: Network Monitor information: /proc/%s\n",proc_name); 
+       }
+       return  0 ;
++
++op_free_iomap:
++      if (olympic_priv->olympic_mmio)
++              iounmap(olympic_priv->olympic_mmio); 
++      if (olympic_priv->olympic_lap)
++              iounmap(olympic_priv->olympic_lap);
++
++op_free_dev:
++      free_netdev(dev);
++      pci_release_regions(pdev); 
++
++op_disable_dev:
++      pci_disable_device(pdev);
++      return i;
+ }
+ static int __devinit olympic_init(struct net_device *dev)
+Index: linux-2.6.0-test5/drivers/net/tokenring/proteon.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/proteon.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/proteon.c  2003-09-27 11:38:28.109255128 +0800
+@@ -410,7 +410,7 @@
+               }
+       } else {
+               for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
+-                      if (setup_card(portlist[i], irq[i], dma[i]))
++                      if (setup_card(portlist[i], irq[num], dma[num]) == 0)
+                               num++;
+               }
+       }
+Index: linux-2.6.0-test5/drivers/net/tokenring/skisa.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/skisa.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/skisa.c    2003-09-27 11:38:28.113254520 +0800
+@@ -423,7 +423,7 @@
+               }
+       } else {
+               for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
+-                      if (setup_card(portlist[i], irq[i], dma[i]))
++                      if (setup_card(portlist[i], irq[num], dma[num]) == 0)
+                               num++;
+               }
+       }
+Index: linux-2.6.0-test5/drivers/net/tokenring/smctr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/smctr.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/smctr.c    2003-09-27 11:38:28.159247528 +0800
+@@ -29,7 +29,6 @@
+  */
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+Index: linux-2.6.0-test5/drivers/net/tokenring/tms380tr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/tms380tr.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/tms380tr.c 2003-09-27 11:38:28.177244792 +0800
+@@ -77,7 +77,6 @@
+ #endif
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+Index: linux-2.6.0-test5/drivers/net/tokenring/tmspci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tokenring/tmspci.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tokenring/tmspci.c   2003-09-27 11:38:28.180244336 +0800
+@@ -40,7 +40,7 @@
+ #include "tms380tr.h"
+-static char version[] __initdata =
++static char version[] __devinitdata =
+ "tmspci.c: v1.02 23/11/2000 by Adam Fritzler\n";
+ #define TMS_PCI_IO_EXTENT 32
+@@ -91,7 +91,7 @@
+       outw(val, dev->base_addr + reg);
+ }
+-static int __init tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
++static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {     
+       static int versionprinted;
+       struct net_device *dev;
+Index: linux-2.6.0-test5/drivers/net/tulip/de2104x.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tulip/de2104x.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tulip/de2104x.c      2003-09-27 11:38:28.195242056 +0800
+@@ -50,7 +50,7 @@
+ #include <asm/unaligned.h>
+ /* These identify the driver base version and may not be removed. */
+-static char version[] __initdata =
++static char version[] =
+ KERN_INFO DRV_NAME " PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
+ MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
+@@ -1932,7 +1932,7 @@
+       goto fill_defaults;
+ }
+-static int __init de_init_one (struct pci_dev *pdev,
++static int __devinit de_init_one (struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+ {
+       struct net_device *dev;
+Index: linux-2.6.0-test5/drivers/net/tulip/de4x5.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tulip/de4x5.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tulip/de4x5.c        2003-09-27 11:38:28.237235672 +0800
+@@ -480,7 +480,7 @@
+ #include "de4x5.h"
+-static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
++static char version[] __devinitdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
+ #define c_char const char
+ #define TWIDDLE(a) (u_short)le16_to_cpu(get_unaligned((u_short *)(a)))
+@@ -1082,7 +1082,7 @@
+ }
\f
+-static int __init 
++static int __devinit 
+ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
+ {
+     char name[DE4X5_NAME_LENGTH + 1];
+@@ -2132,7 +2132,7 @@
+ ** DECchips, we can find the base SROM irrespective of the BIOS scan direction.
+ ** For single port cards this is a time waster...
+ */
+-static void __init 
++static void __devinit 
+ srom_search(struct net_device *dev, struct pci_dev *pdev)
+ {
+     u_char pb;
+@@ -2213,7 +2213,7 @@
+ ** kernels use the V0.535[n] drivers.
+ */
+-static int __init de4x5_pci_probe (struct pci_dev *pdev,
++static int __devinit de4x5_pci_probe (struct pci_dev *pdev,
+                                  const struct pci_device_id *ent)
+ {
+       u_char pb, pbus = 0, dev_num, dnum = 0, timer;
+Index: linux-2.6.0-test5/drivers/net/tulip/tulip_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/tulip/tulip_core.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/tulip/tulip_core.c   2003-09-27 11:38:28.252233392 +0800
+@@ -246,6 +246,7 @@
+ 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);
+@@ -1631,6 +1632,9 @@
+       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 +1792,24 @@
+ }
++#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,
+Index: linux-2.6.0-test5/drivers/net/wan/comx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx.c   2003-09-27 11:38:28.260232176 +0800
+@@ -55,7 +55,6 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/jiffies.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-comx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-comx.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-comx.c   2003-09-27 11:38:28.270230656 +0800
+@@ -51,7 +51,6 @@
+ #define VERSION "0.87"
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-locomx.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-locomx.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-locomx.c 2003-09-27 11:38:28.273230200 +0800
+@@ -38,7 +38,6 @@
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-mixcom.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-mixcom.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-mixcom.c 2003-09-27 11:38:28.280229136 +0800
+@@ -41,7 +41,6 @@
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-hw-munich.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-hw-munich.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-hw-munich.c 2003-09-27 11:38:28.303225640 +0800
+@@ -30,7 +30,6 @@
+ #include <linux/config.h>
+ #include <linux/ctype.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-proto-fr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-proto-fr.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-proto-fr.c  2003-09-27 11:38:28.311224424 +0800
+@@ -37,7 +37,6 @@
+ #define VERSION "0.73"
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/jiffies.h>
+ #include <linux/netdevice.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-proto-lapb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-proto-lapb.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-proto-lapb.c        2003-09-27 11:38:28.315223816 +0800
+@@ -24,7 +24,6 @@
+ #define VERSION "0.80"
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/net/wan/comx-proto-ppp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/comx-proto-ppp.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/comx-proto-ppp.c 2003-09-27 11:38:28.318223360 +0800
+@@ -34,7 +34,6 @@
+ #define VERSION "0.23"
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/jiffies.h>
+ #include <linux/netdevice.h>
+Index: linux-2.6.0-test5/drivers/net/wan/cosa.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/cosa.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/cosa.c   2003-09-27 11:38:28.334220928 +0800
+@@ -326,11 +326,11 @@
+ /* Ioctls */
+ static int cosa_start(struct cosa_data *cosa, int address);
+ static int cosa_reset(struct cosa_data *cosa);
+-static int cosa_download(struct cosa_data *cosa, struct cosa_download *d);
+-static int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d);
++static int cosa_download(struct cosa_data *cosa, unsigned long a);
++static int cosa_readmem(struct cosa_data *cosa, unsigned long a);
+ /* COSA/SRP ROM monitor */
+-static int download(struct cosa_data *cosa, char *data, int addr, int len);
++static int download(struct cosa_data *cosa, const char *data, int addr, int len);
+ static int startmicrocode(struct cosa_data *cosa, int address);
+ static int readmem(struct cosa_data *cosa, char *data, int addr, int len);
+ static int cosa_reset_and_read_id(struct cosa_data *cosa, char *id);
+@@ -1033,11 +1033,10 @@
+ }
+ /* High-level function to download data into COSA memory. Calls download() */
+-static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d)
++static inline int cosa_download(struct cosa_data *cosa, unsigned long arg)
+ {
++      struct cosa_download d;
+       int i;
+-      int addr, len;
+-      char *code;
+       if (cosa->usage > 1)
+               printk(KERN_INFO "%s: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n",
+@@ -1047,38 +1046,36 @@
+                       cosa->name, cosa->firmware_status);
+               return -EPERM;
+       }
+-
+-      if (verify_area(VERIFY_READ, d, sizeof(*d)) ||
+-          __get_user(addr, &(d->addr)) ||
+-          __get_user(len, &(d->len)) ||
+-          __get_user(code, &(d->code)))
++      
++      if (copy_from_user(&d, (void __user *) arg, sizeof(d)))
+               return -EFAULT;
+-      if (addr < 0 || addr > COSA_MAX_FIRMWARE_SIZE)
++      if (d.addr < 0 || d.addr > COSA_MAX_FIRMWARE_SIZE)
+               return -EINVAL;
+-      if (len < 0 || len > COSA_MAX_FIRMWARE_SIZE)
++      if (d.len < 0 || d.len > COSA_MAX_FIRMWARE_SIZE)
+               return -EINVAL;
++
+       /* If something fails, force the user to reset the card */
+       cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_DOWNLOAD);
+-      if ((i=download(cosa, code, len, addr)) < 0) {
++      i = download(cosa, d.code, d.len, d.addr);
++      if (i < 0) {
+               printk(KERN_NOTICE "cosa%d: microcode download failed: %d\n",
+                       cosa->num, i);
+               return -EIO;
+       }
+       printk(KERN_INFO "cosa%d: downloading microcode - 0x%04x bytes at 0x%04x\n",
+-              cosa->num, len, addr);
++              cosa->num, d.len, d.addr);
+       cosa->firmware_status |= COSA_FW_RESET|COSA_FW_DOWNLOAD;
+       return 0;
+ }
+ /* High-level function to read COSA memory. Calls readmem() */
+-static inline int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d)
++static inline int cosa_readmem(struct cosa_data *cosa, unsigned long arg)
+ {
++      struct cosa_download d;
+       int i;
+-      int addr, len;
+-      char *code;
+       if (cosa->usage > 1)
+               printk(KERN_INFO "cosa%d: WARNING: readmem requested with "
+@@ -1090,22 +1087,20 @@
+               return -EPERM;
+       }
+-      if (verify_area(VERIFY_READ, d, sizeof(*d)) ||
+-          __get_user(addr, &(d->addr)) ||
+-          __get_user(len, &(d->len)) ||
+-          __get_user(code, &(d->code)))
++      if (copy_from_user(&d, (void __user *) arg, sizeof(d)))
+               return -EFAULT;
+       /* If something fails, force the user to reset the card */
+       cosa->firmware_status &= ~COSA_FW_RESET;
+-      if ((i=readmem(cosa, code, len, addr)) < 0) {
++      i = readmem(cosa, d.code, d.len, d.addr);
++      if (i < 0) {
+               printk(KERN_NOTICE "cosa%d: reading memory failed: %d\n",
+                       cosa->num, i);
+               return -EIO;
+       }
+       printk(KERN_INFO "cosa%d: reading card memory - 0x%04x bytes at 0x%04x\n",
+-              cosa->num, len, addr);
++              cosa->num, d.len, d.addr);
+       cosa->firmware_status |= COSA_FW_RESET;
+       return 0;
+ }
+@@ -1171,11 +1166,12 @@
+       case COSAIODOWNLD:      /* Download the firmware */
+               if (!capable(CAP_SYS_RAWIO))
+                       return -EACCES;
+-              return cosa_download(cosa, (struct cosa_download *)arg);
++              
++              return cosa_download(cosa, arg);
+       case COSAIORMEM:
+               if (!capable(CAP_SYS_RAWIO))
+                       return -EACCES;
+-              return cosa_readmem(cosa, (struct cosa_download *)arg);
++              return cosa_readmem(cosa, arg);
+       case COSAIORTYPE:
+               return cosa_gettype(cosa, (char *)arg);
+       case COSAIORIDSTR:
+@@ -1405,7 +1401,7 @@
+  * by a single space. Monitor has to reply with a space. Now the download
+  * begins. After the download monitor replies with "\r\n." (CR LF dot).
+  */
+-static int download(struct cosa_data *cosa, char *microcode, int length, int address)
++static int download(struct cosa_data *cosa, const char *microcode, int length, int address)
+ {
+       int i;
+Index: linux-2.6.0-test5/drivers/net/wan/cosa.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/cosa.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/cosa.h   2003-09-27 11:38:28.335220776 +0800
+@@ -73,19 +73,19 @@
+ #define COSAIORSET    _IO('C',0xf0)
+ /* Start microcode at given address */
+-#define COSAIOSTRT    _IOW('C',0xf1,sizeof(int))
++#define COSAIOSTRT    _IOW('C',0xf1, int)
+ /* Read the block from the device memory */
+-#define COSAIORMEM    _IOR('C',0xf2,sizeof(struct cosa_download *))
++#define COSAIORMEM    _IOWR('C',0xf2, struct cosa_download)
+ /* Write the block to the device memory (i.e. download the microcode) */
+-#define COSAIODOWNLD  _IOW('C',0xf2,sizeof(struct cosa_download *))
++#define COSAIODOWNLD  _IOW('C',0xf2, struct cosa_download)
+ /* Read the device type (one of "srp", "cosa", and "cosa8" for now) */
+-#define COSAIORTYPE   _IOR('C',0xf3,sizeof(char *))
++#define COSAIORTYPE   _IOR('C',0xf3, char *)
+ /* Read the device identification string */
+-#define COSAIORIDSTR  _IOR('C',0xf4,sizeof(char *))
++#define COSAIORIDSTR  _IOR('C',0xf4, char *)
+ /* Maximum length of the identification string. */
+ #define COSA_MAX_ID_STRING 128
+@@ -100,7 +100,7 @@
+ #define COSAIONRCHANS _IO('C',0xf8)
+ /* Set the driver for the bus-master operations */
+-#define COSAIOBMSET   _IOW('C', 0xf9, sizeof(unsigned short))
++#define COSAIOBMSET   _IOW('C', 0xf9, unsigned short)
+ #define COSA_BM_OFF   0       /* Bus-mastering off - use ISA DMA (default) */
+ #define COSA_BM_ON    1       /* Bus-mastering on - faster but untested */
+Index: linux-2.6.0-test5/drivers/net/wan/cycx_x25.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/cycx_x25.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/cycx_x25.c       2003-09-27 11:38:28.347218952 +0800
+@@ -78,7 +78,6 @@
+ #define CYCLOMX_X25_DEBUG 1
+-#include <linux/version.h>
+ #include <linux/errno.h>      /* return codes */
+ #include <linux/if_arp.h>       /* ARPHRD_HWX25 */
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+Index: linux-2.6.0-test5/drivers/net/wan/dlci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/dlci.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/dlci.c   2003-09-27 11:38:28.351218344 +0800
+@@ -40,7 +40,6 @@
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+-#include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/netdevice.h>
+ #include <linux/skbuff.h>
+@@ -58,64 +57,9 @@
+ static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org";
+ static LIST_HEAD(dlci_devs);
+-static spinlock_t dlci_dev_lock = SPIN_LOCK_UNLOCKED;
+-static char *basename[16];
+ static void dlci_setup(struct net_device *);
+-/* allow FRAD's to register their name as a valid FRAD */
+-int register_frad(const char *name)
+-{
+-      int i;
+-
+-      if (!name)
+-              return(-EINVAL);
+-
+-      for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+-      {
+-              if (!basename[i])
+-                      break;
+-
+-              /* take care of multiple registrations */
+-              if (strcmp(basename[i], name) == 0)
+-                      return(0);
+-      }
+-
+-      if (i == sizeof(basename) / sizeof(char *))
+-              return(-EMLINK);
+-
+-      basename[i] = kmalloc(strlen(name) + 1, GFP_KERNEL);
+-      if (!basename[i])
+-              return(-ENOMEM);
+-
+-      strcpy(basename[i], name);
+-
+-      return(0);
+-}
+-
+-EXPORT_SYMBOL(register_frad);
+-
+-int unregister_frad(const char *name)
+-{
+-      int i;
+-
+-      if (!name)
+-              return(-EINVAL);
+-
+-      for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+-              if (basename[i] && (strcmp(basename[i], name) == 0))
+-                      break;
+-
+-      if (i == sizeof(basename) / sizeof(char *))
+-              return(-EINVAL);
+-
+-      kfree(basename[i]);
+-      basename[i] = NULL;
+-
+-      return(0);
+-}
+-EXPORT_SYMBOL(unregister_frad);
+-
+ /* 
+  * these encapsulate the RFC 1490 requirements as well as 
+  * deal with packet transmission and reception, working with
+@@ -414,46 +358,38 @@
+       struct net_device       *master, *slave;
+       struct dlci_local       *dlp;
+       struct frad_local       *flp;
+-      int                     err, i;
++      int                     err = -EINVAL;
+       /* validate slave device */
+       slave = dev_get_by_name(dlci->devname);
+       if (!slave)
+-              return(-ENODEV);
+-
+-      if (slave->type != ARPHRD_FRAD) {
+-              dev_put(slave);
+-              return(-EINVAL);
+-      }
++              return -ENODEV;
+-      /* check for registration */
+-      for (i=0;i<sizeof(basename) / sizeof(char *); i++)
+-              if ((basename[i]) && 
+-                       (strncmp(dlci->devname, basename[i], strlen(basename[i])) == 0) && 
+-                       (strlen(dlci->devname) > strlen(basename[i])))
+-                      break;
+-
+-      if (i == sizeof(basename) / sizeof(char *)) {
+-              dev_put(slave);
+-              return(-EINVAL);
+-      }
++      if (slave->type != ARPHRD_FRAD || slave->priv == NULL)
++              goto err1;
+       /* create device name */
+       master = alloc_netdev( sizeof(struct dlci_local), "dlci%d",
+                             dlci_setup);
+       if (!master) {
+-              dev_put(slave);
+-              return(-ENOMEM);
++              err = -ENOMEM;
++              goto err1;
+       }
+-      err = register_netdev(master);
+-      if (err < 0) {
+-              dev_put(slave);
+-              kfree(master);
+-              return(err);
++      /* make sure same slave not already registered */
++      rtnl_lock();
++      list_for_each_entry(dlp, &dlci_devs, list) {
++              if (dlp->slave == slave) {
++                      err = -EBUSY;
++                      goto err2;
++              }
+       }
++      err = dev_alloc_name(master, master->name);
++      if (err < 0)
++              goto err2;
++
+       *(short *)(master->dev_addr) = dlci->dlci;
+       dlp = (struct dlci_local *) master->priv;
+@@ -461,22 +397,27 @@
+       dlp->master = master;
+       flp = slave->priv;
+-      err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
++      err = (*flp->assoc)(slave, master);
+       if (err < 0)
+-      {
+-              unregister_netdev(master);
+-              dev_put(slave);
+-              free_netdev(master);
+-              return(err);
+-      }
++              goto err2;
++
++      err = register_netdevice(master);
++      if (err < 0) 
++              goto err2;
+       strcpy(dlci->devname, master->name);
+-      spin_lock_bh(&dlci_dev_lock);
+       list_add(&dlp->list, &dlci_devs);
+-      spin_unlock_bh(&dlci_dev_lock);
++      rtnl_unlock();
+       return(0);
++
++ err2:
++      rtnl_unlock();
++      kfree(master);
++ err1:
++      dev_put(slave);
++      return(err);
+ }
+ static int dlci_del(struct dlci_add *dlci)
+@@ -499,21 +440,18 @@
+       slave = dlp->slave;
+       flp = slave->priv;
++      rtnl_lock();
+       err = (*flp->deassoc)(slave, master);
+-      if (err) 
+-              return(err);
+-
++      if (!err) {
++              list_del(&dlp->list);
+-      spin_lock_bh(&dlci_dev_lock);
+-      list_del(&dlp->list);
+-      spin_unlock_bh(&dlci_dev_lock);
++              unregister_netdevice(master);
+-      unregister_netdev(master);
+-
+-      dev_put(slave);
+-      free_netdev(master);
++              dev_put(slave);
++      }
++      rtnl_unlock();
+-      return(0);
++      return(err);
+ }
+ static int dlci_ioctl(unsigned int cmd, void *arg)
+@@ -560,6 +498,7 @@
+       dev->hard_header        = dlci_header;
+       dev->get_stats          = dlci_get_stats;
+       dev->change_mtu         = dlci_change_mtu;
++      dev->destructor         = free_netdev;
+       dlp->receive            = dlci_receive;
+@@ -569,31 +508,54 @@
+ }
+-int __init init_dlci(void)
++/* if slave is unregistering, then cleanup master */
++static int dlci_dev_event(struct notifier_block *unused,
++                        unsigned long event, void *ptr)
++{
++      struct net_device *dev = (struct net_device *) ptr;
++
++      if (event == NETDEV_UNREGISTER) {
++              struct dlci_local *dlp;
++
++              list_for_each_entry(dlp, &dlci_devs, list) {
++                      if (dlp->slave == dev) {
++                              list_del(&dlp->list);
++                              unregister_netdevice(dlp->master);
++                              dev_put(dlp->slave);
++                              break;
++                      }
++              }
++      }
++      return NOTIFY_DONE;
++}
++
++static struct notifier_block dlci_notifier = {
++      .notifier_call = dlci_dev_event,
++};
++
++static int __init init_dlci(void)
+ {
+-      int i;
+       dlci_ioctl_set(dlci_ioctl);
++      register_netdevice_notifier(&dlci_notifier);
+       printk("%s.\n", version);
+-      for(i=0;i<sizeof(basename) / sizeof(char *);i++)
+-              basename[i] = NULL;
+-
+       return 0;
+ }
+-void __exit dlci_exit(void)
++static void __exit dlci_exit(void)
+ {
+       struct dlci_local       *dlp, *nxt;
+       
+       dlci_ioctl_set(NULL);
++      unregister_netdevice_notifier(&dlci_notifier);
++      rtnl_lock();
+       list_for_each_entry_safe(dlp, nxt, &dlci_devs, list) {
+-              unregister_netdev(dlp->master);
++              unregister_netdevice(dlp->master);
+               dev_put(dlp->slave);
+-              free_netdev(dlp->master);
+       }
+-
++      rtnl_unlock();
+ }
+ module_init(init_dlci);
+Index: linux-2.6.0-test5/drivers/net/wan/dscc4.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/dscc4.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/dscc4.c  2003-09-27 11:38:28.366216064 +0800
+@@ -80,7 +80,6 @@
+  * - misc crapectomy.
+  */
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/errno.h>
+@@ -693,7 +692,7 @@
+       kfree(ppriv);
+ }
+-static int __init dscc4_init_one(struct pci_dev *pdev,
++static int __devinit dscc4_init_one(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+ {
+       struct dscc4_pci_priv *priv;
+Index: linux-2.6.0-test5/drivers/net/wan/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/Kconfig     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/Kconfig  2003-09-27 11:38:28.373215000 +0800
+@@ -342,6 +342,30 @@
+ comment "X.25/LAPB support is disabled"
+       depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
++config WANXL
++      tristate "SBE Inc. wanXL support"
++      depends on HDLC && PCI
++      help
++        This driver is for wanXL PCI cards made by SBE Inc.  If you have
++        such a card, say Y here and see <http://hq.pm.waw.pl/pub/hdlc/>.
++
++        If you want to compile the driver as a module ( = code which can be
++        inserted in and removed from the running kernel whenever you want),
++        say M here and read <file:Documentation/modules.txt>.  The module
++        will be called wanxl.
++
++        If unsure, say N here.
++
++config WANXL_BUILD_FIRMWARE
++      bool "rebuild wanXL firmware"
++      depends on WANXL
++      help
++        This option allows you to rebuild firmware run by the QUICC
++        processor. It requires as68k, ld68k and hexdump programs.
++        You should never need this option.
++
++        If unsure, say N here.
++
+ config PC300
+       tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)"
+       depends on HDLC && PCI
+Index: linux-2.6.0-test5/drivers/net/wan/lmc/lmc_ver.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/lmc/lmc_ver.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/lmc/lmc_ver.h    2003-09-27 11:38:28.375214696 +0800
+@@ -1,3 +1,5 @@
++#include <linux/version.h>
++
+ #ifndef _IF_LMC_LINUXVER_
+ #define _IF_LMC_LINUXVER_
+Index: linux-2.6.0-test5/drivers/net/wan/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/Makefile    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/Makefile 2003-09-27 11:38:28.376214544 +0800
+@@ -66,3 +66,25 @@
+ endif
+ obj-$(CONFIG_N2)              += n2.o
+ obj-$(CONFIG_C101)            += c101.o
++obj-$(CONFIG_WANXL)           += wanxl.o
++
++ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y)
++ifeq ($(ARCH),m68k)
++  AS68K = $(AS)
++  LD68K = $(LD)
++else
++  AS68K = as68k
++  LD68K = ld68k
++endif
++
++quiet_cmd_build_wanxlfw = BLD FW  $@
++      cmd_build_wanxlfw = \
++      $(CPP) -Wp,-MD,$(depfile) -Iinclude $(obj)/wanxlfw.S | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \
++      $(LD68K) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \
++      hexdump -ve '"\n" 16/1 "0x%02X,"' $(obj)/wanxlfw.bin | sed 's/0x  ,//g;1s/^/static u8 firmware[]={/;$$s/,$$/\n};\n/' >$(obj)/wanxlfw.inc; \
++      rm -f $(obj)/wanxlfw.bin $(obj)/wanxlfw.o
++
++$(obj)/wanxlfw.inc:   $(obj)/wanxlfw.S
++      $(call if_changed_dep,build_wanxlfw)
++targets += wanxlfw.inc
++endif
+Index: linux-2.6.0-test5/drivers/net/wan/pc300_drv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/pc300_drv.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/pc300_drv.c      2003-09-27 11:38:28.404210288 +0800
+@@ -227,7 +227,6 @@
+ #include <linux/netdevice.h>
+ #include <linux/spinlock.h>
+ #include <linux/if.h>
+-#include <linux/version.h>
+ #include <net/syncppp.h>
+ #include <net/arp.h>
+Index: linux-2.6.0-test5/drivers/net/wan/pc300_tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/pc300_tty.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/pc300_tty.c      2003-09-27 11:38:28.413208920 +0800
+@@ -37,7 +37,6 @@
+  */
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/errno.h>
+Index: linux-2.6.0-test5/drivers/net/wan/sbni.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sbni.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sbni.c   2003-09-27 11:38:28.424207248 +0800
+@@ -53,6 +53,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
++#include <linux/delay.h>
+ #include <net/arp.h>
+@@ -337,13 +338,12 @@
+       outb( 0, ioaddr + CSR0 );
+       if( irq < 2 ) {
+-              unsigned long irq_mask, delay;
++              unsigned long irq_mask;
+               irq_mask = probe_irq_on();
+               outb( EN_INT | TR_REQ, ioaddr + CSR0 );
+               outb( PR_RES, ioaddr + CSR1 );
+-              delay = jiffies + HZ/20;
+-              while (time_before(jiffies, delay)) ;
++              mdelay(50);
+               irq = probe_irq_off(irq_mask);
+               outb( 0, ioaddr + CSR0 );
+@@ -1562,13 +1562,13 @@
+ static u32
+ calc_crc32( u32  crc,  u8  *p,  u32  len )
+ {
+-      register u32  _crc __asm ( "ax" );
++      register u32  _crc;
+       _crc = crc;
+       
+       __asm __volatile (
+               "xorl   %%ebx, %%ebx\n"
+-              "movl   %1, %%esi\n" 
+-              "movl   %2, %%ecx\n" 
++              "movl   %2, %%esi\n" 
++              "movl   %3, %%ecx\n" 
+               "movl   $crc32tab, %%edi\n"
+               "shrl   $2, %%ecx\n"
+               "jz     1f\n"
+@@ -1604,7 +1604,7 @@
+               "jnz    0b\n"
+       "1:\n"
+-              "movl   %2, %%ecx\n"
++              "movl   %3, %%ecx\n"
+               "andl   $3, %%ecx\n"
+               "jz     2f\n"
+@@ -1629,9 +1629,9 @@
+               "xorb   2(%%esi), %%bl\n"
+               "xorl   (%%edi,%%ebx,4), %%eax\n"
+       "2:\n"
+-              :
+-              : "a" (_crc), "g" (p), "g" (len)
+-              : "ax", "bx", "cx", "dx", "si", "di"
++              : "=a" (_crc)
++              : "0" (_crc), "g" (p), "g" (len)
++              : "bx", "cx", "dx", "si", "di"
+       );
+       return  _crc;
+Index: linux-2.6.0-test5/drivers/net/wan/sdla.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla.c   2003-09-27 11:38:28.434205728 +0800
+@@ -60,8 +60,6 @@
+ static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org";
+-static const char* devname = "sdla";
+-
+ static unsigned int valid_port[] __initdata = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
+ static unsigned int valid_mem[]  __initdata = {
+@@ -1626,41 +1624,16 @@
+ static void setup_sdla(struct net_device *dev)
+ {
++      struct frad_local *flp = dev->priv;
++
++      netdev_boot_setup_check(dev);
++
++      SET_MODULE_OWNER(dev);
+       dev->flags              = 0;
+       dev->type               = 0xFFFF;
+       dev->hard_header_len    = 0;
+       dev->addr_len           = 0;
+       dev->mtu                = SDLA_MAX_MTU;
+-}
+-
+-static int frad_registered;
+-
+-struct net_device * __init sdla_init(void)
+-{
+-      struct net_device *dev;
+-      struct frad_local *flp;
+-      int err = -ENOMEM;
+-
+-      if (!frad_registered) {
+-              err = register_frad(devname);
+-              if (err) {
+-                      printk(KERN_ERR "%s: frad registration failed %d\n",
+-                             devname, err);
+-                      return ERR_PTR(err);
+-              }
+-              frad_registered = 1;
+-              printk("%s.\n", version);
+-      }
+-              
+-
+-      dev = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
+-      if (!dev)
+-              goto out;
+-
+-      SET_MODULE_OWNER(dev);
+-      netdev_boot_setup_check(dev);
+-
+-      flp = dev->priv;
+       dev->open               = sdla_open;
+       dev->stop               = sdla_close;
+@@ -1680,48 +1653,41 @@
+       flp->timer.expires      = 1;
+       flp->timer.data         = (unsigned long) dev;
+       flp->timer.function     = sdla_poll;
+-
+-      err = register_netdev(dev);
+-      if (err)
+-              goto out1;
+-      return dev;
+-out1:
+-      kfree(dev);
+-out:
+-      return ERR_PTR(err);
+ }
+-#ifdef MODULE
+-static struct net_device *sdla0;
++static struct net_device *sdla;
+ static int __init init_sdla(void)
+ {
+-      int result = 0;
++      int err;
+-      sdla0 = sdla_init();
+-      if (IS_ERR(sdla0))
+-              result = PTR_ERR(sdla0);
++      printk("%s.\n", version);
+-      return result;
++      sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
++      if (!sdla) 
++              return -ENOMEM;
++
++      err = register_netdev(sdla);
++      if (err) 
++              free_netdev(sdla);
++
++      return err;
+ }
+ static void __exit exit_sdla(void)
+ {
+       struct frad_local *flp;
+-      unregister_netdev(sdla0);
+-      if (sdla0->irq)
+-              free_irq(sdla0->irq, sdla0);
++      unregister_netdev(sdla);
++      if (sdla->irq)
++              free_irq(sdla->irq, sdla);
+-      flp = sdla0->priv;
++      flp = sdla->priv;
+       del_timer_sync(&flp->timer);
+-      free_netdev(sdla0);
+-      
+-      unregister_frad(devname);
++      free_netdev(sdla);
+ }
+ MODULE_LICENSE("GPL");
+ module_init(init_sdla);
+ module_exit(exit_sdla);
+-#endif
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_chdlc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_chdlc.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_chdlc.c     2003-09-27 11:38:28.465201016 +0800
+@@ -49,7 +49,6 @@
+ *****************************************************************************/
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+@@ -560,8 +559,8 @@
+       
+               if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
+-                      printk (KERN_INFO "%s: 
+-                              Failed to set interrupt triggers!\n",
++                      printk (KERN_INFO "%s: "
++                              "Failed to set interrupt triggers!\n",
+                               card->devname);
+                       return -EIO;    
+               }
+Index: linux-2.6.0-test5/drivers/net/wan/sdladrv.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdladrv.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdladrv.c        2003-09-27 11:38:28.482198432 +0800
+@@ -91,7 +91,6 @@
+ #if   defined(_LINUX_)        /****** Linux *******************************/
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+@@ -201,7 +200,7 @@
+  * Note: All data must be explicitly initialized!!!
+  */
+-static struct pci_device_id sdladrv_pci_tbl[] __initdata = {
++static struct pci_device_id sdladrv_pci_tbl[] = {
+       { V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
+       { }                     /* Terminating entry */
+ };
+@@ -351,7 +350,7 @@
+ }
+ module_init(sdladrv_init);
+-module_cleanup(sdladrv_cleanup);
++module_exit(sdladrv_cleanup);
+ #endif
+ /******* Kernel APIs ********************************************************/
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_fr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_fr.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_fr.c        2003-09-27 11:38:28.517193112 +0800
+@@ -139,7 +139,6 @@
+ *****************************************************************************/
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+@@ -147,6 +146,7 @@
+ #include <linux/slab.h>       /* kmalloc(), kfree() */
+ #include <linux/wanrouter.h>  /* WAN router definitions */
+ #include <linux/wanpipe.h>    /* WANPIPE common user API definitions */
++#include <linux/workqueue.h>
+ #include <linux/if_arp.h>     /* ARPHRD_* defines */
+ #include <asm/byteorder.h>    /* htons(), etc. */
+ #include <asm/io.h>           /* for inb(), outb(), etc. */
+@@ -247,7 +247,7 @@
+       /* Polling task queue. Each interface
+          * has its own task queue, which is used
+          * to defer events from the interrupt */
+-      struct tq_struct fr_poll_task;
++      struct work_struct fr_poll_work;
+       struct timer_list fr_arp_timer;
+       u32 ip_local;
+@@ -987,9 +987,7 @@
+          * We need a poll routine for each network
+          * interface. 
+          */
+-      chan->fr_poll_task.sync = 0;
+-      chan->fr_poll_task.routine = (void *)(void *)fr_poll;
+-      chan->fr_poll_task.data = dev;
++      INIT_WORK(&chan->fr_poll_work, (void *)fr_poll, dev);
+       init_timer(&chan->fr_arp_timer);
+       chan->fr_arp_timer.data=(unsigned long)dev;
+@@ -1212,9 +1210,7 @@
+       /* Initialize the task queue */
+       chan->tq_working=0;
+-      chan->common.wanpipe_task.sync = 0;
+-      chan->common.wanpipe_task.routine = (void *)(void *)fr_bh;
+-      chan->common.wanpipe_task.data = dev;
++      INIT_WORK(&chan->common.wanpipe_work, (void *)fr_bh, dev);
+       /* Allocate and initialize BH circular buffer */
+       chan->bh_head = kmalloc((sizeof(bh_data_t)*MAX_BH_BUFF),GFP_ATOMIC);
+@@ -2178,7 +2174,7 @@
+               } 
+               
+-              /* Send a packed up the IP stack */
++              /* Send a packet up the IP stack */
+               skb->dev->last_rx = jiffies;
+               netif_rx(skb);
+               ++chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack;
+@@ -2216,8 +2212,8 @@
+  *         dlci number.
+  *      2. Check that network interface is up and
+  *         properly setup.
+- *    3. Check for a buffered packed.
+- *      4. Transmit the packed.
++ *    3. Check for a buffered packet.
++ *      4. Transmit the packet.
+  *    5. If we are in WANPIPE mode, mark the 
+  *         NET_BH handler. 
+  *      6. If we are in API mode, kick
+@@ -4359,8 +4355,8 @@
+  * bh_enqueue
+  *
+  * Description:
+- *    Insert a received packed into a circular
+- *      rx queue.  This packed will be picked up 
++ *    Insert a received packet into a circular
++ *      rx queue.  This packet will be picked up 
+  *      by fr_bh() and sent up the stack to the
+  *      user.
+  *            
+@@ -4411,8 +4407,7 @@
+ static void trigger_fr_bh (fr_channel_t *chan)
+ {
+       if (!test_and_set_bit(0,&chan->tq_working)){
+-              wanpipe_queue_tq(&chan->common.wanpipe_task);
+-              wanpipe_mark_bh();
++              wanpipe_queue_work(&chan->common.wanpipe_work);
+       }
+ }
+@@ -4435,10 +4430,10 @@
+  *      card into an skb buffer, the skb buffer
+  *    is appended to a circular BH buffer.
+  *    Then the interrupt kicks fr_bh() to finish the
+- *      job at a later time (no within the interrupt).
++ *      job at a later time (not within the interrupt).
+  *       
+  * Usage:
+- *    Interrupts use this to defer a taks to 
++ *    Interrupts use this to defer a task to 
+  *      a polling routine.
+  *
+  */   
+@@ -4527,7 +4522,7 @@
+ static void trigger_fr_poll(struct net_device *dev)
+ {
+       fr_channel_t* chan = dev->priv;
+-      schedule_task(&chan->fr_poll_task);
++      schedule_work(&chan->fr_poll_work);
+       return;
+ }
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_ft1.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_ft1.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_ft1.c       2003-09-27 11:38:28.521192504 +0800
+@@ -21,7 +21,6 @@
+ *****************************************************************************/
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+Index: linux-2.6.0-test5/drivers/net/wan/sdlamain.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdlamain.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdlamain.c       2003-09-27 11:38:28.531190984 +0800
+@@ -46,7 +46,6 @@
+ * Jan 02, 1997        Gene Kozin      Initial version.
+ *****************************************************************************/
+-#include <linux/version.h>
+ #include <linux/config.h>     /* OS configuration options */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+@@ -189,7 +188,6 @@
+ /* Miscellaneous functions */
+ STATIC irqreturn_t sdla_isr   (int irq, void* dev_id, struct pt_regs *regs);
+ static void release_hw  (sdla_t *card);
+-static void run_wanpipe_tq (unsigned long);
+ static int check_s508_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
+ static int check_s514_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
+@@ -203,29 +201,21 @@
+ static char drvname[] = "wanpipe";
+ static char fullname[]        = "WANPIPE(tm) Multiprotocol Driver";
+ static char copyright[]       = "(c) 1995-2000 Sangoma Technologies Inc.";
+-static int ncards = 0; 
+-static sdla_t* card_array = NULL;     /* adapter data space */
++static int ncards; 
++static sdla_t* card_array;            /* adapter data space */
+-/* Wanpipe's own task queue, used for all API's.
+- * All protocol specific tasks will be instered
+- * into "wanpipe_tq_custom" task_queue. 
+-
+- * On each rx_interrupt, the whole task queue
+- * (wanpipe_tq_custom) will be queued into 
+- * IMMEDIATE_BH via wanpipe_mark_bh() call. 
+- 
+- * The IMMEDIATE_BH will execute run_wanpipe_tq() 
+- * function, which will execute all pending,
+- * tasks in wanpipe_tq_custom queue */
+-
+-DECLARE_TASK_QUEUE(wanpipe_tq_custom);
+-static struct tq_struct wanpipe_tq_task = 
+-{
+-      .routine = (void (*)(void *)) run_wanpipe_tq,
+-      .data = &wanpipe_tq_custom
+-};
++/* Wanpipe's own workqueue, used for all API's.
++ * All protocol specific tasks will be inserted
++ * into the "wanpipe_wq" workqueue. 
++
++ * The kernel workqueue mechanism will execute
++ * all pending tasks in the "wanpipe_wq" workqueue.
++ */
+-static int wanpipe_bh_critical=0;
++struct workqueue_struct *wanpipe_wq;
++DECLARE_WORK(wanpipe_work, NULL, NULL);
++
++static int wanpipe_bh_critical;
+ /******* Kernel Loadable Module Entry Points ********************************/
+@@ -249,6 +239,10 @@
+       printk(KERN_INFO "%s v%u.%u %s\n",
+               fullname, DRV_VERSION, DRV_RELEASE, copyright);
++      wanpipe_wq = create_workqueue("wanpipe_wq");
++      if (!wanpipe_wq)
++              return -ENOMEM;
++
+       /* Probe for wanpipe cards and return the number found */
+       printk(KERN_INFO "wanpipe: Probing for WANPIPE hardware.\n");
+       ncards = wanpipe_hw_probe();
+@@ -256,13 +250,16 @@
+               printk(KERN_INFO "wanpipe: Allocating maximum %i devices: wanpipe%i - wanpipe%i.\n",ncards,1,ncards);
+       }else{
+               printk(KERN_INFO "wanpipe: No S514/S508 cards found, unloading modules!\n");
++              destroy_workqueue(wanpipe_wq);
+               return -ENODEV;
+       }
+       
+       /* Verify number of cards and allocate adapter data space */
+       card_array = kmalloc(sizeof(sdla_t) * ncards, GFP_KERNEL);
+-      if (card_array == NULL)
++      if (card_array == NULL) {
++              destroy_workqueue(wanpipe_wq);
+               return -ENOMEM;
++      }
+       memset(card_array, 0, sizeof(sdla_t) * ncards);
+@@ -292,6 +289,7 @@
+               ncards = cnt;   /* adjust actual number of cards */
+       }else {
+               kfree(card_array);
++              destroy_workqueue(wanpipe_wq);
+               printk(KERN_INFO "IN Init Module: NO Cards registered\n");
+               err = -ENODEV;
+       }
+@@ -316,6 +314,7 @@
+               sdla_t* card = &card_array[i];
+               unregister_wan_device(card->devname);
+       }
++      destroy_workqueue(wanpipe_wq);
+       kfree(card_array);
+       printk(KERN_INFO "\nwanpipe: WANPIPE Modules Unloaded.\n");
+@@ -673,15 +672,20 @@
+       
+       /* Make sure I/O port region is available only if we are the
+-       * master device.  If we are running in piggibacking mode, 
+-       * we will use the resources of the master card */
+-      if (check_region(conf->ioport, SDLA_MAXIORANGE) && 
+-          !card->wandev.piggyback) {
+-              printk(KERN_INFO
+-                      "%s: I/O region 0x%X - 0x%X is in use!\n",
+-                      card->wandev.name, conf->ioport,
+-                      conf->ioport + SDLA_MAXIORANGE);
+-              return -EINVAL;
++       * master device.  If we are running in piggybacking mode, 
++       * we will use the resources of the master card. */
++      if (!card->wandev.piggyback) {
++              struct resource *rr =
++                      request_region(conf->ioport, SDLA_MAXIORANGE, "sdlamain");
++              release_region(conf->ioport, SDLA_MAXIORANGE);
++
++              if (!rr) {
++                      printk(KERN_INFO
++                              "%s: I/O region 0x%X - 0x%X is in use!\n",
++                              card->wandev.name, conf->ioport,
++                              conf->ioport + SDLA_MAXIORANGE - 1);
++                      return -EINVAL;
++              }
+       }
+       return 0;
+@@ -1029,7 +1033,6 @@
+ STATIC irqreturn_t sdla_isr (int irq, void* dev_id, struct pt_regs *regs)
+ {
+ #define       card    ((sdla_t*)dev_id)
+-      int handled = 0;
+       if(card->hw.type == SDLA_S514) {        /* handle interrrupt on S514 */
+                 u32 int_status;
+@@ -1210,6 +1213,7 @@
+       }
+       return NULL;
+ }
++
+ sdla_t * wanpipe_find_card_num (int num)
+ {
+       if (num < 1 || num > ncards)
+@@ -1218,35 +1222,20 @@
+       return &card_array[num];
+ }
+-
+-static void run_wanpipe_tq (unsigned long data)
+-{
+-      task_queue *tq_queue = (task_queue *)data;
+-      if (test_and_set_bit(2,(void*)&wanpipe_bh_critical))
+-              printk(KERN_INFO "CRITICAL IN RUNNING TASK QUEUE\n");
+-      run_task_queue (tq_queue);
+-      clear_bit(2,(void*)&wanpipe_bh_critical);
+-
+-}
+-
+-void wanpipe_queue_tq (struct tq_struct *bh_pointer)
++/*
++ * @work_pointer:     work_struct to be done;
++ *                    should already have PREPARE_WORK() or
++ *                      INIT_WORK() done on it by caller;
++ */
++void wanpipe_queue_work (struct work_struct *work_pointer)
+ {
+-      if (test_and_set_bit(1,(void*)&wanpipe_bh_critical))
+-              printk(KERN_INFO "CRITICAL IN QUEUING TASK\n");
++      if (test_and_set_bit(1, (void*)&wanpipe_bh_critical))
++              printk(KERN_INFO "CRITICAL IN QUEUING WORK\n");
+-      queue_task(bh_pointer,&wanpipe_tq_custom);
++      queue_work(wanpipe_wq, work_pointer);
+       clear_bit(1,(void*)&wanpipe_bh_critical);
+ }
+-void wanpipe_mark_bh (void)
+-{
+-      if (!test_and_set_bit(0,(void*)&wanpipe_bh_critical)){
+-              queue_task(&wanpipe_tq_task,&tq_immediate);
+-              mark_bh(IMMEDIATE_BH);
+-              clear_bit(0,(void*)&wanpipe_bh_critical);
+-      }
+-} 
+-
+ void wakeup_sk_bh(struct net_device *dev)
+ {
+       wanpipe_common_t *chan = dev->priv;
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_ppp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_ppp.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_ppp.c       2003-09-27 11:38:28.556187184 +0800
+@@ -91,7 +91,6 @@
+ *****************************************************************************/
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+Index: linux-2.6.0-test5/drivers/net/wan/sdla_x25.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sdla_x25.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sdla_x25.c       2003-09-27 11:38:28.594181408 +0800
+@@ -82,7 +82,6 @@
+  *=====================================================*/
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+@@ -91,6 +90,7 @@
+ #include <linux/slab.h>       /* kmalloc(), kfree() */
+ #include <linux/wanrouter.h>  /* WAN router definitions */
+ #include <linux/wanpipe.h>    /* WANPIPE common user API definitions */
++#include <linux/workqueue.h>
+ #include <asm/byteorder.h>    /* htons(), etc. */
+ #include <asm/atomic.h>
+ #include <linux/delay.h>      /* Experimental delay */
+@@ -790,9 +790,7 @@
+       
+       init_global_statistics(card);   
+-      card->u.x.x25_poll_task.sync=0;
+-      card->u.x.x25_poll_task.routine = (void*)(void*)wpx_poll;
+-      card->u.x.x25_poll_task.data = card;
++      INIT_WORK(&card->u.x.x25_poll_work, (void *)wpx_poll, card);
+       init_timer(&card->u.x.x25_timer);
+       card->u.x.x25_timer.data = (unsigned long)card;
+@@ -1175,7 +1173,7 @@
+  * Warnings:  None
+  *
+  * Return:    0       Ok
+- *            <0      Failur: Interface will not come up.
++ *            <0      Failure: Interface will not come up.
+  */
+ static int if_open(struct net_device* dev)
+@@ -1190,10 +1188,8 @@
+       chan->tq_working = 0;
+-      /* Initialize the task queue */
+-      chan->common.wanpipe_task.sync = 0;
+-      chan->common.wanpipe_task.routine = (void *)(void *)x25api_bh;
+-      chan->common.wanpipe_task.data = dev;
++      /* Initialize the workqueue */
++      INIT_WORK(&chan->common.wanpipe_work, (void *)x25api_bh, dev);
+       /* Allocate and initialize BH circular buffer */
+       /* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */
+@@ -1732,8 +1728,7 @@
+               chan->rx_skb = NULL;
+               if (!test_and_set_bit(0, &chan->tq_working)){
+-                      wanpipe_queue_tq(&chan->common.wanpipe_task);
+-                      wanpipe_mark_bh();
++                      wanpipe_queue_work(&chan->common.wanpipe_work);
+               }
+               return;
+       }
+@@ -2227,7 +2222,7 @@
+ /*====================================================================
+  *    Main polling routine.
+- *    This routine is repeatedly called by the WANPIPE 'thead' to allow for
++ *    This routine is repeatedly called by the WANPIPE 'thread' to allow for
+  *    time-dependent housekeeping work.
+  *
+  *    Notes:
+@@ -2274,7 +2269,7 @@
+ static void trigger_x25_poll(sdla_t *card)
+ {
+-      schedule_task(&card->u.x.x25_poll_task);
++      schedule_work(&card->u.x.x25_poll_work);
+ }
+ /*====================================================================
+Index: linux-2.6.0-test5/drivers/net/wan/sealevel.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/sealevel.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/sealevel.c       2003-09-27 11:38:28.598180800 +0800
+@@ -31,7 +31,6 @@
+ struct slvl_device
+ {
+-      void *if_ptr;   /* General purpose pointer (used by SPPP) */
+       struct z8530_channel *chan;
+       struct ppp_device netdev;
+       int channel;
+@@ -40,7 +39,7 @@
+ struct slvl_board
+ {
+-      struct slvl_device dev[2];
++      struct slvl_device *dev[2];
+       struct z8530_dev board;
+       int iobase;
+ };
+@@ -119,7 +118,6 @@
+        *      Go go go
+        */
+       netif_start_queue(d);
+-      MOD_INC_USE_COUNT;
+       return 0;
+ }
+@@ -153,7 +151,6 @@
+                       z8530_sync_close(d, slvl->chan);
+                       break;
+       }
+-      MOD_DEC_USE_COUNT;
+       return 0;
+ }
+@@ -202,48 +199,79 @@
+       return 0;
+ }
++              
++static void slvl_setup(struct net_device *d)
++{
++      d->open = sealevel_open;
++      d->stop = sealevel_close;
++      d->hard_start_xmit = sealevel_queue_xmit;
++      d->get_stats = sealevel_get_stats;
++      d->set_multicast_list = NULL;
++      d->do_ioctl = sealevel_ioctl;
++      d->neigh_setup = sealevel_neigh_setup_dev;
++      d->set_mac_address = NULL;
++
++}
++
++static inline struct slvl_device *slvl_alloc(int iobase, int irq)
++{
++      struct net_device *d;
++      struct slvl_device *sv;
++
++      d = alloc_netdev(sizeof(struct slvl_device), "hdlc%d",
++                       slvl_setup);
++
++      if (!d) 
++              return NULL;
++
++      sv = d->priv;
++      sv->netdev.dev = d;
++      d->base_addr = iobase;
++      d->irq = irq;
++              
++      sppp_attach(&sv->netdev);
++      return sv;
++}
++
++
+ /*
+- *    Description block for a Comtrol Hostess SV11 card
++ *    Allocate and setup Sealevel board.
+  */
+  
+-static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, int slow)
++static __init struct slvl_board *slvl_init(int iobase, int irq, 
++                                         int txdma, int rxdma, int slow)
+ {
+       struct z8530_dev *dev;
+-      struct slvl_device *sv;
+       struct slvl_board *b;
+-      int u;
+       
+       /*
+        *      Get the needed I/O space
+        */
+-       
++
+       if(!request_region(iobase, 8, "Sealevel 4021")) 
+       {       
+               printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n", iobase);
+               return NULL;
+       }
+       
+-      b=(struct slvl_board *)kmalloc(sizeof(struct slvl_board), GFP_KERNEL);
++      b = kmalloc(sizeof(struct slvl_board), GFP_KERNEL);
+       if(!b)
+               goto fail3;
+-                      
+-      memset(b, 0, sizeof(*sv));
+-      b->dev[0].chan = &b->board.chanA;       
+-      b->dev[0].if_ptr = &b->dev[0].netdev;
+-      b->dev[0].netdev.dev=(struct net_device *)
+-              kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-      if(!b->dev[0].netdev.dev)
++      memset(b, 0, sizeof(*b));
++      if (!(b->dev[0]= slvl_alloc(iobase, irq)))
+               goto fail2;
+-      b->dev[1].chan = &b->board.chanB;
+-      b->dev[1].if_ptr = &b->dev[1].netdev;
+-      b->dev[1].netdev.dev=(struct net_device *)
+-              kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-      if(!b->dev[1].netdev.dev)
++      b->dev[0]->chan = &b->board.chanA;      
++      b->dev[0]->channel = 0;
++      
++      if (!(b->dev[1] = slvl_alloc(iobase, irq)))
+               goto fail1_0;
+-      dev=&b->board;
++      b->dev[1]->chan = &b->board.chanB;
++      b->dev[1]->channel = 1;
++
++      dev = &b->board;
+       
+       /*
+        *      Stuff in the I/O addressing
+@@ -287,8 +315,8 @@
+       dev->irq=irq;
+       dev->chanA.private=&b->dev[0];
+       dev->chanB.private=&b->dev[1];
+-      dev->chanA.netdevice=b->dev[0].netdev.dev;
+-      dev->chanB.netdevice=b->dev[1].netdev.dev;
++      dev->chanA.netdevice=b->dev[0]->netdev.dev;
++      dev->chanB.netdevice=b->dev[1]->netdev.dev;
+       dev->chanA.dev=dev;
+       dev->chanB.dev=dev;
+@@ -329,55 +357,18 @@
+       
+       enable_irq(irq);
+-      for(u=0; u<2; u++)
+-      {
+-              sv=&b->dev[u];
+-              sv->channel = u;
+-      
+-              if(dev_alloc_name(sv->chan->netdevice,"hdlc%d")>=0)
+-              {
+-                      struct net_device *d=sv->chan->netdevice;
+-
+-                      /* 
+-                       *      Initialise the PPP components
+-                       */
+-                      sppp_attach(&sv->netdev);
+-              
+-                      /*
+-                       *      Local fields
+-                       */     
+-                      
+-                      d->base_addr = iobase;
+-                      d->irq = irq;
+-                      d->priv = sv;
+-                      d->init = NULL;
+-              
+-                      d->open = sealevel_open;
+-                      d->stop = sealevel_close;
+-                      d->hard_start_xmit = sealevel_queue_xmit;
+-                      d->get_stats = sealevel_get_stats;
+-                      d->set_multicast_list = NULL;
+-                      d->do_ioctl = sealevel_ioctl;
+-                      d->neigh_setup = sealevel_neigh_setup_dev;
+-                      d->set_mac_address = NULL;
++      if (register_netdev(b->dev[0]->netdev.dev)) 
++              goto dmafail2;
+               
+-                      if(register_netdev(d)==-1)
+-                      {
+-                              printk(KERN_ERR "%s: unable to register device.\n",
+-                                      d->name);
+-                              goto fail_unit;
+-                      }                               
++      if (register_netdev(b->dev[1]->netdev.dev)) 
++              goto fail_unit;
+-                      break;
+-              }
+-      }
+       z8530_describe(dev, "I/O", iobase);
+       dev->active=1;
+       return b;
+ fail_unit:
+-      if(u==1)
+-              unregister_netdev(b->dev[0].chan->netdevice);
++      unregister_netdev(b->dev[0]->netdev.dev);
+       
+ dmafail2:
+       free_dma(dev->chanA.rxdma);
+@@ -386,9 +377,9 @@
+ fail:
+       free_irq(irq, dev);
+ fail1_1:
+-      kfree(b->dev[1].netdev.dev);
++      free_netdev(b->dev[1]->netdev.dev);
+ fail1_0:
+-      kfree(b->dev[0].netdev.dev);
++      free_netdev(b->dev[0]->netdev.dev);
+ fail2:
+       kfree(b);
+ fail3:
+@@ -396,7 +387,7 @@
+       return NULL;
+ }
+-static void slvl_shutdown(struct slvl_board *b)
++static void __exit slvl_shutdown(struct slvl_board *b)
+ {
+       int u;
+@@ -404,8 +395,11 @@
+       
+       for(u=0; u<2; u++)
+       {
+-              sppp_detach(b->dev[u].netdev.dev);
+-              unregister_netdev(b->dev[u].netdev.dev);
++              struct net_device *d = b->dev[u]->netdev.dev;
++              sppp_detach(d);
++
++              unregister_netdev(d);
++              free_netdev(d);
+       }
+       
+       free_irq(b->board.irq, &b->board);
+@@ -416,7 +410,6 @@
+       release_region(b->iobase, 8);
+ }
+-#ifdef MODULE
+ static int io=0x238;
+ static int txdma=1;
+@@ -441,20 +434,22 @@
+ static struct slvl_board *slvl_unit;
+-int init_module(void)
++static int __init slvl_init_module(void)
+ {
++#ifdef MODULE
+       printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.02.\n");
+-      printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");   
+-      if((slvl_unit=slvl_init(io,irq, txdma, rxdma, slow))==NULL)
+-              return -ENODEV;
+-      return 0;
++      printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");
++#endif
++      slvl_unit = slvl_init(io, irq, txdma, rxdma, slow);
++
++      return slvl_unit ? 0 : -ENODEV;
+ }
+-void cleanup_module(void)
++static void __exit slvl_cleanup_module(void)
+ {
+       if(slvl_unit)
+               slvl_shutdown(slvl_unit);
+ }
+-#endif
+-
++module_init(slvl_init_module);
++module_exit(slvl_cleanup_module);
+Index: linux-2.6.0-test5/drivers/net/wan/wanpipe_multppp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanpipe_multppp.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanpipe_multppp.c        2003-09-27 11:38:28.616178064 +0800
+@@ -18,7 +18,6 @@
+ *****************************************************************************/
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>     /* printk(), and other useful stuff */
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+Index: linux-2.6.0-test5/drivers/net/wan/wanxl.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxl.c     2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxl.c  2003-09-27 11:38:28.618177760 +0800
+@@ -0,0 +1,836 @@
++/*
++ * wanXL serial card driver for Linux
++ * host part
++ *
++ * Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>
++ *
++ * 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.
++ *
++ * Status:
++ *   - Only DTE (external clock) support with NRZ and NRZI encodings
++ *   - wanXL100 will require minor driver modifications, no access to hw
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/netdevice.h>
++#include <linux/hdlc.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++
++#include "wanxl.h"
++
++static const char* version = "wanXL serial card driver version: 0.46";
++
++#define PLX_CTL_RESET   0x40000000 /* adapter reset */
++
++#undef DEBUG_PKT
++#define DEBUG_PCI
++
++/* MAILBOX #1 - PUTS COMMANDS */
++#define MBX1_CMD_ABORTJ 0x85000000 /* Abort and Jump */
++#ifdef __LITTLE_ENDIAN
++#define MBX1_CMD_BSWAP  0x8C000001 /* little-endian Byte Swap Mode */
++#else
++#define MBX1_CMD_BSWAP  0x8C000000 /* big-endian Byte Swap Mode */
++#endif
++
++/* MAILBOX #2 - DRAM SIZE */
++#define MBX2_MEMSZ_MASK 0xFFFF0000 /* PUTS Memory Size Register mask */
++
++
++typedef struct {
++      hdlc_device hdlc;       /* HDLC device struct - must be first */
++      struct card_t *card;
++      spinlock_t lock;        /* for wanxl_xmit */
++        int node;             /* physical port #0 - 3 */
++      unsigned int clock_type;
++      int tx_in, tx_out;
++      struct sk_buff *tx_skbs[TX_BUFFERS];
++}port_t;
++
++
++typedef struct {
++      desc_t rx_descs[RX_QUEUE_LENGTH];
++      port_status_t port_status[4];
++}card_status_t;
++
++
++typedef struct card_t {
++      int n_ports;            /* 1, 2 or 4 ports */
++      u8 irq;
++
++      u8 *plx;                /* PLX PCI9060 virtual base address */
++      struct pci_dev *pdev;   /* for pdev->slot_name */
++      port_t *ports[4];
++      int rx_in;
++      struct sk_buff *rx_skbs[RX_QUEUE_LENGTH];
++      card_status_t *status;  /* shared between host and card */
++      dma_addr_t status_address;
++}card_t;
++
++
++
++static inline port_t* hdlc_to_port(hdlc_device *hdlc)
++{
++        return (port_t*)hdlc;
++}
++
++
++static inline port_t* dev_to_port(struct net_device *dev)
++{
++        return hdlc_to_port(dev_to_hdlc(dev));
++}
++
++
++static inline struct net_device *port_to_dev(port_t* port)
++{
++        return hdlc_to_dev(&port->hdlc);
++}
++
++
++static inline const char* port_name(port_t *port)
++{
++      return hdlc_to_name((hdlc_device*)port);
++}
++
++
++static inline const char* card_name(struct pci_dev *pdev)
++{
++      return pdev->slot_name;
++}
++
++
++static inline port_status_t* get_status(port_t *port)
++{
++      return &port->card->status->port_status[port->node];
++}
++
++
++#ifdef DEBUG_PCI
++static inline dma_addr_t pci_map_single_debug(struct pci_dev *pdev, void *ptr,
++                                            size_t size, int direction)
++{
++      dma_addr_t addr = pci_map_single(pdev, ptr, size, direction);
++      if (addr + size > 0x100000000LL)
++              printk(KERN_CRIT "wanXL %s: pci_map_single() returned memory"
++                     " at 0x%X!\n", card_name(pdev), addr);
++      return addr;
++}
++
++#undef pci_map_single
++#define pci_map_single pci_map_single_debug
++#endif
++
++
++/* Cable and/or personality module change interrupt service */
++static inline void wanxl_cable_intr(port_t *port)
++{
++      u32 value = get_status(port)->cable;
++      int valid = 1;
++      const char *cable, *pm, *dte = "", *dsr = "", *dcd = "";
++
++      switch(value & 0x7) {
++      case STATUS_CABLE_V35: cable = "V.35"; break;
++      case STATUS_CABLE_X21: cable = "X.21"; break;
++      case STATUS_CABLE_V24: cable = "V.24"; break;
++      case STATUS_CABLE_EIA530: cable = "EIA530"; break;
++      case STATUS_CABLE_NONE: cable = "no"; break;
++      default: cable = "invalid";
++      }
++
++      switch((value >> STATUS_CABLE_PM_SHIFT) & 0x7) {
++      case STATUS_CABLE_V35: pm = "V.35"; break;
++      case STATUS_CABLE_X21: pm = "X.21"; break;
++      case STATUS_CABLE_V24: pm = "V.24"; break;
++      case STATUS_CABLE_EIA530: pm = "EIA530"; break;
++      case STATUS_CABLE_NONE: pm = "no personality"; valid = 0; break;
++      default: pm = "invalid personality"; valid = 0;
++      }
++
++      if (valid) {
++              if ((value & 7) == ((value >> STATUS_CABLE_PM_SHIFT) & 7)) {
++                      dsr = (value & STATUS_CABLE_DSR) ? ", DSR ON" :
++                              ", DSR off";
++                      dcd = (value & STATUS_CABLE_DCD) ? ", carrier ON" :
++                              ", carrier off";
++              }
++              dte = (value & STATUS_CABLE_DCE) ? " DCE" : " DTE";
++      }
++      printk(KERN_INFO "%s: %s%s module, %s cable%s%s\n",
++             port_name(port), pm, dte, cable, dsr, dcd);
++
++      hdlc_set_carrier(value & STATUS_CABLE_DCD, &port->hdlc);
++}
++
++
++
++/* Transmit complete interrupt service */
++static inline void wanxl_tx_intr(port_t *port)
++{
++      while (1) {
++                desc_t *desc;
++              desc = &get_status(port)->tx_descs[port->tx_in];
++              struct sk_buff *skb = port->tx_skbs[port->tx_in];
++
++              switch (desc->stat) {
++              case PACKET_FULL:
++              case PACKET_EMPTY:
++                      netif_wake_queue(port_to_dev(port));
++                      return;
++
++              case PACKET_UNDERRUN:
++                      port->hdlc.stats.tx_errors++;
++                      port->hdlc.stats.tx_fifo_errors++;
++                      break;
++
++              default:
++                      port->hdlc.stats.tx_packets++;
++                      port->hdlc.stats.tx_bytes += skb->len;
++              }
++                desc->stat = PACKET_EMPTY; /* Free descriptor */
++              pci_unmap_single(port->card->pdev, desc->address, skb->len,
++                               PCI_DMA_TODEVICE);
++              dev_kfree_skb_irq(skb);
++                port->tx_in = (port->tx_in + 1) % TX_BUFFERS;
++        }
++}
++
++
++
++/* Receive complete interrupt service */
++static inline void wanxl_rx_intr(card_t *card)
++{
++      desc_t *desc;
++      while(desc = &card->status->rx_descs[card->rx_in],
++            desc->stat != PACKET_EMPTY) {
++              struct sk_buff *skb = card->rx_skbs[card->rx_in];
++              port_t *port = card->ports[desc->stat & PACKET_PORT_MASK];
++              struct net_device *dev = port_to_dev(port);
++
++              if ((desc->stat & PACKET_PORT_MASK) > card->n_ports)
++                      printk(KERN_CRIT "wanXL %s: received packet for"
++                             " nonexistent port\n", card_name(card->pdev));
++
++              else if (!skb)
++                      port->hdlc.stats.rx_dropped++;
++
++              else {
++                      pci_unmap_single(card->pdev, desc->address,
++                                       BUFFER_LENGTH, PCI_DMA_FROMDEVICE);
++                      skb_put(skb, desc->length);
++
++#ifdef DEBUG_PKT
++                      printk(KERN_DEBUG "%s RX(%i):", port_name(port),
++                             skb->len);
++                      debug_frame(skb);
++#endif
++                      port->hdlc.stats.rx_packets++;
++                      port->hdlc.stats.rx_bytes += skb->len;
++                      skb->mac.raw = skb->data;
++                      skb->dev = dev;
++                      dev->last_rx = jiffies;
++                      skb->protocol = hdlc_type_trans(skb, dev);
++                      netif_rx(skb);
++                      skb = NULL;
++              }
++
++              if (!skb) {
++                      skb = dev_alloc_skb(BUFFER_LENGTH);
++                      desc->address = skb ?
++                              pci_map_single(card->pdev, skb->data,
++                                             BUFFER_LENGTH,
++                                             PCI_DMA_FROMDEVICE) : 0;
++                      card->rx_skbs[card->rx_in] = skb;
++              }
++              desc->stat = PACKET_EMPTY; /* Free descriptor */
++              card->rx_in = (card->rx_in + 1) % RX_QUEUE_LENGTH;
++      }
++}
++
++
++
++static irqreturn_t wanxl_intr(int irq, void* dev_id, struct pt_regs *regs)
++{
++        card_t *card = dev_id;
++        int i;
++        u32 stat;
++        int handled = 0;
++
++
++        while((stat = readl(card->plx + PLX_DOORBELL_FROM_CARD)) != 0) {
++                handled = 1;
++              writel(stat, card->plx + PLX_DOORBELL_FROM_CARD);
++
++                for (i = 0; i < card->n_ports; i++) {
++                      if (stat & (1 << (DOORBELL_FROM_CARD_TX_0 + i)))
++                              wanxl_tx_intr(card->ports[i]);
++                      if (stat & (1 << (DOORBELL_FROM_CARD_CABLE_0 + i)))
++                              wanxl_cable_intr(card->ports[i]);
++              }
++              if (stat & (1 << DOORBELL_FROM_CARD_RX))
++                      wanxl_rx_intr(card);
++        }
++
++        return IRQ_RETVAL(handled);
++}
++
++
++
++static int wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++        port_t *port = hdlc_to_port(hdlc);
++
++        spin_lock(&port->lock);
++
++      desc_t *desc = &get_status(port)->tx_descs[port->tx_out];
++        if (desc->stat != PACKET_EMPTY) {
++                /* should never happen - previous xmit should stop queue */
++#ifdef DEBUG_PKT
++                printk(KERN_DEBUG "%s: transmitter buffer full\n",
++                     port_name(port));
++#endif
++              netif_stop_queue(dev);
++              spin_unlock_irq(&port->lock);
++              return 1;       /* request packet to be queued */
++      }
++
++#ifdef DEBUG_PKT
++      printk(KERN_DEBUG "%s TX(%i):", port_name(port), skb->len);
++      debug_frame(skb);
++#endif
++
++      port->tx_skbs[port->tx_out] = skb;
++      desc->address = pci_map_single(port->card->pdev, skb->data, skb->len,
++                                     PCI_DMA_TODEVICE);
++      desc->length = skb->len;
++      desc->stat = PACKET_FULL;
++      writel(1 << (DOORBELL_TO_CARD_TX_0 + port->node),
++             port->card->plx + PLX_DOORBELL_TO_CARD);
++      dev->trans_start = jiffies;
++
++      port->tx_out = (port->tx_out + 1) % TX_BUFFERS;
++
++      if (get_status(port)->tx_descs[port->tx_out].stat != PACKET_EMPTY) {
++              netif_stop_queue(dev);
++#ifdef DEBUG_PKT
++              printk(KERN_DEBUG "%s: transmitter buffer full\n",
++                     port_name(port));
++#endif
++      }
++
++      spin_unlock(&port->lock);
++      return 0;
++}
++
++
++
++static int wanxl_attach(hdlc_device *hdlc, unsigned short encoding,
++                      unsigned short parity)
++{
++      port_t *port = hdlc_to_port(hdlc);
++
++      if (encoding != ENCODING_NRZ &&
++          encoding != ENCODING_NRZI)
++              return -EINVAL;
++
++      if (parity != PARITY_NONE &&
++          parity != PARITY_CRC32_PR1_CCITT &&
++          parity != PARITY_CRC16_PR1_CCITT &&
++          parity != PARITY_CRC32_PR0_CCITT &&
++          parity != PARITY_CRC16_PR0_CCITT)
++              return -EINVAL;
++
++      get_status(port)->encoding = encoding;
++      get_status(port)->parity = parity;
++      return 0;
++}
++
++
++
++static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
++{
++      const size_t size = sizeof(sync_serial_settings);
++      sync_serial_settings line;
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++      port_t *port = hdlc_to_port(hdlc);
++
++      if (cmd != SIOCWANDEV)
++              return hdlc_ioctl(dev, ifr, cmd);
++
++      switch (ifr->ifr_settings.type) {
++      case IF_GET_IFACE:
++              ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
++              if (ifr->ifr_settings.size < size) {
++                      ifr->ifr_settings.size = size; /* data size wanted */
++                      return -ENOBUFS;
++              }
++              line.clock_type = get_status(port)->clocking;
++              line.clock_rate = 0;
++              line.loopback = 0;
++
++              if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &line, size))
++                      return -EFAULT;
++              return 0;
++
++      case IF_IFACE_SYNC_SERIAL:
++              if (!capable(CAP_NET_ADMIN))
++                      return -EPERM;
++              if (dev->flags & IFF_UP)
++                      return -EBUSY;
++
++              if (copy_from_user(&line, ifr->ifr_settings.ifs_ifsu.sync,
++                                 size))
++                      return -EFAULT;
++
++              if (line.clock_type != CLOCK_EXT &&
++                  line.clock_type != CLOCK_TXFROMRX)
++                      return -EINVAL; /* No such clock setting */
++
++              if (line.loopback != 0)
++                      return -EINVAL;
++
++              get_status(port)->clocking = line.clock_type;
++              return 0;
++
++      default:
++              return hdlc_ioctl(dev, ifr, cmd);
++        }
++}
++
++
++
++static int wanxl_open(struct net_device *dev)
++{
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++      port_t *port = hdlc_to_port(hdlc);
++      u8 *dbr = port->card->plx + PLX_DOORBELL_TO_CARD;
++      unsigned long timeout;
++      int i;
++
++      if (get_status(port)->open) {
++              printk(KERN_ERR "%s: port already open\n", port_name(port));
++              return -EIO;
++      }
++      if ((i = hdlc_open(hdlc)) != 0)
++              return i;
++
++      port->tx_in = port->tx_out = 0;
++      for (i = 0; i < TX_BUFFERS; i++)
++              get_status(port)->tx_descs[i].stat = PACKET_EMPTY;
++      /* signal the card */
++      writel(1 << (DOORBELL_TO_CARD_OPEN_0 + port->node), dbr);
++
++      timeout = jiffies + HZ;
++      do
++              if (get_status(port)->open)
++                      return 0;
++      while (time_after(timeout, jiffies));
++
++      printk(KERN_ERR "%s: unable to open port\n", port_name(port));
++      /* ask the card to close the port, should it be still alive */
++      writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr);
++      return -EFAULT;
++}
++
++
++
++static int wanxl_close(struct net_device *dev)
++{
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++      port_t *port = hdlc_to_port(hdlc);
++      unsigned long timeout;
++      int i;
++
++      hdlc_close(hdlc);
++      /* signal the card */
++      writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node),
++             port->card->plx + PLX_DOORBELL_TO_CARD);
++
++      timeout = jiffies + HZ;
++      do
++              if (!get_status(port)->open)
++                      break;
++      while (time_after(timeout, jiffies));
++
++      if (get_status(port)->open)
++              printk(KERN_ERR "%s: unable to close port\n", port_name(port));
++
++      for (i = 0; i < TX_BUFFERS; i++) {
++              desc_t *desc = &get_status(port)->tx_descs[i];
++
++              if (desc->stat != PACKET_EMPTY) {
++                      desc->stat = PACKET_EMPTY;
++                      pci_unmap_single(port->card->pdev, desc->address,
++                                       port->tx_skbs[i]->len,
++                                       PCI_DMA_TODEVICE);
++                      dev_kfree_skb(port->tx_skbs[i]);
++              }
++      }
++      return 0;
++}
++
++
++
++static struct net_device_stats *wanxl_get_stats(struct net_device *dev)
++{
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++      port_t *port = hdlc_to_port(hdlc);
++
++      hdlc->stats.rx_over_errors = get_status(port)->rx_overruns;
++      hdlc->stats.rx_frame_errors = get_status(port)->rx_frame_errors;
++      hdlc->stats.rx_errors = hdlc->stats.rx_over_errors +
++              hdlc->stats.rx_frame_errors;
++        return &hdlc->stats;
++}
++
++
++
++static int wanxl_puts_command(card_t *card, u32 cmd)
++{
++      unsigned long timeout = jiffies + 5 * HZ;
++
++      writel(cmd, card->plx + PLX_MAILBOX_1);
++      do {
++              if (readl(card->plx + PLX_MAILBOX_1) == 0)
++                      return 0;
++
++              schedule();
++      }while (time_after(timeout, jiffies));
++
++      return -1;
++}
++
++
++
++static void wanxl_reset(card_t *card)
++{
++      u32 old_value = readl(card->plx + PLX_CONTROL) & ~PLX_CTL_RESET;
++
++      writel(0x80, card->plx + PLX_MAILBOX_0);
++      writel(old_value | PLX_CTL_RESET, card->plx + PLX_CONTROL);
++      readl(card->plx + PLX_CONTROL); /* wait for posted write */
++      udelay(1);
++      writel(old_value, card->plx + PLX_CONTROL);
++      readl(card->plx + PLX_CONTROL); /* wait for posted write */
++}
++
++
++
++static void wanxl_pci_remove_one(struct pci_dev *pdev)
++{
++      card_t *card = pci_get_drvdata(pdev);
++      int i;
++
++      /* unregister and free all host resources */
++      if (card->irq)
++              free_irq(card->irq, card);
++
++      for (i = 0; i < 4; i++)
++              if (card->ports[i])
++                      unregister_hdlc_device(&card->ports[i]->hdlc);
++
++      wanxl_reset(card);
++
++      for (i = 0; i < RX_QUEUE_LENGTH; i++)
++              if (card->rx_skbs[i]) {
++                      pci_unmap_single(card->pdev,
++                                       card->status->rx_descs[i].address,
++                                       BUFFER_LENGTH, PCI_DMA_FROMDEVICE);
++                      dev_kfree_skb(card->rx_skbs[i]);
++              }
++
++      if (card->plx)
++              iounmap(card->plx);
++
++      if (card->status)
++              pci_free_consistent(pdev, sizeof(card_status_t),
++                                  card->status, card->status_address);
++
++      pci_set_drvdata(pdev, NULL);
++      kfree(card);
++      pci_release_regions(pdev);
++}
++
++
++#include "wanxlfw.inc"
++
++static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
++                                      const struct pci_device_id *ent)
++{
++      card_t *card;
++      u32 ramsize, stat;
++      unsigned long timeout;
++      u32 plx_phy;            /* PLX PCI base address */
++      u32 mem_phy;            /* memory PCI base addr */
++      u8 *mem;                /* memory virtual base addr */
++      int i, ports, alloc_size;
++
++      i = pci_enable_device(pdev);
++      if (i)
++              return i;
++
++      /* QUICC can only access first 256 MB of host RAM directly,
++         but PLX9060 DMA does 32-bits for actual packet data transfers */
++
++      /* FIXME when PCI/DMA subsystems are fixed.
++         We set both dma_mask and consistent_dma_mask to 28 bits
++         and pray pci_alloc_consistent() will use this info. It should
++         work on most platforms */
++      if (pci_set_consistent_dma_mask(pdev, 0x0FFFFFFF) ||
++          pci_set_dma_mask(pdev, 0x0FFFFFFF)) {
++              printk(KERN_ERR "No usable DMA configuration\n");
++              return -EIO;
++      }
++
++      i = pci_request_regions(pdev, "wanXL");
++      if (i)
++              return i;
++
++      switch (pdev->device) {
++      case PCI_DEVICE_ID_SBE_WANXL100: ports = 1; break;
++      case PCI_DEVICE_ID_SBE_WANXL200: ports = 2; break;
++      default: ports = 4;
++      }
++
++      alloc_size = sizeof(card_t) + ports * sizeof(port_t);
++      card = kmalloc(alloc_size, GFP_KERNEL);
++      if (card == NULL) {
++              printk(KERN_ERR "wanXL %s: unable to allocate memory\n",
++                     card_name(pdev));
++              pci_release_regions(pdev);
++              return -ENOBUFS;
++      }
++      memset(card, 0, alloc_size);
++
++      pci_set_drvdata(pdev, card);
++      card->pdev = pdev;
++      card->n_ports = ports;
++
++      card->status = pci_alloc_consistent(pdev, sizeof(card_status_t),
++                                          &card->status_address);
++      if (card->status == NULL) {
++              wanxl_pci_remove_one(pdev);
++              return -ENOBUFS;
++      }
++
++#ifdef DEBUG_PCI
++      printk(KERN_DEBUG "wanXL %s: pci_alloc_consistent() returned memory"
++             " at 0x%X\n", card_name(pdev), card->status_address);
++#endif
++
++      /* FIXME when PCI/DMA subsystems are fixed.
++         We set both dma_mask and consistent_dma_mask back to 32 bits
++         to indicate the card can do 32-bit DMA addressing */
++      if (pci_set_consistent_dma_mask(pdev, 0xFFFFFFFF) ||
++          pci_set_dma_mask(pdev, 0xFFFFFFFF)) {
++              printk(KERN_ERR "No usable DMA configuration\n");
++              wanxl_pci_remove_one(pdev);
++              return -EIO;
++      }
++
++      /* set up PLX mapping */
++      plx_phy = pci_resource_start(pdev, 0);
++      card->plx = ioremap_nocache(plx_phy, 0x70);
++
++#if RESET_WHILE_LOADING
++      wanxl_reset(card);
++#endif
++
++      timeout = jiffies + 20 * HZ;
++      while ((stat = readl(card->plx + PLX_MAILBOX_0)) != 0) {
++              if (time_before(timeout, jiffies)) {
++                      printk(KERN_WARNING "wanXL %s: timeout waiting for"
++                             " PUTS to complete\n", card_name(pdev));
++                      wanxl_pci_remove_one(pdev);
++                      return -ENODEV;
++              }
++
++              switch(stat & 0xC0) {
++              case 0x00:      /* hmm - PUTS completed with non-zero code? */
++              case 0x80:      /* PUTS still testing the hardware */
++                      break;
++
++              default:
++                      printk(KERN_WARNING "wanXL %s: PUTS test 0x%X"
++                             " failed\n", card_name(pdev), stat & 0x30);
++                      wanxl_pci_remove_one(pdev);
++                      return -ENODEV;
++              }
++
++              schedule();
++      }
++
++      /* get on-board memory size (PUTS detects no more than 4 MB) */
++      ramsize = readl(card->plx + PLX_MAILBOX_2) & MBX2_MEMSZ_MASK;
++
++      /* set up on-board RAM mapping */
++      mem_phy = pci_resource_start(pdev, 2);
++
++
++      /* sanity check the board's reported memory size */
++      if (ramsize < BUFFERS_ADDR +
++          (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * ports) {
++              printk(KERN_WARNING "wanXL %s: no enough on-board RAM"
++                     " (%u bytes detected, %u bytes required)\n",
++                     card_name(pdev), ramsize, BUFFERS_ADDR +
++                     (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * ports);
++              wanxl_pci_remove_one(pdev);
++              return -ENODEV;
++      }
++
++      if (wanxl_puts_command(card, MBX1_CMD_BSWAP)) {
++              printk(KERN_WARNING "wanXL %s: unable to Set Byte Swap"
++                     " Mode\n", card_name(pdev));
++              wanxl_pci_remove_one(pdev);
++              return -ENODEV;
++      }
++
++      for (i = 0; i < ports; i++) {
++              port_t *port = (void *)card + sizeof(card_t) +
++                      i * sizeof(port_t);
++              struct net_device *dev = hdlc_to_dev(&port->hdlc);
++              spin_lock_init(&port->lock);
++              SET_MODULE_OWNER(dev);
++              dev->tx_queue_len = 50;
++              dev->do_ioctl = wanxl_ioctl;
++              dev->open = wanxl_open;
++              dev->stop = wanxl_close;
++              port->hdlc.attach = wanxl_attach;
++              port->hdlc.xmit = wanxl_xmit;
++              if(register_hdlc_device(&port->hdlc)) {
++                      printk(KERN_ERR "wanXL %s: unable to register hdlc"
++                             " device\n", card_name(pdev));
++                      wanxl_pci_remove_one(pdev);
++                      return -ENOBUFS;
++              }
++              card->ports[i] = port;
++              dev->get_stats = wanxl_get_stats;
++              port->card = card;
++              port->node = i;
++              get_status(port)->clocking = CLOCK_EXT;
++      }
++
++      for (i = 0; i < RX_QUEUE_LENGTH; i++) {
++              struct sk_buff *skb = dev_alloc_skb(BUFFER_LENGTH);
++              card->rx_skbs[i] = skb;
++              if (skb)
++                      card->status->rx_descs[i].address =
++                              pci_map_single(card->pdev, skb->data,
++                                             BUFFER_LENGTH,
++                                             PCI_DMA_FROMDEVICE);
++      }
++
++      mem = ioremap_nocache(mem_phy, PDM_OFFSET + sizeof(firmware));
++      for (i = 0; i < sizeof(firmware); i += 4)
++              writel(htonl(*(u32*)(firmware + i)), mem + PDM_OFFSET + i);
++
++      for (i = 0; i < ports; i++)
++              writel(card->status_address +
++                     (void *)&card->status->port_status[i] -
++                     (void *)card->status, mem + PDM_OFFSET + 4 + i * 4);
++      writel(card->status_address, mem + PDM_OFFSET + 20);
++      writel(PDM_OFFSET, mem);
++      iounmap(mem);
++
++      writel(0, card->plx + PLX_MAILBOX_5);
++
++      if (wanxl_puts_command(card, MBX1_CMD_ABORTJ)) {
++              printk(KERN_WARNING "wanXL %s: unable to Abort and Jump\n",
++                     card_name(pdev));
++              wanxl_pci_remove_one(pdev);
++              return -ENODEV;
++      }
++
++      stat = 0;
++      timeout = jiffies + 5 * HZ;
++      do {
++              if ((stat = readl(card->plx + PLX_MAILBOX_5)) != 0)
++                      break;
++              schedule();
++      }while (time_after(timeout, jiffies));
++
++      if (!stat) {
++              printk(KERN_WARNING "wanXL %s: timeout while initializing card"
++                     "firmware\n", card_name(pdev));
++              wanxl_pci_remove_one(pdev);
++              return -ENODEV;
++      }
++
++#if DETECT_RAM
++      ramsize = stat;
++#endif
++
++      printk(KERN_INFO "wanXL %s: at 0x%X, %u KB of RAM at 0x%X, irq"
++             " %u\n" KERN_INFO "wanXL %s: port", card_name(pdev),
++             plx_phy, ramsize / 1024, mem_phy, pdev->irq, card_name(pdev));
++
++      for (i = 0; i < ports; i++)
++              printk("%s #%i: %s", i ? "," : "", i,
++                     port_name(card->ports[i]));
++      printk("\n");
++
++      /* Allocate IRQ */
++      if(request_irq(pdev->irq, wanxl_intr, SA_SHIRQ, "wanXL", card)) {
++              printk(KERN_WARNING "wanXL %s: could not allocate IRQ%i.\n",
++                     card_name(pdev), pdev->irq);
++              wanxl_pci_remove_one(pdev);
++              return -EBUSY;
++      }
++      card->irq = pdev->irq;
++
++      return 0;
++}
++
++static struct pci_device_id wanxl_pci_tbl[] __devinitdata = {
++      { PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL100, PCI_ANY_ID,
++        PCI_ANY_ID, 0, 0, 0 },
++      { PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL200, PCI_ANY_ID,
++        PCI_ANY_ID, 0, 0, 0 },
++      { PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_SBE_WANXL400, PCI_ANY_ID,
++        PCI_ANY_ID, 0, 0, 0 },
++      { 0, }
++};
++
++
++static struct pci_driver wanxl_pci_driver = {
++      name:           "wanXL",
++      id_table:       wanxl_pci_tbl,
++      probe:          wanxl_pci_init_one,
++      remove:         wanxl_pci_remove_one,
++};
++
++
++static int __init wanxl_init_module(void)
++{
++#ifdef MODULE
++      printk(KERN_INFO "%s\n", version);
++#endif
++      return pci_module_init(&wanxl_pci_driver);
++}
++
++static void __exit wanxl_cleanup_module(void)
++{
++      pci_unregister_driver(&wanxl_pci_driver);
++}
++
++
++MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
++MODULE_DESCRIPTION("SBE Inc. wanXL serial port driver");
++MODULE_LICENSE("GPL v2");
++MODULE_DEVICE_TABLE(pci, wanxl_pci_tbl);
++
++module_init(wanxl_init_module);
++module_exit(wanxl_cleanup_module);
+Index: linux-2.6.0-test5/drivers/net/wan/wanxlfw.inc
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxlfw.inc 2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxlfw.inc      2003-09-27 11:38:28.619177608 +0800
+@@ -0,0 +1,158 @@
++static u8 firmware[]={
++0x60,0x00,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xB9,0x40,0x00,0x00,0x00,0x00,0x00,
++0x10,0x14,0x42,0x80,0x4A,0xB0,0x09,0xB0,0x00,0x00,0x10,0x04,0x67,0x00,0x00,0x0E,
++0x06,0xB0,0x40,0x00,0x00,0x00,0x09,0xB0,0x00,0x00,0x10,0x04,0x58,0x80,0x0C,0x80,
++0x00,0x00,0x00,0x10,0x66,0x00,0xFF,0xDE,0x21,0xFC,0x00,0x00,0x16,0xBC,0x00,0x6C,
++0x21,0xFC,0x00,0x00,0x17,0x5E,0x01,0x00,0x21,0xFC,0x00,0x00,0x16,0xDE,0x01,0x78,
++0x21,0xFC,0x00,0x00,0x16,0xFE,0x01,0x74,0x21,0xFC,0x00,0x00,0x17,0x1E,0x01,0x70,
++0x21,0xFC,0x00,0x00,0x17,0x3E,0x01,0x6C,0x21,0xFC,0x00,0x00,0x18,0x4C,0x02,0x00,
++0x23,0xFC,0x78,0x00,0x00,0x00,0xFF,0xFC,0x15,0x48,0x33,0xFC,0x04,0x80,0xFF,0xFC,
++0x10,0x26,0x33,0xFC,0x01,0x10,0xFF,0xFC,0x10,0x2A,0x23,0xFC,0x00,0xD4,0x9F,0x40,
++0xFF,0xFC,0x15,0x40,0x23,0xFC,0x00,0x00,0x05,0x43,0xFF,0xF9,0x01,0x00,0x23,0xFC,
++0x00,0x00,0x05,0x43,0xFF,0xF9,0x01,0x14,0x23,0xFC,0x00,0x00,0x00,0x00,0xFF,0xF9,
++0x01,0x10,0x23,0xFC,0x00,0x00,0x00,0x08,0xFF,0xF9,0x01,0x24,0x23,0xFC,0x00,0x00,
++0x01,0x01,0xFF,0xF9,0x01,0x28,0x00,0xB9,0x00,0x0F,0x03,0x00,0xFF,0xF9,0x00,0xE8,
++0x23,0xFC,0x00,0x00,0x00,0x01,0xFF,0xF9,0x00,0xD4,0x61,0x00,0x06,0x74,0x33,0xFC,
++0xFF,0xFF,0xFF,0xFC,0x15,0x52,0x42,0x79,0xFF,0xFC,0x15,0x50,0x42,0x79,0xFF,0xFC,
++0x15,0x64,0x2E,0x3A,0x08,0x50,0x42,0xB9,0x00,0x00,0x19,0x54,0x4A,0x87,0x66,0x00,
++0x00,0x0E,0x4E,0x72,0x22,0x00,0x46,0xFC,0x27,0x00,0x60,0x00,0xFF,0xE6,0x42,0x80,
++0x42,0x86,0x08,0x07,0x00,0x04,0x67,0x00,0x00,0x0A,0x08,0x87,0x00,0x00,0x61,0x00,
++0x02,0xA0,0x08,0x07,0x00,0x00,0x67,0x00,0x00,0x06,0x61,0x00,0x00,0x36,0x08,0x07,
++0x00,0x08,0x67,0x00,0x00,0x06,0x61,0x00,0x02,0xB8,0x08,0x07,0x00,0x0C,0x67,0x00,
++0x00,0x0A,0x61,0x00,0x04,0x94,0x61,0x00,0x03,0x60,0xE2,0x8F,0x58,0x80,0x0C,0x80,
++0x00,0x00,0x00,0x10,0x66,0x00,0xFF,0xBC,0x23,0xC6,0xFF,0xF9,0x00,0xE4,0x60,0x00,
++0xFF,0x92,0x20,0x70,0x09,0xB0,0x00,0x00,0x10,0x04,0x4A,0xA8,0x00,0x00,0x66,0x00,
++0x02,0x4E,0x21,0x7C,0x00,0x00,0x00,0x01,0x00,0x00,0x42,0xB0,0x09,0xB0,0x00,0x00,
++0x19,0x58,0x42,0xB0,0x09,0xB0,0x00,0x00,0x19,0x68,0x42,0xB0,0x09,0xB0,0x00,0x00,
++0x19,0x78,0x42,0xB0,0x09,0xB0,0x00,0x00,0x19,0x88,0x22,0x39,0xFF,0xFC,0x16,0xEC,
++0xC2,0xB0,0x09,0xB0,0x00,0x00,0x18,0xF2,0x0C,0xA8,0x00,0x00,0x00,0x04,0x00,0x18,
++0x66,0x00,0x00,0x0E,0x82,0xB0,0x09,0xB0,0x00,0x00,0x18,0xE2,0x60,0x00,0x00,0x0A,
++0x82,0xB0,0x09,0xB0,0x00,0x00,0x18,0xD2,0x23,0xC1,0xFF,0xFC,0x16,0xEC,0x00,0x70,
++0x10,0x00,0x09,0xB0,0x00,0x00,0x19,0xAA,0x61,0x00,0x05,0x76,0x22,0x30,0x09,0xB0,
++0x00,0x00,0x18,0x92,0x22,0x70,0x09,0xB0,0x00,0x00,0x18,0x72,0x74,0x08,0x26,0x3C,
++0x18,0x00,0x00,0x00,0x0C,0xA8,0x00,0x00,0x00,0x01,0x00,0x10,0x67,0x00,0x00,0x06,
++0x08,0xC3,0x00,0x1A,0x22,0xC3,0x22,0xC1,0x06,0x81,0x00,0x00,0x05,0xFC,0x51,0xCA,
++0xFF,0xF4,0x08,0xC3,0x00,0x1D,0x22,0xC3,0x22,0xC1,0x74,0x1C,0x22,0xFC,0x90,0x00,
++0x00,0x00,0x22,0xC1,0x06,0x81,0x00,0x00,0x05,0xFC,0x51,0xCA,0xFF,0xF0,0x22,0xFC,
++0xB0,0x00,0x00,0x00,0x22,0xC1,0x22,0x70,0x09,0xB0,0x00,0x00,0x18,0x62,0x24,0x70,
++0x09,0xB0,0x00,0x00,0x18,0x52,0x25,0x7C,0x00,0x00,0xFF,0xFF,0x00,0x10,0x25,0x7C,
++0x00,0x00,0x00,0x00,0x00,0x14,0x22,0x30,0x09,0xB0,0x00,0x00,0x18,0x72,0x33,0x41,
++0x00,0x02,0x06,0x81,0x00,0x00,0x00,0x50,0x33,0x41,0x00,0x00,0x13,0x7C,0x00,0x08,
++0x00,0x04,0x13,0x7C,0x00,0x08,0x00,0x05,0x0C,0xA8,0x00,0x00,0x00,0x05,0x00,0x10,
++0x66,0x00,0x00,0x2A,0x42,0x6A,0x00,0x08,0x23,0x7C,0x00,0x00,0xF0,0xB8,0x00,0x34,
++0x23,0x7C,0x00,0x00,0xFF,0xFF,0x00,0x38,0x33,0x7C,0x05,0xFA,0x00,0x46,0x31,0xBC,
++0x00,0x02,0x09,0xB0,0x00,0x00,0x19,0x9C,0x60,0x00,0x00,0xBC,0x0C,0xA8,0x00,0x00,
++0x00,0x07,0x00,0x10,0x66,0x00,0x00,0x2C,0x35,0x7C,0x08,0x00,0x00,0x08,0x23,0x7C,
++0xDE,0xBB,0x20,0xE3,0x00,0x34,0x23,0x7C,0xFF,0xFF,0xFF,0xFF,0x00,0x38,0x33,0x7C,
++0x05,0xFC,0x00,0x46,0x31,0xBC,0x00,0x04,0x09,0xB0,0x00,0x00,0x19,0x9C,0x60,0x00,
++0x00,0x86,0x0C,0xA8,0x00,0x00,0x00,0x04,0x00,0x10,0x66,0x00,0x00,0x26,0x42,0x6A,
++0x00,0x08,0x23,0x7C,0x00,0x00,0xF0,0xB8,0x00,0x34,0x42,0xA9,0x00,0x38,0x33,0x7C,
++0x05,0xFA,0x00,0x46,0x31,0xBC,0x00,0x02,0x09,0xB0,0x00,0x00,0x19,0x9C,0x60,0x00,
++0x00,0x56,0x0C,0xA8,0x00,0x00,0x00,0x06,0x00,0x10,0x66,0x00,0x00,0x28,0x35,0x7C,
++0x08,0x00,0x00,0x08,0x23,0x7C,0xDE,0xBB,0x20,0xE3,0x00,0x34,0x42,0xA9,0x00,0x38,
++0x33,0x7C,0x05,0xFC,0x00,0x46,0x31,0xBC,0x00,0x04,0x09,0xB0,0x00,0x00,0x19,0x9C,
++0x60,0x00,0x00,0x24,0x42,0x6A,0x00,0x08,0x23,0x7C,0x00,0x00,0xF0,0xB8,0x00,0x34,
++0x23,0x7C,0x00,0x00,0xFF,0xFF,0x00,0x38,0x33,0x7C,0x05,0xF8,0x00,0x46,0x42,0x70,
++0x09,0xB0,0x00,0x00,0x19,0x9C,0x25,0x7C,0x00,0x00,0x00,0x03,0x00,0x04,0x0C,0xA8,
++0x00,0x00,0x00,0x02,0x00,0x14,0x66,0x00,0x00,0x0E,0x25,0x7C,0x10,0x04,0x09,0x00,
++0x00,0x00,0x60,0x00,0x00,0x0A,0x25,0x7C,0x10,0x04,0x00,0x00,0x00,0x00,0x33,0x7C,
++0x05,0xFC,0x00,0x06,0x22,0x00,0xE9,0x89,0x00,0x81,0x00,0x00,0x00,0x01,0x33,0xC1,
++0xFF,0xFC,0x15,0xC0,0x08,0x39,0x00,0x00,0xFF,0xFC,0x15,0xC0,0x66,0x00,0xFF,0xF6,
++0x35,0x7C,0x00,0x1F,0x00,0x14,0x00,0xAA,0x00,0x00,0x00,0x30,0x00,0x00,0x4E,0x75,
++0x20,0x70,0x09,0xB0,0x00,0x00,0x18,0x52,0x42,0x68,0x00,0x14,0x02,0xA8,0xFF,0xFF,
++0xFF,0xCF,0x00,0x00,0x02,0x70,0xEF,0xFF,0x09,0xB0,0x00,0x00,0x19,0xAA,0x61,0x00,
++0x03,0x70,0x22,0x30,0x09,0xB0,0x00,0x00,0x10,0x04,0x42,0xB0,0x19,0x90,0x4E,0x75,
++0x0C,0xB0,0x00,0x00,0x00,0x0A,0x09,0xB0,0x00,0x00,0x19,0x78,0x67,0x00,0x00,0xA8,
++0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x68,0x24,0x01,0x4C,0x3C,0x20,0x00,0x00,0x00,
++0x00,0x0C,0xD4,0xB0,0x09,0xB0,0x00,0x00,0x10,0x04,0x06,0x82,0x00,0x00,0x00,0x1C,
++0x0C,0xB0,0x00,0x00,0x00,0x10,0x29,0x90,0x66,0x00,0x00,0x7C,0x20,0x70,0x29,0xA0,
++0x00,0x04,0xE7,0x89,0xD2,0xB0,0x09,0xB0,0x00,0x00,0x18,0x72,0x22,0x70,0x19,0xA0,
++0x00,0x04,0x24,0x30,0x29,0xA0,0x00,0x08,0x31,0x82,0x19,0xA0,0x00,0x02,0x56,0x82,
++0x02,0x82,0xFF,0xFF,0xFF,0xFC,0x23,0xC8,0xFF,0xF9,0x01,0x04,0x23,0xC9,0xFF,0xF9,
++0x01,0x08,0x23,0xC2,0xFF,0xF9,0x01,0x0C,0x23,0xFC,0x00,0x00,0x01,0x03,0xFF,0xF9,
++0x01,0x28,0x61,0x00,0x01,0xF6,0x08,0xF0,0x00,0x1F,0x19,0x90,0x22,0x30,0x09,0xB0,
++0x00,0x00,0x19,0x68,0x52,0x81,0x0C,0x81,0x00,0x00,0x00,0x0A,0x66,0x00,0x00,0x04,
++0x42,0x81,0x21,0x81,0x09,0xB0,0x00,0x00,0x19,0x68,0x52,0xB0,0x09,0xB0,0x00,0x00,
++0x19,0x78,0x60,0x00,0xFF,0x4C,0x4E,0x75,0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x88,
++0xE7,0x89,0xD2,0xB0,0x09,0xB0,0x00,0x00,0x18,0x82,0x34,0x30,0x19,0x90,0x08,0x02,
++0x00,0x0F,0x66,0x00,0x01,0x12,0x08,0x02,0x00,0x01,0x66,0x00,0x00,0xE6,0x4A,0x70,
++0x09,0xB0,0x00,0x00,0x19,0x9C,0x66,0x00,0x00,0x06,0x08,0x82,0x00,0x02,0x02,0x42,
++0x0C,0xBC,0x0C,0x42,0x0C,0x00,0x66,0x00,0x00,0xDC,0x42,0x83,0x36,0x30,0x19,0xA0,
++0x00,0x02,0x96,0x70,0x09,0xB0,0x00,0x00,0x19,0x9C,0x0C,0x43,0x05,0xF8,0x6E,0x00,
++0x00,0xC4,0x24,0x3A,0x04,0x84,0x4C,0x3C,0x20,0x00,0x00,0x00,0x00,0x0C,0xD4,0xBA,
++0xFA,0xF4,0x0C,0xB0,0x00,0x00,0x00,0x00,0x29,0x90,0x66,0x00,0x00,0x96,0x21,0x83,
++0x29,0xA0,0x00,0x08,0x20,0x70,0x19,0xA0,0x00,0x04,0x22,0x70,0x29,0xA0,0x00,0x04,
++0x4A,0x89,0x67,0x00,0x00,0x2A,0x56,0x83,0x02,0x83,0xFF,0xFF,0xFF,0xFC,0x23,0xC8,
++0xFF,0xF9,0x01,0x1C,0x23,0xC9,0xFF,0xF9,0x01,0x18,0x23,0xC3,0xFF,0xF9,0x01,0x20,
++0x23,0xFC,0x00,0x00,0x03,0x01,0xFF,0xF9,0x01,0x28,0x61,0x00,0x01,0x2C,0x21,0xB0,
++0x09,0xB0,0x00,0x00,0x18,0xC2,0x29,0x90,0x08,0xC6,0x00,0x04,0x24,0x3A,0x04,0x1A,
++0x52,0x82,0x0C,0x82,0x00,0x00,0x00,0x28,0x66,0x00,0x00,0x04,0x42,0x82,0x23,0xC2,
++0x00,0x00,0x19,0x98,0x02,0x70,0xF0,0x00,0x19,0x90,0x08,0xF0,0x00,0x1F,0x19,0x90,
++0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x88,0x52,0x81,0x0C,0x81,0x00,0x00,0x00,0x1E,
++0x66,0x00,0x00,0x04,0x42,0x81,0x21,0x81,0x09,0xB0,0x00,0x00,0x19,0x88,0x60,0x00,
++0xFE,0xF8,0x24,0x30,0x09,0xB0,0x00,0x00,0x10,0x04,0x52,0xB0,0x29,0xA0,0x00,0x08,
++0x60,0x00,0xFF,0xC2,0x24,0x30,0x09,0xB0,0x00,0x00,0x10,0x04,0x52,0xB0,0x29,0xA0,
++0x00,0x0C,0x60,0x00,0xFF,0xB0,0x4E,0x75,0x4A,0xB0,0x09,0xB0,0x00,0x00,0x19,0x78,
++0x67,0x00,0x00,0x86,0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x58,0x24,0x01,0xE7,0x89,
++0xD2,0xB0,0x09,0xB0,0x00,0x00,0x18,0x72,0x36,0x30,0x19,0x90,0x08,0x03,0x00,0x0F,
++0x66,0x00,0x00,0x66,0x8C,0xB0,0x09,0xB0,0x00,0x00,0x18,0xA2,0x53,0xB0,0x09,0xB0,
++0x00,0x00,0x19,0x78,0x22,0x30,0x09,0xB0,0x00,0x00,0x19,0x58,0x52,0x81,0x0C,0x81,
++0x00,0x00,0x00,0x0A,0x66,0x00,0x00,0x04,0x42,0x81,0x21,0x81,0x09,0xB0,0x00,0x00,
++0x19,0x58,0x4C,0x3C,0x20,0x00,0x00,0x00,0x00,0x0C,0xD4,0xB0,0x09,0xB0,0x00,0x00,
++0x10,0x04,0x06,0x82,0x00,0x00,0x00,0x1C,0x08,0x03,0x00,0x01,0x66,0x00,0x00,0x0E,
++0x21,0xBC,0x00,0x00,0x00,0x20,0x29,0x90,0x60,0x00,0xFF,0x7E,0x21,0xBC,0x00,0x00,
++0x00,0x30,0x29,0x90,0x60,0x00,0xFF,0x72,0x4E,0x75,0x2F,0x00,0x40,0xE7,0x20,0x39,
++0xFF,0xF9,0x01,0x28,0x08,0x00,0x00,0x04,0x66,0x00,0x00,0x2C,0x4E,0x72,0x22,0x00,
++0x46,0xFC,0x27,0x00,0x60,0x00,0xFF,0xE8,0x2F,0x00,0x40,0xE7,0x20,0x39,0xFF,0xF9,
++0x01,0x28,0x08,0x00,0x00,0x0C,0x66,0x00,0x00,0x0E,0x4E,0x72,0x22,0x00,0x46,0xFC,
++0x27,0x00,0x60,0x00,0xFF,0xE8,0x46,0xDF,0x20,0x1F,0x4E,0x75,0x2F,0x00,0x20,0x39,
++0xFF,0xF9,0x00,0xE0,0x23,0xC0,0xFF,0xF9,0x00,0xE0,0x81,0xB9,0x00,0x00,0x19,0x54,
++0x23,0xFC,0x00,0x00,0x09,0x09,0xFF,0xF9,0x01,0x28,0x20,0x1F,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x10,0x00,0xB9,0x00,0x00,0x10,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x40,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x30,0x00,0xB9,0x00,0x00,0x20,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x20,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x50,0x00,0xB9,0x00,0x00,0x40,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x10,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x00,0xB9,
++0x00,0x00,0x00,0x00,0xFF,0xFC,0x16,0x70,0x00,0xB9,0x00,0x00,0x80,0x00,0x00,0x00,
++0x19,0x54,0x23,0xFC,0x08,0x00,0x00,0x00,0xFF,0xFC,0x15,0x4C,0x4E,0x73,0x4E,0x73,
++0x2F,0x00,0x2F,0x01,0x2F,0x02,0x2F,0x08,0x2F,0x09,0x42,0x80,0x20,0x7C,0xFF,0xFB,
++0x00,0x00,0x32,0x10,0x02,0x81,0x00,0x00,0x00,0xE7,0x0C,0x41,0x00,0x42,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x0E,0x08,0x60,0x00,0x00,0x3E,0x0C,0x41,0x00,0x63,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x04,0x08,0x60,0x00,0x00,0x2E,0x0C,0x41,0x00,0x84,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x02,0x08,0x60,0x00,0x00,0x1E,0x0C,0x41,0x00,0xA5,0x66,0x00,
++0x00,0x0A,0x32,0x3C,0x0D,0x08,0x60,0x00,0x00,0x0E,0x32,0x3C,0x00,0x08,0x34,0x3C,
++0x80,0xE7,0x60,0x00,0x00,0x14,0x34,0x30,0x09,0xB0,0x00,0x00,0x19,0xAA,0x02,0x42,
++0x30,0x00,0x82,0x42,0x34,0x3C,0x80,0xFF,0xB2,0x70,0x09,0xB0,0x00,0x00,0x19,0xAC,
++0x67,0x00,0x00,0x0C,0x31,0x81,0x09,0xB0,0x00,0x00,0x19,0xAC,0x30,0x81,0x32,0x39,
++0xFF,0xFC,0x15,0x66,0xC2,0x70,0x09,0xB0,0x00,0x00,0x19,0x02,0x67,0x00,0x00,0x0C,
++0x32,0x10,0x02,0x41,0xFF,0xF7,0x60,0x00,0x00,0x08,0x32,0x10,0x00,0x41,0x00,0x08,
++0xC2,0x42,0x22,0x70,0x09,0xB0,0x00,0x00,0x10,0x04,0xB2,0xA9,0x00,0x04,0x67,0x00,
++0x00,0x12,0x23,0x41,0x00,0x04,0x23,0xF0,0x09,0xB0,0x00,0x00,0x18,0xB2,0xFF,0xF9,
++0x00,0xE4,0x54,0x88,0x58,0x80,0x0C,0x80,0x00,0x00,0x00,0x10,0x66,0x00,0xFF,0x34,
++0x22,0x5F,0x20,0x5F,0x24,0x1F,0x22,0x1F,0x20,0x1F,0x4E,0x75,0x61,0x00,0xFF,0x12,
++0x4E,0x73,0xFF,0xFC,0x16,0x00,0xFF,0xFC,0x16,0x20,0xFF,0xFC,0x16,0x40,0xFF,0xFC,
++0x16,0x60,0xFF,0xFC,0x0C,0x00,0xFF,0xFC,0x0D,0x00,0xFF,0xFC,0x0E,0x00,0xFF,0xFC,
++0x0F,0x00,0xFF,0xFC,0x00,0x00,0xFF,0xFC,0x01,0x40,0xFF,0xFC,0x02,0x80,0xFF,0xFC,
++0x03,0xC0,0xFF,0xFC,0x00,0x50,0xFF,0xFC,0x01,0x90,0xFF,0xFC,0x02,0xD0,0xFF,0xFC,
++0x04,0x10,0x00,0x00,0x40,0x00,0x00,0x01,0x2F,0x60,0x00,0x02,0x1E,0xC0,0x00,0x03,
++0x0E,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,
++0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,
++0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x12,0x00,0x00,
++0x00,0x13,0x00,0x00,0x00,0x2C,0x00,0x00,0x3E,0x00,0x00,0x2C,0x00,0x00,0x3E,0x00,
++0x00,0x00,0x00,0x00,0x00,0x2D,0x00,0x00,0x3F,0x00,0x00,0x2D,0x00,0x00,0x3F,0x00,
++0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,
++0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x08,0x00,
++0x77,0x61,0x6E,0x58,0x4C,0x20,0x66,0x69,0x72,0x6D,0x77,0x61,0x72,0x65,0x0A,0x43,
++0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x30,
++0x33,0x20,0x4B,0x72,0x7A,0x79,0x73,0x7A,0x74,0x6F,0x66,0x20,0x48,0x61,0x6C,0x61,
++0x73,0x61,0x20,0x3C,0x6B,0x68,0x63,0x40,0x70,0x6D,0x2E,0x77,0x61,0x77,0x2E,0x70,
++0x6C,0x3E,0x0A,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,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,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,0x00,0x00,0x00,
++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++};
+Index: linux-2.6.0-test5/drivers/net/wan/wanxlfw.S
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxlfw.S   2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxlfw.S        2003-09-27 11:38:28.621177304 +0800
+@@ -0,0 +1,895 @@
++.psize 0
++/*
++  wanXL serial card driver for Linux
++  card firmware part
++
++  Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>
++
++  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.
++
++
++
++
++      DPRAM BDs:
++      0x000 - 0x050 TX#0      0x050 - 0x140 RX#0
++      0x140 - 0x190 TX#1      0x190 - 0x280 RX#1
++      0x280 - 0x2D0 TX#2      0x2D0 - 0x3C0 RX#2
++      0x3C0 - 0x410 TX#3      0x410 - 0x500 RX#3
++
++
++      000 5FF 1536 Bytes Dual-Port RAM User Data / BDs
++      600 6FF 256 Bytes Dual-Port RAM User Data / BDs
++      700 7FF 256 Bytes Dual-Port RAM User Data / BDs
++      C00 CBF 192 Bytes Dual-Port RAM Parameter RAM Page 1
++      D00 DBF 192 Bytes Dual-Port RAM Parameter RAM Page 2
++      E00 EBF 192 Bytes Dual-Port RAM Parameter RAM Page 3
++      F00 FBF 192 Bytes Dual-Port RAM Parameter RAM Page 4
++
++      local interrupts                    level
++      NMI                                     7
++      PIT timer, CPM (RX/TX complete)         4
++      PCI9060 DMA and PCI doorbells           3
++      Cable - not used                        1
++*/
++
++#include <linux/hdlc.h>
++#include "wanxl.h"
++
++/* memory addresses and offsets */
++
++MAX_RAM_SIZE  = 16 * 1024 * 1024      // max RAM supported by hardware
++
++PCI9060_VECTOR        = 0x0000006C
++CPM_IRQ_BASE  = 0x40
++ERROR_VECTOR  = CPM_IRQ_BASE * 4
++SCC1_VECTOR   = (CPM_IRQ_BASE + 0x1E) * 4
++SCC2_VECTOR   = (CPM_IRQ_BASE + 0x1D) * 4
++SCC3_VECTOR   = (CPM_IRQ_BASE + 0x1C) * 4
++SCC4_VECTOR   = (CPM_IRQ_BASE + 0x1B) * 4
++CPM_IRQ_LEVEL = 4
++TIMER_IRQ     = 128
++TIMER_IRQ_LEVEL = 4
++PITR_CONST    = 0x100 + 16            // 1 Hz timer
++
++MBAR          = 0x0003FF00
++
++VALUE_WINDOW  = 0x40000000
++ORDER_WINDOW  = 0xC0000000
++
++PLX           = 0xFFF90000
++
++CSRA          = 0xFFFB0000
++CSRB          = 0xFFFB0002
++CSRC          = 0xFFFB0004
++CSRD          = 0xFFFB0006
++STATUS_CABLE_LL               = 0x2000
++STATUS_CABLE_DTR      = 0x1000
++
++DPRBASE               = 0xFFFC0000
++
++SCC1_BASE     = DPRBASE + 0xC00
++MISC_BASE     = DPRBASE + 0xCB0
++SCC2_BASE     = DPRBASE + 0xD00
++SCC3_BASE     = DPRBASE + 0xE00
++SCC4_BASE     = DPRBASE + 0xF00
++
++// offset from SCCx_BASE
++// SCC_xBASE contain offsets from DPRBASE and must be divisible by 8
++SCC_RBASE     = 0             // 16-bit RxBD base address
++SCC_TBASE     = 2             // 16-bit TxBD base address
++SCC_RFCR      = 4             // 8-bit Rx function code
++SCC_TFCR      = 5             // 8-bit Tx function code
++SCC_MRBLR     = 6             // 16-bit maximum Rx buffer length
++SCC_C_MASK    = 0x34          // 32-bit CRC constant
++SCC_C_PRES    = 0x38          // 32-bit CRC preset
++SCC_MFLR      = 0x46          // 16-bit max Rx frame length (without flags)
++
++REGBASE               = DPRBASE + 0x1000
++PICR          = REGBASE + 0x026       // 16-bit periodic irq control
++PITR          = REGBASE + 0x02A       // 16-bit periodic irq timing
++OR1           = REGBASE + 0x064       // 32-bit RAM bank #1 options
++CICR          = REGBASE + 0x540       // 32(24)-bit CP interrupt config
++CIMR          = REGBASE + 0x548       // 32-bit CP interrupt mask
++CISR          = REGBASE + 0x54C       // 32-bit CP interrupts in-service
++PADIR         = REGBASE + 0x550       // 16-bit PortA data direction bitmap
++PAPAR         = REGBASE + 0x552       // 16-bit PortA pin assignment bitmap
++PAODR         = REGBASE + 0x554       // 16-bit PortA open drain bitmap
++PADAT         = REGBASE + 0x556       // 16-bit PortA data register
++
++PCDIR         = REGBASE + 0x560       // 16-bit PortC data direction bitmap
++PCPAR         = REGBASE + 0x562       // 16-bit PortC pin assignment bitmap
++PCSO          = REGBASE + 0x564       // 16-bit PortC special options
++PCDAT         = REGBASE + 0x566       // 16-bit PortC data register
++PCINT         = REGBASE + 0x568       // 16-bit PortC interrupt control
++CR            = REGBASE + 0x5C0       // 16-bit Command register
++
++SCC1_REGS     = REGBASE + 0x600
++SCC2_REGS     = REGBASE + 0x620
++SCC3_REGS     = REGBASE + 0x640
++SCC4_REGS     = REGBASE + 0x660
++SICR          = REGBASE + 0x6EC       // 32-bit SI clock route
++
++// offset from SCCx_REGS
++SCC_GSMR_L    = 0x00  // 32 bits
++SCC_GSMR_H    = 0x04  // 32 bits
++SCC_PSMR      = 0x08  // 16 bits
++SCC_TODR      = 0x0C  // 16 bits
++SCC_DSR               = 0x0E  // 16 bits
++SCC_SCCE      = 0x10  // 16 bits
++SCC_SCCM      = 0x14  // 16 bits
++SCC_SCCS      = 0x17  // 8 bits
++
++#if QUICC_MEMCPY_USES_PLX
++      .macro memcpy_from_pci src, dest, len // len must be < 8 MB
++      addl #3, \len
++      andl #0xFFFFFFFC, \len          // always copy n * 4 bytes
++      movel \src, PLX_DMA_0_PCI
++      movel \dest, PLX_DMA_0_LOCAL
++      movel \len, PLX_DMA_0_LENGTH
++      movel #0x0103, PLX_DMA_CMD_STS  // start channel 0 transfer
++      bsr memcpy_from_pci_run
++      .endm
++
++      .macro memcpy_to_pci src, dest, len
++      addl #3, \len
++      andl #0xFFFFFFFC, \len          // always copy n * 4 bytes
++      movel \src, PLX_DMA_1_LOCAL
++      movel \dest, PLX_DMA_1_PCI
++      movel \len, PLX_DMA_1_LENGTH
++      movel #0x0301, PLX_DMA_CMD_STS  // start channel 1 transfer
++      bsr memcpy_to_pci_run
++      .endm
++
++#else
++
++      .macro memcpy src, dest, len    // len must be < 65536 bytes
++      movel %d7, -(%sp)               // src and dest must be < 256 MB
++      movel \len, %d7                 // bits 0 and 1
++      lsrl #2, \len
++      andl \len, \len
++      beq 99f                         // only 0 - 3 bytes
++      subl #1, \len                   // for dbf
++98:   movel (\src)+, (\dest)+
++      dbfw \len, 98b
++99:   movel %d7, \len
++      btstl #1, \len
++      beq 99f
++      movew (\src)+, (\dest)+
++99:   btstl #0, \len
++      beq 99f
++      moveb (\src)+, (\dest)+
++99:
++      movel (%sp)+, %d7
++      .endm
++
++      .macro memcpy_from_pci src, dest, len
++      addl #VALUE_WINDOW, \src
++      memcpy \src, \dest, \len
++      .endm
++
++      .macro memcpy_to_pci src, dest, len
++      addl #VALUE_WINDOW, \dest
++      memcpy \src, \dest, \len
++      .endm
++#endif
++
++
++      .macro wait_for_command
++99:   btstl #0, CR
++      bne 99b
++      .endm
++
++
++
++
++/****************************** card initialization *******************/
++      .text
++      .global _start
++_start:       bra init
++
++      .org _start + 4
++ch_status_addr:       .long 0, 0, 0, 0
++rx_descs_addr:        .long 0
++
++init:
++#if DETECT_RAM
++      movel OR1, %d0
++      andl #0xF00007FF, %d0           // mask AMxx bits
++      orl #0xFFFF800 & ~(MAX_RAM_SIZE - 1), %d0 // update RAM bank size
++      movel %d0, OR1
++#endif
++
++      addl #VALUE_WINDOW, rx_descs_addr // PCI addresses of shared data
++      clrl %d0                        // D0 = 4 * port
++init_1:       tstl ch_status_addr(%d0)
++      beq init_2
++      addl #VALUE_WINDOW, ch_status_addr(%d0)
++init_2:       addl #4, %d0
++      cmpl #4 * 4, %d0
++      bne init_1
++
++      movel #pci9060_interrupt, PCI9060_VECTOR
++      movel #error_interrupt, ERROR_VECTOR
++      movel #port_interrupt_1, SCC1_VECTOR
++      movel #port_interrupt_2, SCC2_VECTOR
++      movel #port_interrupt_3, SCC3_VECTOR
++      movel #port_interrupt_4, SCC4_VECTOR
++      movel #timer_interrupt, TIMER_IRQ * 4
++
++      movel #0x78000000, CIMR         // only SCCx IRQs from CPM
++      movew #(TIMER_IRQ_LEVEL << 8) + TIMER_IRQ, PICR // interrupt from PIT
++      movew #PITR_CONST, PITR
++
++      // SCC1=SCCa SCC2=SCCb SCC3=SCCc SCC4=SCCd prio=4 HP=-1 IRQ=64-79
++      movel #0xD41F40 + (CPM_IRQ_LEVEL << 13), CICR
++      movel #0x543, PLX_DMA_0_MODE    // 32-bit, Ready, Burst, IRQ
++      movel #0x543, PLX_DMA_1_MODE
++      movel #0x0, PLX_DMA_0_DESC      // from PCI to local
++      movel #0x8, PLX_DMA_1_DESC      // from local to PCI
++      movel #0x101, PLX_DMA_CMD_STS   // enable both DMA channels
++      // enable local IRQ, DMA, doorbells and PCI IRQ
++      orl #0x000F0300, PLX_INTERRUPT_CS
++
++#if DETECT_RAM
++      bsr ram_test
++#else
++      movel #1, PLX_MAILBOX_5         // non-zero value = init complete
++#endif
++      bsr check_csr
++
++      movew #0xFFFF, PAPAR            // all pins are clocks/data
++      clrw PADIR                      // first function
++      clrw PCSO                       // CD and CTS always active
++
++
++/****************************** main loop *****************************/
++
++main: movel channel_stats, %d7        // D7 = doorbell + irq status
++      clrl channel_stats
++
++      tstl %d7
++      bne main_1
++      // nothing to do - wait for next event
++      stop #0x2200                    // supervisor + IRQ level 2
++      movew #0x2700, %sr              // disable IRQs again
++      bra main
++
++main_1:       clrl %d0                        // D0 = 4 * port
++      clrl %d6                        // D6 = doorbell to host value
++
++main_l: btstl #DOORBELL_TO_CARD_CLOSE_0, %d7
++      beq main_op
++      bclrl #DOORBELL_TO_CARD_OPEN_0, %d7 // in case both bits are set
++      bsr close_port
++main_op:
++      btstl #DOORBELL_TO_CARD_OPEN_0, %d7
++      beq main_cl
++      bsr open_port
++main_cl:
++      btstl #DOORBELL_TO_CARD_TX_0, %d7
++      beq main_txend
++      bsr tx
++main_txend:
++      btstl #TASK_SCC_0, %d7
++      beq main_next
++      bsr tx_end
++      bsr rx
++
++main_next:
++      lsrl #1, %d7                    // port status for next port
++      addl #4, %d0                    // D0 = 4 * next port
++      cmpl #4 * 4, %d0
++      bne main_l
++      movel %d6, PLX_DOORBELL_FROM_CARD // signal the host
++      bra main
++
++
++/****************************** open port *****************************/
++
++open_port:                            // D0 = 4 * port, D6 = doorbell to host
++      movel ch_status_addr(%d0), %a0  // A0 = port status address
++      tstl STATUS_OPEN(%a0)
++      bne open_port_ret               // port already open
++      movel #1, STATUS_OPEN(%a0)      // confirm the port is open
++// setup BDs
++      clrl tx_in(%d0)
++      clrl tx_out(%d0)
++      clrl tx_count(%d0)
++      clrl rx_in(%d0)
++
++      movel SICR, %d1                 // D1 = clock settings in SICR
++      andl clocking_mask(%d0), %d1
++      cmpl #CLOCK_TXFROMRX, STATUS_CLOCKING(%a0)
++      bne open_port_clock_ext
++      orl clocking_txfromrx(%d0), %d1
++      bra open_port_set_clock
++
++open_port_clock_ext:
++      orl clocking_ext(%d0), %d1
++open_port_set_clock:
++      movel %d1, SICR                 // update clock settings in SICR
++
++      orw #STATUS_CABLE_DTR, csr_output(%d0)  // DTR on
++      bsr check_csr                   // call with disabled timer interrupt
++
++// Setup TX descriptors
++      movel first_buffer(%d0), %d1    // D1 = starting buffer address
++      movel tx_first_bd(%d0), %a1     // A1 = starting TX BD address
++      movel #TX_BUFFERS - 2, %d2      // D2 = TX_BUFFERS - 1 counter
++      movel #0x18000000, %d3          // D3 = initial TX BD flags: Int + Last
++      cmpl #PARITY_NONE, STATUS_PARITY(%a0)
++      beq open_port_tx_loop
++      bsetl #26, %d3                  // TX BD flag: Transmit CRC
++open_port_tx_loop:
++      movel %d3, (%a1)+               // TX flags + length
++      movel %d1, (%a1)+               // buffer address
++      addl #BUFFER_LENGTH, %d1
++      dbfw %d2, open_port_tx_loop
++
++      bsetl #29, %d3                  // TX BD flag: Wrap (last BD)
++      movel %d3, (%a1)+               // Final TX flags + length
++      movel %d1, (%a1)+               // buffer address
++
++// Setup RX descriptors                       // A1 = starting RX BD address
++      movel #RX_BUFFERS - 2, %d2      // D2 = RX_BUFFERS - 1 counter
++open_port_rx_loop:
++      movel #0x90000000, (%a1)+       // RX flags + length
++      movel %d1, (%a1)+               // buffer address
++      addl #BUFFER_LENGTH, %d1
++      dbfw %d2, open_port_rx_loop
++
++      movel #0xB0000000, (%a1)+       // Final RX flags + length
++      movel %d1, (%a1)+               // buffer address
++
++// Setup port parameters
++      movel scc_base_addr(%d0), %a1   // A1 = SCC_BASE address
++      movel scc_reg_addr(%d0), %a2    // A2 = SCC_REGS address
++
++      movel #0xFFFF, SCC_SCCE(%a2)    // clear status bits
++      movel #0x0000, SCC_SCCM(%a2)    // interrupt mask
++
++      movel tx_first_bd(%d0), %d1
++      movew %d1, SCC_TBASE(%a1)       // D1 = offset of first TxBD
++      addl #TX_BUFFERS * 8, %d1
++      movew %d1, SCC_RBASE(%a1)       // D1 = offset of first RxBD
++      moveb #0x8, SCC_RFCR(%a1)       // Intel mode, 1000
++      moveb #0x8, SCC_TFCR(%a1)
++
++// Parity settings
++      cmpl #PARITY_CRC16_PR1_CCITT, STATUS_PARITY(%a0)
++      bne open_port_parity_1
++      clrw SCC_PSMR(%a2)              // CRC16-CCITT
++      movel #0xF0B8, SCC_C_MASK(%a1)
++      movel #0xFFFF, SCC_C_PRES(%a1)
++      movew #HDLC_MAX_MRU + 2, SCC_MFLR(%a1) // 2 bytes for CRC
++      movew #2, parity_bytes(%d0)
++      bra open_port_2
++
++open_port_parity_1:
++      cmpl #PARITY_CRC32_PR1_CCITT, STATUS_PARITY(%a0)
++      bne open_port_parity_2
++      movew #0x0800, SCC_PSMR(%a2)    // CRC32-CCITT
++      movel #0xDEBB20E3, SCC_C_MASK(%a1)
++      movel #0xFFFFFFFF, SCC_C_PRES(%a1)
++      movew #HDLC_MAX_MRU + 4, SCC_MFLR(%a1) // 4 bytes for CRC
++      movew #4, parity_bytes(%d0)
++      bra open_port_2
++
++open_port_parity_2:
++      cmpl #PARITY_CRC16_PR0_CCITT, STATUS_PARITY(%a0)
++      bne open_port_parity_3
++      clrw SCC_PSMR(%a2)              // CRC16-CCITT preset 0
++      movel #0xF0B8, SCC_C_MASK(%a1)
++      clrl SCC_C_PRES(%a1)
++      movew #HDLC_MAX_MRU + 2, SCC_MFLR(%a1) // 2 bytes for CRC
++      movew #2, parity_bytes(%d0)
++      bra open_port_2
++
++open_port_parity_3:
++      cmpl #PARITY_CRC32_PR0_CCITT, STATUS_PARITY(%a0)
++      bne open_port_parity_4
++      movew #0x0800, SCC_PSMR(%a2)    // CRC32-CCITT preset 0
++      movel #0xDEBB20E3, SCC_C_MASK(%a1)
++      clrl SCC_C_PRES(%a1)
++      movew #HDLC_MAX_MRU + 4, SCC_MFLR(%a1) // 4 bytes for CRC
++      movew #4, parity_bytes(%d0)
++      bra open_port_2
++
++open_port_parity_4:
++      clrw SCC_PSMR(%a2)              // no parity
++      movel #0xF0B8, SCC_C_MASK(%a1)
++      movel #0xFFFF, SCC_C_PRES(%a1)
++      movew #HDLC_MAX_MRU, SCC_MFLR(%a1) // 0 bytes for CRC
++      clrw parity_bytes(%d0)
++
++open_port_2:
++      movel #0x00000003, SCC_GSMR_H(%a2) // RTSM
++      cmpl #ENCODING_NRZI, STATUS_ENCODING(%a0)
++      bne open_port_nrz
++      movel #0x10040900, SCC_GSMR_L(%a2) // NRZI: TCI Tend RECN+TENC=1
++      bra open_port_3
++
++open_port_nrz:
++      movel #0x10040000, SCC_GSMR_L(%a2) // NRZ: TCI Tend RECN+TENC=0
++open_port_3:
++      movew #BUFFER_LENGTH, SCC_MRBLR(%a1)
++      movel %d0, %d1
++      lsll #4, %d1                    // D1 bits 7 and 6 = port
++      orl #1, %d1
++      movew %d1, CR                   // Init SCC RX and TX params
++      wait_for_command
++
++      // TCI Tend ENR ENT
++      movew #0x001F, SCC_SCCM(%a2)    // TXE RXF BSY TXB RXB interrupts
++      orl #0x00000030, SCC_GSMR_L(%a2) // enable SCC
++open_port_ret:
++      rts
++
++
++/****************************** close port ****************************/
++
++close_port:                           // D0 = 4 * port, D6 = doorbell to host
++      movel scc_reg_addr(%d0), %a0    // A0 = SCC_REGS address
++      clrw SCC_SCCM(%a0)              // no SCC interrupts
++      andl #0xFFFFFFCF, SCC_GSMR_L(%a0) // Disable ENT and ENR
++
++      andw #~STATUS_CABLE_DTR, csr_output(%d0) // DTR off
++      bsr check_csr                   // call with disabled timer interrupt
++
++      movel ch_status_addr(%d0), %d1
++      clrl STATUS_OPEN(%d1)           // confirm the port is closed
++      rts
++
++
++/****************************** transmit packet ***********************/
++// queue packets for transmission
++tx:                                   // D0 = 4 * port, D6 = doorbell to host
++      cmpl #TX_BUFFERS, tx_count(%d0)
++      beq tx_ret                      // all DB's = descs in use
++
++      movel tx_out(%d0), %d1
++      movel %d1, %d2                  // D1 = D2 = tx_out BD# = desc#
++      mulul #DESC_LENGTH, %d2         // D2 = TX desc offset
++      addl ch_status_addr(%d0), %d2
++      addl #STATUS_TX_DESCS, %d2      // D2 = TX desc address
++      cmpl #PACKET_FULL, (%d2)        // desc status
++      bne tx_ret
++
++// queue it
++      movel 4(%d2), %a0               // PCI address
++      lsll #3, %d1                    // BD is 8-bytes long
++      addl tx_first_bd(%d0), %d1      // D1 = current tx_out BD addr
++
++      movel 4(%d1), %a1               // A1 = dest address
++      movel 8(%d2), %d2               // D2 = length
++      movew %d2, 2(%d1)               // length into BD
++      memcpy_from_pci %a0, %a1, %d2
++      bsetl #31, (%d1)                // CP go ahead
++
++// update tx_out and tx_count
++      movel tx_out(%d0), %d1
++      addl #1, %d1
++      cmpl #TX_BUFFERS, %d1
++      bne tx_1
++      clrl %d1
++tx_1: movel %d1, tx_out(%d0)
++
++      addl #1, tx_count(%d0)
++      bra tx
++
++tx_ret: rts
++
++
++/****************************** packet received ***********************/
++
++// Service receive buffers            // D0 = 4 * port, D6 = doorbell to host
++rx:   movel rx_in(%d0), %d1           // D1 = rx_in BD#
++      lsll #3, %d1                    // BD is 8-bytes long
++      addl rx_first_bd(%d0), %d1      // D1 = current rx_in BD address
++      movew (%d1), %d2                // D2 = RX BD flags
++      btstl #15, %d2
++      bne rx_ret                      // BD still empty
++
++      btstl #1, %d2
++      bne rx_overrun
++
++      tstw parity_bytes(%d0)
++      bne rx_parity
++      bclrl #2, %d2                   // do not test for CRC errors
++rx_parity:
++      andw #0x0CBC, %d2               // mask status bits
++      cmpw #0x0C00, %d2               // correct frame
++      bne rx_bad_frame
++      clrl %d3
++      movew 2(%d1), %d3
++      subw parity_bytes(%d0), %d3     // D3 = packet length
++      cmpw #HDLC_MAX_MRU, %d3
++      bgt rx_bad_frame
++
++rx_good_frame:
++      movel rx_out, %d2
++      mulul #DESC_LENGTH, %d2
++      addl rx_descs_addr, %d2         // D2 = RX desc address
++      cmpl #PACKET_EMPTY, (%d2)       // desc stat
++      bne rx_overrun
++
++      movel %d3, 8(%d2)
++      movel 4(%d1), %a0               // A0 = source address
++      movel 4(%d2), %a1
++      tstl %a1
++      beq rx_ignore_data
++      memcpy_to_pci %a0, %a1, %d3
++rx_ignore_data:
++      movel packet_full(%d0), (%d2)   // update desc stat
++
++// update D6 and rx_out
++      bsetl #DOORBELL_FROM_CARD_RX, %d6 // signal host that RX completed
++      movel rx_out, %d2
++      addl #1, %d2
++      cmpl #RX_QUEUE_LENGTH, %d2
++      bne rx_1
++      clrl %d2
++rx_1: movel %d2, rx_out
++
++rx_free_bd:
++      andw #0xF000, (%d1)             // clear CM and error bits
++      bsetl #31, (%d1)                // free BD
++// update rx_in
++      movel rx_in(%d0), %d1
++      addl #1, %d1
++      cmpl #RX_BUFFERS, %d1
++      bne rx_2
++      clrl %d1
++rx_2: movel %d1, rx_in(%d0)
++      bra rx
++
++rx_overrun:
++      movel ch_status_addr(%d0), %d2
++      addl #1, STATUS_RX_OVERRUNS(%d2)
++      bra rx_free_bd
++
++rx_bad_frame:
++      movel ch_status_addr(%d0), %d2
++      addl #1, STATUS_RX_FRAME_ERRORS(%d2)
++      bra rx_free_bd
++
++rx_ret: rts
++
++
++/****************************** packet transmitted ********************/
++
++// Service transmit buffers           // D0 = 4 * port, D6 = doorbell to host
++tx_end:       tstl tx_count(%d0)
++      beq tx_end_ret                  // TX buffers already empty
++
++      movel tx_in(%d0), %d1
++      movel %d1, %d2                  // D1 = D2 = tx_in BD# = desc#
++      lsll #3, %d1                    // BD is 8-bytes long
++      addl tx_first_bd(%d0), %d1      // D1 = current tx_in BD address
++      movew (%d1), %d3                // D3 = TX BD flags
++      btstl #15, %d3
++      bne tx_end_ret                  // BD still being transmitted
++
++// update D6, tx_in and tx_count
++      orl bell_tx(%d0), %d6           // signal host that TX desc freed
++      subl #1, tx_count(%d0)
++      movel tx_in(%d0), %d1
++      addl #1, %d1
++      cmpl #TX_BUFFERS, %d1
++      bne tx_end_1
++      clrl %d1
++tx_end_1:
++      movel %d1, tx_in(%d0)
++
++// free host's descriptor
++      mulul #DESC_LENGTH, %d2         // D2 = TX desc offset
++      addl ch_status_addr(%d0), %d2
++      addl #STATUS_TX_DESCS, %d2      // D2 = TX desc address
++      btstl #1, %d3
++      bne tx_end_underrun
++      movel #PACKET_SENT, (%d2)
++      bra tx_end
++
++tx_end_underrun:
++      movel #PACKET_UNDERRUN, (%d2)
++      bra tx_end
++
++tx_end_ret: rts
++
++
++/****************************** PLX PCI9060 DMA memcpy ****************/
++
++#if QUICC_MEMCPY_USES_PLX
++// called with interrupts disabled
++memcpy_from_pci_run:
++      movel %d0, -(%sp)
++      movew %sr, -(%sp)
++memcpy_1:
++      movel PLX_DMA_CMD_STS, %d0      // do not btst PLX register directly
++      btstl #4, %d0                   // transfer done?
++      bne memcpy_end
++      stop #0x2200                    // enable PCI9060 interrupts
++      movew #0x2700, %sr              // disable interrupts again
++      bra memcpy_1
++
++memcpy_to_pci_run:
++      movel %d0, -(%sp)
++      movew %sr, -(%sp)
++memcpy_2:
++      movel PLX_DMA_CMD_STS, %d0      // do not btst PLX register directly
++      btstl #12, %d0                  // transfer done?
++      bne memcpy_end
++      stop #0x2200                    // enable PCI9060 interrupts
++      movew #0x2700, %sr              // disable interrupts again
++      bra memcpy_2
++
++memcpy_end:
++      movew (%sp)+, %sr
++      movel (%sp)+, %d0
++      rts
++#endif
++
++
++
++
++
++
++/****************************** PLX PCI9060 interrupt *****************/
++
++pci9060_interrupt:
++      movel %d0, -(%sp)
++
++      movel PLX_DOORBELL_TO_CARD, %d0
++      movel %d0, PLX_DOORBELL_TO_CARD // confirm all requests
++      orl %d0, channel_stats
++
++      movel #0x0909, PLX_DMA_CMD_STS  // clear DMA ch #0 and #1 interrupts
++
++      movel (%sp)+, %d0
++      rte
++
++/****************************** SCC interrupts ************************/
++
++port_interrupt_1:
++      orl #0, SCC1_REGS + SCC_SCCE; // confirm SCC events
++      orl #1 << TASK_SCC_0, channel_stats
++      movel #0x40000000, CISR
++      rte
++
++port_interrupt_2:
++      orl #0, SCC2_REGS + SCC_SCCE; // confirm SCC events
++      orl #1 << TASK_SCC_1, channel_stats
++      movel #0x20000000, CISR
++      rte
++
++port_interrupt_3:
++      orl #0, SCC3_REGS + SCC_SCCE; // confirm SCC events
++      orl #1 << TASK_SCC_2, channel_stats
++      movel #0x10000000, CISR
++      rte
++
++port_interrupt_4:
++      orl #0, SCC4_REGS + SCC_SCCE; // confirm SCC events
++      orl #1 << TASK_SCC_3, channel_stats
++      movel #0x08000000, CISR
++      rte
++
++error_interrupt:
++      rte
++
++
++/****************************** cable and PM routine ******************/
++// modified registers: none
++check_csr:
++      movel %d0, -(%sp)
++      movel %d1, -(%sp)
++      movel %d2, -(%sp)
++      movel %a0, -(%sp)
++      movel %a1, -(%sp)
++
++      clrl %d0                        // D0 = 4 * port
++      movel #CSRA, %a0                // A0 = CSR address
++
++check_csr_loop:
++      movew (%a0), %d1                // D1 = CSR input bits
++      andl #0xE7, %d1                 // PM and cable sense bits (no DCE bit)
++      cmpw #STATUS_CABLE_V35 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++      bne check_csr_1
++      movew #0x0E08, %d1
++      bra check_csr_valid
++
++check_csr_1:
++      cmpw #STATUS_CABLE_X21 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++      bne check_csr_2
++      movew #0x0408, %d1
++      bra check_csr_valid
++
++check_csr_2:
++      cmpw #STATUS_CABLE_V24 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++      bne check_csr_3
++      movew #0x0208, %d1
++      bra check_csr_valid
++
++check_csr_3:
++      cmpw #STATUS_CABLE_EIA530 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1
++      bne check_csr_disable
++      movew #0x0D08, %d1
++      bra check_csr_valid
++
++check_csr_disable:
++      movew #0x0008, %d1              // D1 = disable everything
++      movew #0x80E7, %d2              // D2 = input mask: ignore DSR
++      bra check_csr_write
++
++check_csr_valid:                      // D1 = mode and IRQ bits
++      movew csr_output(%d0), %d2
++      andw #0x3000, %d2               // D2 = requested LL and DTR bits
++      orw %d2, %d1                    // D1 = all requested output bits
++      movew #0x80FF, %d2              // D2 = input mask: include DSR
++
++check_csr_write:
++      cmpw old_csr_output(%d0), %d1
++      beq check_csr_input
++      movew %d1, old_csr_output(%d0)
++      movew %d1, (%a0)                // Write CSR output bits
++
++check_csr_input:
++      movew (PCDAT), %d1
++      andw dcd_mask(%d0), %d1
++      beq check_csr_dcd_on            // DCD and CTS signals are negated
++      movew (%a0), %d1                // D1 = CSR input bits
++      andw #~STATUS_CABLE_DCD, %d1    // DCD off
++      bra check_csr_previous
++
++check_csr_dcd_on:
++      movew (%a0), %d1                // D1 = CSR input bits
++      orw #STATUS_CABLE_DCD, %d1      // DCD on
++check_csr_previous:
++      andw %d2, %d1                   // input mask
++      movel ch_status_addr(%d0), %a1
++      cmpl STATUS_CABLE(%a1), %d1     // check for change
++      beq check_csr_next
++      movel %d1, STATUS_CABLE(%a1)    // update status
++      movel bell_cable(%d0), PLX_DOORBELL_FROM_CARD   // signal the host
++
++check_csr_next:
++      addl #2, %a0                    // next CSR register
++      addl #4, %d0                    // D0 = 4 * next port
++      cmpl #4 * 4, %d0
++      bne check_csr_loop
++
++      movel (%sp)+, %a1
++      movel (%sp)+, %a0
++      movel (%sp)+, %d2
++      movel (%sp)+, %d1
++      movel (%sp)+, %d0
++      rts
++
++
++/****************************** timer interrupt ***********************/
++
++timer_interrupt:
++      bsr check_csr
++      rte
++
++
++/****************************** RAM sizing and test *******************/
++#if DETECT_RAM
++ram_test:
++      movel #0x12345678, %d1          // D1 = test value
++      movel %d1, (128 * 1024 - 4)
++      movel #128 * 1024, %d0          // D0 = RAM size tested
++ram_test_size:
++      cmpl #MAX_RAM_SIZE, %d0
++      beq ram_test_size_found
++      movel %d0, %a0
++      addl #128 * 1024 - 4, %a0
++      cmpl (%a0), %d1
++      beq ram_test_size_check
++ram_test_next_size:
++      lsll #1, %d0
++      bra ram_test_size
++
++ram_test_size_check:
++      eorl #0xFFFFFFFF, %d1
++      movel %d1, (128 * 1024 - 4)
++      cmpl (%a0), %d1
++      bne ram_test_next_size
++
++ram_test_size_found:                  // D0 = RAM size
++      movel %d0, %a0                  // A0 = fill ptr
++      subl #firmware_end + 4, %d0
++      lsrl #2, %d0
++      movel %d0, %d1                  // D1 = DBf counter
++ram_test_fill:
++      movel %a0, -(%a0)
++      dbfw %d1, ram_test_fill
++      subl #0x10000, %d1
++      cmpl #0xFFFFFFFF, %d1
++      bne ram_test_fill
++
++ram_test_loop:                                // D0 = DBf counter
++      cmpl (%a0)+, %a0
++      dbnew %d0, ram_test_loop
++      bne ram_test_found_bad
++      subl #0x10000, %d0
++      cmpl #0xFFFFFFFF, %d0
++      bne ram_test_loop
++      bra ram_test_all_ok
++
++ram_test_found_bad:
++      subl #4, %a0
++ram_test_all_ok:
++      movel %a0, PLX_MAILBOX_5
++      rts
++#endif
++
++
++/****************************** constants *****************************/
++
++scc_reg_addr:
++      .long SCC1_REGS, SCC2_REGS, SCC3_REGS, SCC4_REGS
++scc_base_addr:
++      .long SCC1_BASE, SCC2_BASE, SCC3_BASE, SCC4_BASE
++
++tx_first_bd:
++      .long DPRBASE
++      .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8
++      .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8 * 2
++      .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8 * 3
++
++rx_first_bd:
++      .long DPRBASE + TX_BUFFERS * 8
++      .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8
++      .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8 * 2
++      .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8 * 3
++
++first_buffer:
++      .long BUFFERS_ADDR
++      .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH
++      .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * 2
++      .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * 3
++
++bell_tx:
++      .long 1 << DOORBELL_FROM_CARD_TX_0, 1 << DOORBELL_FROM_CARD_TX_1
++      .long 1 << DOORBELL_FROM_CARD_TX_2, 1 << DOORBELL_FROM_CARD_TX_3
++
++bell_cable:
++      .long 1 << DOORBELL_FROM_CARD_CABLE_0, 1 << DOORBELL_FROM_CARD_CABLE_1
++      .long 1 << DOORBELL_FROM_CARD_CABLE_2, 1 << DOORBELL_FROM_CARD_CABLE_3
++
++packet_full:
++      .long PACKET_FULL, PACKET_FULL + 1, PACKET_FULL + 2, PACKET_FULL + 3
++
++clocking_ext:
++      .long 0x0000002C, 0x00003E00, 0x002C0000, 0x3E000000
++clocking_txfromrx:
++      .long 0x0000002D, 0x00003F00, 0x002D0000, 0x3F000000
++clocking_mask:
++      .long 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
++dcd_mask:
++      .word 0x020, 0, 0x080, 0, 0x200, 0, 0x800
++
++      .ascii "wanXL firmware\n"
++      .asciz "Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>\n"
++
++
++/****************************** variables *****************************/
++
++              .align 4
++channel_stats:        .long 0
++
++tx_in:                .long 0, 0, 0, 0        // transmitted
++tx_out:               .long 0, 0, 0, 0        // received from host for transmission
++tx_count:     .long 0, 0, 0, 0        // currently in transmit queue
++
++rx_in:                .long 0, 0, 0, 0        // received from port
++rx_out:               .long 0                 // transmitted to host
++parity_bytes: .word 0, 0, 0, 0, 0, 0, 0 // only 4 words are used
++
++csr_output:   .word 0
++old_csr_output:       .word 0, 0, 0, 0, 0, 0, 0
++              .align 4
++firmware_end:                         // must be dword-aligned
+Index: linux-2.6.0-test5/drivers/net/wan/wanxl.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wan/wanxl.h     2003-09-27 11:38:18.459722080 +0800
++++ linux-2.6.0-test5/drivers/net/wan/wanxl.h  2003-09-27 11:38:28.622177152 +0800
+@@ -0,0 +1,152 @@
++/*
++ * wanXL serial card driver for Linux
++ * definitions common to host driver and card firmware
++ *
++ * Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>
++ *
++ * 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.
++ */
++
++#define RESET_WHILE_LOADING 0
++
++/* you must rebuild the firmware if any of the following is changed */
++#define DETECT_RAM 0          /* needed for > 4MB RAM, 16 MB maximum */
++#define QUICC_MEMCPY_USES_PLX 1       /* must be used if the host has > 256 MB RAM */
++
++
++#define STATUS_CABLE_V35      2
++#define STATUS_CABLE_X21      3
++#define STATUS_CABLE_V24      4
++#define STATUS_CABLE_EIA530   5
++#define STATUS_CABLE_INVALID  6
++#define STATUS_CABLE_NONE     7
++
++#define STATUS_CABLE_DCE      0x8000
++#define STATUS_CABLE_DSR      0x0010
++#define STATUS_CABLE_DCD      0x0008
++#define STATUS_CABLE_PM_SHIFT 5
++
++#define PDM_OFFSET 0x1000
++
++#define TX_BUFFERS 10         /* per port */
++#define RX_BUFFERS 30
++#define RX_QUEUE_LENGTH 40    /* card->host queue length - per card */
++
++#define PACKET_EMPTY          0x00
++#define PACKET_FULL           0x10
++#define PACKET_SENT           0x20 /* TX only */
++#define PACKET_UNDERRUN               0x30 /* TX only */
++#define PACKET_PORT_MASK      0x03 /* RX only */
++
++/* bit numbers in PLX9060 doorbell registers */
++#define DOORBELL_FROM_CARD_TX_0               0 /* packet sent by the card */
++#define DOORBELL_FROM_CARD_TX_1               1
++#define DOORBELL_FROM_CARD_TX_2               2
++#define DOORBELL_FROM_CARD_TX_3               3
++#define DOORBELL_FROM_CARD_RX         4
++#define DOORBELL_FROM_CARD_CABLE_0    5 /* cable/PM/etc. changed */
++#define DOORBELL_FROM_CARD_CABLE_1    6
++#define DOORBELL_FROM_CARD_CABLE_2    7
++#define DOORBELL_FROM_CARD_CABLE_3    8
++
++#define DOORBELL_TO_CARD_OPEN_0               0
++#define DOORBELL_TO_CARD_OPEN_1               1
++#define DOORBELL_TO_CARD_OPEN_2               2
++#define DOORBELL_TO_CARD_OPEN_3               3
++#define DOORBELL_TO_CARD_CLOSE_0      4
++#define DOORBELL_TO_CARD_CLOSE_1      5
++#define DOORBELL_TO_CARD_CLOSE_2      6
++#define DOORBELL_TO_CARD_CLOSE_3      7
++#define DOORBELL_TO_CARD_TX_0         8 /* outbound packet queued */
++#define DOORBELL_TO_CARD_TX_1         9
++#define DOORBELL_TO_CARD_TX_2         10
++#define DOORBELL_TO_CARD_TX_3         11
++
++/* firmware-only status bits, starting from last DOORBELL_TO_CARD + 1 */
++#define TASK_SCC_0                    12
++#define TASK_SCC_1                    13
++#define TASK_SCC_2                    14
++#define TASK_SCC_3                    15
++
++#define ALIGN32(x) (((x) + 3) & 0xFFFFFFFC)
++#define BUFFER_LENGTH ALIGN32(HDLC_MAX_MRU + 4) /* 4 bytes for 32-bit CRC */
++
++/* Address of TX and RX buffers in 68360 address space */
++#define BUFFERS_ADDR  0x4000  /* 16 KB */
++
++#ifndef __ASSEMBLER__
++#define PLX_OFFSET            0
++#else
++#define PLX_OFFSET            PLX + 0x80
++#endif
++
++#define PLX_MAILBOX_0         (PLX_OFFSET + 0x40)
++#define PLX_MAILBOX_1         (PLX_OFFSET + 0x44)
++#define PLX_MAILBOX_2         (PLX_OFFSET + 0x48)
++#define PLX_MAILBOX_3         (PLX_OFFSET + 0x4C)
++#define PLX_MAILBOX_4         (PLX_OFFSET + 0x50)
++#define PLX_MAILBOX_5         (PLX_OFFSET + 0x54)
++#define PLX_MAILBOX_6         (PLX_OFFSET + 0x58)
++#define PLX_MAILBOX_7         (PLX_OFFSET + 0x5C)
++#define PLX_DOORBELL_TO_CARD  (PLX_OFFSET + 0x60)
++#define PLX_DOORBELL_FROM_CARD        (PLX_OFFSET + 0x64)
++#define PLX_INTERRUPT_CS      (PLX_OFFSET + 0x68)
++#define PLX_CONTROL           (PLX_OFFSET + 0x6C)
++
++#ifdef __ASSEMBLER__
++#define PLX_DMA_0_MODE                (PLX + 0x100)
++#define PLX_DMA_0_PCI         (PLX + 0x104)
++#define PLX_DMA_0_LOCAL               (PLX + 0x108)
++#define PLX_DMA_0_LENGTH      (PLX + 0x10C)
++#define PLX_DMA_0_DESC                (PLX + 0x110)
++#define PLX_DMA_1_MODE                (PLX + 0x114)
++#define PLX_DMA_1_PCI         (PLX + 0x118)
++#define PLX_DMA_1_LOCAL               (PLX + 0x11C)
++#define PLX_DMA_1_LENGTH      (PLX + 0x120)
++#define PLX_DMA_1_DESC                (PLX + 0x124)
++#define PLX_DMA_CMD_STS               (PLX + 0x128)
++#define PLX_DMA_ARBITR_0      (PLX + 0x12C)
++#define PLX_DMA_ARBITR_1      (PLX + 0x130)
++#endif
++
++#define DESC_LENGTH 12
++
++/* offsets from start of status_t */
++/* card to host */
++#define STATUS_OPEN           0
++#define STATUS_CABLE          (STATUS_OPEN + 4)
++#define STATUS_RX_OVERRUNS    (STATUS_CABLE + 4)
++#define STATUS_RX_FRAME_ERRORS        (STATUS_RX_OVERRUNS + 4)
++
++/* host to card */
++#define STATUS_PARITY         (STATUS_RX_FRAME_ERRORS + 4)
++#define STATUS_ENCODING               (STATUS_PARITY + 4)
++#define STATUS_CLOCKING               (STATUS_ENCODING + 4)
++#define STATUS_TX_DESCS               (STATUS_CLOCKING + 4)
++
++#ifndef __ASSEMBLER__
++
++typedef struct {
++      volatile u32 stat;
++      u32 address;            /* PCI address */
++      volatile u32 length;
++}desc_t;
++
++
++typedef struct {
++// Card to host
++      volatile u32 open;
++      volatile u32 cable;
++      volatile u32 rx_overruns;
++      volatile u32 rx_frame_errors;
++
++// Host to card
++      u32 parity;
++      u32 encoding;
++      u32 clocking;
++      desc_t tx_descs[TX_BUFFERS];
++}port_status_t;
++
++#endif /* __ASSEMBLER__ */
+Index: linux-2.6.0-test5/drivers/net/wd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wd.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wd.c 2003-09-27 11:38:28.627176392 +0800
+@@ -235,7 +235,7 @@
+               int reg4 = inb(ioaddr+4);
+               if (ancient || reg1 == 0xff) {  /* Ack!! No way to read the IRQ! */
+                       short nic_addr = ioaddr+WD_NIC_OFFSET;
+-                      unsigned long irq_mask, delay;
++                      unsigned long irq_mask;
+                       /* We have an old-style ethercard that doesn't report its IRQ
+                          line.  Do autoirq to find the IRQ line. Note that this IS NOT
+@@ -248,8 +248,7 @@
+                       outb_p(0x00, nic_addr + EN0_RCNTLO);
+                       outb_p(0x00, nic_addr + EN0_RCNTHI);
+                       outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */
+-                      delay = jiffies + HZ/50;
+-                      while (time_before(jiffies, delay)) ;
++                      mdelay(20);
+                       dev->irq = probe_irq_off(irq_mask);
+                       
+                       outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */
+Index: linux-2.6.0-test5/drivers/net/wireless/airo.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/airo.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/airo.c      2003-09-27 11:38:28.682168032 +0800
+@@ -18,7 +18,6 @@
+ ======================================================================*/
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -42,7 +41,6 @@
+ #include <linux/skbuff.h>
+ #include <linux/if_arp.h>
+ #include <linux/ioport.h>
+-#include <linux/config.h>
+ #include <linux/pci.h>
+ #include <asm/uaccess.h>
+@@ -1435,7 +1433,7 @@
+   
+       int i,j;
+       u32 counter;
+-      u8 *cipher;
++      u8 *cipher, plain[16];
+       struct scatterlist sg[1];
+       crypto_cipher_setkey(tfm, pkey, 16);
+@@ -1446,8 +1444,9 @@
+               aes_counter[13] = (u8)(counter >> 16);
+               aes_counter[12] = (u8)(counter >> 24);
+               counter++;
+-              sg[0].page = virt_to_page(aes_counter);
+-              sg[0].offset = ((long) aes_counter & ~PAGE_MASK);
++              memcpy (plain, aes_counter, 16);
++              sg[0].page = virt_to_page(plain);
++              sg[0].offset = ((long) plain & ~PAGE_MASK);
+               sg[0].length = 16;
+               crypto_cipher_encrypt(tfm, sg, sg, 16);
+               cipher = kmap(sg[0].page) + sg[0].offset;
+@@ -4624,7 +4623,7 @@
+               return -ENODEV;
+       pci_set_drvdata(pdev, dev);
+-      clear_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
++      set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
+       return 0;
+ }
+Index: linux-2.6.0-test5/drivers/net/wireless/airo_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/airo_cs.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/airo_cs.c   2003-09-27 11:38:28.689166968 +0800
+@@ -163,24 +163,6 @@
+ /*======================================================================
+   
+-  This bit of code is used to avoid unregistering network devices
+-  at inappropriate times.  2.2 and later kernels are fairly picky
+-  about when this can happen.
+-  
+-  ======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-      dev_link_t *link, *next;
+-      for (link = dev_list; link; link = next) {
+-              next = link->next;
+-              if (link->state & DEV_STALE_LINK)
+-                      airo_detach(link);
+-      }
+-}
+- 
+-/*======================================================================
+-  
+   airo_attach() creates an "instance" of the driver, allocating
+   local data structures for one device.  The device is registered
+   with Card Services.
+@@ -199,8 +181,7 @@
+       int ret, i;
+       
+       DEBUG(0, "airo_attach()\n");
+-      flush_stale_links();
+-      
++
+       /* Initialize the dev_link_t structure */
+       link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+       if (!link) {
+@@ -285,10 +266,8 @@
+       
+       if (link->state & DEV_CONFIG) {
+               airo_release(link);
+-              if (link->state & DEV_STALE_CONFIG) {
+-                      link->state |= DEV_STALE_LINK;
++              if (link->state & DEV_STALE_CONFIG)
+                       return;
+-              }
+       }
+       
+       if ( ((local_info_t*)link->priv)->eth_dev ) {
+@@ -554,8 +533,10 @@
+       if (link->irq.AssignedIRQ)
+               CardServices(ReleaseIRQ, link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+-      
+-} /* airo_release */
++
++      if (link->state & DEV_STALE_CONFIG)
++              airo_detach(link);
++}
+ /*======================================================================
+   
+Index: linux-2.6.0-test5/drivers/net/wireless/arlan.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/arlan.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/arlan.c     2003-09-27 11:38:28.705164536 +0800
+@@ -5,6 +5,7 @@
+  * This module provides support for the Arlan 655 card made by Aironet
+  */
++#include <linux/version.h>
+ #include <linux/config.h>
+ #include "arlan.h"
+Index: linux-2.6.0-test5/drivers/net/wireless/arlan.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/arlan.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/arlan.h     2003-09-27 11:38:28.710163776 +0800
+@@ -3,7 +3,6 @@
+  *  Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500      
+  *  GNU General Public License applies
+  */
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/config.h>
+Index: linux-2.6.0-test5/drivers/net/wireless/arlan-proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/arlan-proc.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/arlan-proc.c        2003-09-27 11:38:28.718162560 +0800
+@@ -5,9 +5,6 @@
+ #ifdef CONFIG_PROC_FS
+-
+-#include <linux/version.h>
+-
+ /* void enableReceive(struct net_device* dev);
+ */
+Index: linux-2.6.0-test5/drivers/net/wireless/atmel_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/atmel_cs.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/atmel_cs.c  2003-09-27 11:38:28.736159824 +0800
+@@ -176,24 +176,6 @@
+ /*======================================================================
+   
+-  This bit of code is used to avoid unregistering network devices
+-  at inappropriate times.  2.2 and later kernels are fairly picky
+-  about when this can happen.
+-  
+-  ======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-      dev_link_t *link, *next;
+-      for (link = dev_list; link; link = next) {
+-              next = link->next;
+-              if (link->state & DEV_STALE_LINK)
+-                      atmel_detach(link);
+-      }
+-}
+- 
+-/*======================================================================
+-  
+   atmel_attach() creates an "instance" of the driver, allocating
+   local data structures for one device.  The device is registered
+   with Card Services.
+@@ -212,8 +194,7 @@
+       int ret, i;
+       
+       DEBUG(0, "atmel_attach()\n");
+-      flush_stale_links();
+-      
++
+       /* Initialize the dev_link_t structure */
+       link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+       if (!link) {
+@@ -296,29 +277,19 @@
+       if (*linkp == NULL)
+               return;
+-      if ( link->state & DEV_CONFIG ) {
++      if (link->state & DEV_CONFIG)
+               atmel_release(link);
+-              if ( link->state & DEV_STALE_CONFIG ) {
+-                      link->state |= DEV_STALE_LINK;
+-                      return;
+-              }
+-      }
+-      
+               
+       /* Break the link with Card Services */
+       if (link->handle)
+               CardServices(DeregisterClient, link->handle);
+-      
+-      
+-      
++
+       /* Unlink device structure, free pieces */
+       *linkp = link->next;
+-      if (link->priv) {
++      if (link->priv)
+               kfree(link->priv);
+-      }
+       kfree(link);
+-      
+-} /* atmel_detach */
++}
+ /*======================================================================
+   
+Index: linux-2.6.0-test5/drivers/net/wireless/netwave_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/netwave_cs.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/netwave_cs.c        2003-09-27 11:38:28.751157544 +0800
+@@ -211,7 +211,6 @@
+                                                                                                          insertion */
+ static dev_link_t *netwave_attach(void);     /* Create instance */
+ static void netwave_detach(dev_link_t *);    /* Destroy instance */
+-static void netwave_flush_stale_links(void);       /* Destroy all staled instances */
+ /* Hardware configuration */
+ static void netwave_doreset(ioaddr_t iobase, u_char* ramBase);
+@@ -444,9 +443,6 @@
+     
+     DEBUG(0, "netwave_attach()\n");
+     
+-    /* Perform some cleanup */
+-    netwave_flush_stale_links();
+-
+     /* Initialize the dev_link_t structure */
+     dev = alloc_etherdev(sizeof(netwave_private));
+     if (!dev)
+@@ -553,7 +549,6 @@
+       if (link->state & DEV_STALE_CONFIG) {
+           DEBUG(1, "netwave_cs: detach postponed, '%s' still "
+                 "locked\n", link->dev->dev_name);
+-          link->state |= DEV_STALE_LINK;
+           return;
+       }
+     }
+@@ -581,31 +576,6 @@
+ } /* netwave_detach */
+ /*
+- * Function netwave_flush_stale_links (void)
+- *
+- *    This deletes all driver "instances" that need to be deleted.
+- *    Sometimes, netwave_detach can't be performed following a call from
+- *    cardmgr (device still open) and the device is put in a STALE_LINK
+- *    state.
+- *    This function is in charge of making the cleanup...
+- */
+-static void netwave_flush_stale_links(void)
+-{
+-    dev_link_t *      link;           /* Current node in linked list */
+-    dev_link_t *      next;           /* Next node in linked list */
+-
+-    DEBUG(1, "netwave_flush_stale_links(0x%p)\n", dev_list);
+-
+-    /* Go through the list */
+-    for (link = dev_list; link; link = next) {
+-        next = link->next;
+-        /* Check if in need of being removed */
+-        if(link->state & DEV_STALE_LINK)
+-          netwave_detach(link);
+-    }
+-} /* netwave_flush_stale_links */
+-
+-/*
+  * Wireless Handler : get protocol name
+  */
+ static int netwave_get_name(struct net_device *dev,
+@@ -1181,9 +1151,11 @@
+     CardServices(ReleaseIO, link->handle, &link->io);
+     CardServices(ReleaseIRQ, link->handle, &link->irq);
+-    link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG);
++    link->state &= ~DEV_CONFIG;
+-} /* netwave_release */
++    if (link->state & DEV_STALE_CONFIG)
++      netwave_detach(link);
++}
+ /*
+  * Function netwave_event (event, priority, args)
+@@ -1755,8 +1727,6 @@
+ {
+       pcmcia_unregister_driver(&netwave_driver);
+-      /* Do some cleanup of the device list */
+-      netwave_flush_stale_links();
+       if (dev_list != NULL)   /* Critical situation */
+               printk("netwave_cs: devices remaining when removing module\n");
+ }
+Index: linux-2.6.0-test5/drivers/net/wireless/orinoco_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/orinoco_cs.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/orinoco_cs.c        2003-09-27 11:38:28.757156632 +0800
+@@ -153,24 +153,6 @@
+       CardServices(ReportError, handle, &err);
+ }
+-
+-/* Remove zombie instances (card removed, detach pending) */
+-static void
+-flush_stale_links(void)
+-{
+-      dev_link_t *link, *next;
+-
+-      TRACE_ENTER("");
+-
+-      for (link = dev_list; link; link = next) {
+-              next = link->next;
+-              if (link->state & DEV_STALE_LINK) {
+-                      orinoco_cs_detach(link);
+-              }
+-      }
+-      TRACE_EXIT("");
+-}
+-
+ /*
+  * This creates an "instance" of the driver, allocating local data
+  * structures for one device.  The device is registered with Card
+@@ -189,9 +171,6 @@
+       client_reg_t client_reg;
+       int ret, i;
+-      /* A bit of cleanup */
+-      flush_stale_links();
+-
+       dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
+       if (! dev)
+               return NULL;
+@@ -266,13 +245,8 @@
+               return;
+       }
+-      if (link->state & DEV_CONFIG) {
++      if (link->state & DEV_CONFIG)
+               orinoco_cs_release(link);
+-              if (link->state & DEV_CONFIG) {
+-                      link->state |= DEV_STALE_LINK;
+-                      return;
+-              }
+-      }
+       /* Break the link with Card Services */
+       if (link->handle)
+Index: linux-2.6.0-test5/drivers/net/wireless/ray_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/ray_cs.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/ray_cs.c    2003-09-27 11:38:28.783152680 +0800
+@@ -138,7 +138,7 @@
+ static void verify_dl_startup(u_long);
+ /* Prototypes for interrpt time functions **********************************/
+-static void ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
++static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
+ static void clear_interrupt(ray_dev_t *local);
+ static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, 
+                        unsigned int pkt_addr, int rx_len);
+@@ -319,24 +319,6 @@
+ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+-/*======================================================================
+-
+-    This bit of code is used to avoid unregistering network devices
+-    at inappropriate times.  2.2 and later kernels are fairly picky
+-    about when this can happen.
+-    
+-======================================================================*/
+-
+-static void flush_stale_links(void)
+-{
+-    dev_link_t *link, *next;
+-    for (link = dev_list; link; link = next) {
+-      next = link->next;
+-      if (link->state & DEV_STALE_LINK)
+-          ray_detach(link);
+-    }
+-}
+-
+ /*=============================================================================
+     ray_attach() creates an "instance" of the driver, allocating
+     local data structures for one device.  The device is registered
+@@ -354,7 +336,6 @@
+     struct net_device *dev;
+     
+     DEBUG(1, "ray_attach()\n");
+-    flush_stale_links();
+     /* Initialize the dev_link_t structure */
+     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+@@ -484,10 +465,8 @@
+     */
+     if (link->state & DEV_CONFIG) {
+         ray_release(link);
+-        if(link->state & DEV_STALE_CONFIG) {
+-            link->state |= DEV_STALE_LINK;
++        if(link->state & DEV_STALE_CONFIG)
+             return;
+-        }
+     }
+     /* Break the link with Card Services */
+@@ -932,7 +911,11 @@
+     if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
+     DEBUG(2,"ray_release ending\n");
+-} /* ray_release */
++
++    if (link->state & DEV_STALE_CONFIG)
++          ray_detach(link);
++}
++
+ /*=============================================================================
+     The card status event handler.  Mostly, this schedules other
+     stuff to run after an event is received.  A CARD_REMOVAL event
+@@ -2050,7 +2033,7 @@
+ /*=============================================================================
+  * All routines below here are run at interrupt time.
+ =============================================================================*/
+-static void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
++static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+ {
+     struct net_device *dev = (struct net_device *)dev_id;
+     dev_link_t *link;
+@@ -2063,7 +2046,7 @@
+     UCHAR status;
+     if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
+-    return;
++      return IRQ_NONE;
+     DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
+@@ -2071,7 +2054,7 @@
+     link = (dev_link_t *)local->finder;
+     if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
+         DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
+-        return;
++        return IRQ_NONE;
+     }
+     rcsindex = readb(&((struct scb *)(local->sram))->rcs_index);
+@@ -2079,7 +2062,7 @@
+     {
+         DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
+         clear_interrupt(local);
+-        return;
++        return IRQ_HANDLED;
+     }
+     if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
+     {
+@@ -2235,6 +2218,7 @@
+         writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
+     }
+     clear_interrupt(local);
++    return IRQ_HANDLED;
+ } /* ray_interrupt */
+ /*===========================================================================*/
+ static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs)
+Index: linux-2.6.0-test5/drivers/net/wireless/strip.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/strip.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/strip.c     2003-09-27 11:38:28.805149336 +0800
+@@ -83,7 +83,6 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/init.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -965,8 +964,6 @@
+       return (buffer);
+ }
+-#define STRIP_PROC_HEADER     ((void *)1)
+-
+ /* get Nth element of the linked list */
+ static struct strip *strip_get_idx(loff_t pos) 
+ {
+@@ -984,7 +981,7 @@
+ static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       rcu_read_lock();
+-      return *pos ? strip_get_idx(*pos - 1) : STRIP_PROC_HEADER;
++      return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -993,7 +990,7 @@
+       struct strip *s;
+       ++*pos;
+-      if (v == STRIP_PROC_HEADER)
++      if (v == SEQ_START_TOKEN)
+               return strip_get_idx(1);
+       s = v;
+@@ -1149,7 +1146,7 @@
+  */
+ static int strip_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == STRIP_PROC_HEADER)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "strip_version: %s\n", StripVersion);
+       else
+               strip_seq_status_info(seq, (const struct strip *)v);
+Index: linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/wavelan_cs.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.c        2003-09-27 11:38:28.841143864 +0800
+@@ -4175,50 +4175,14 @@
+   CardServices(ReleaseIO, link->handle, &link->io);
+   CardServices(ReleaseIRQ, link->handle, &link->irq);
+-  link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG);
++  link->state &= ~DEV_CONFIG;
+ #ifdef DEBUG_CONFIG_TRACE
+   printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
+ #endif
+-} /* wv_pcmcia_release */
+-/*------------------------------------------------------------------*/
+-/*
+- * Sometimes, wavelan_detach can't be performed following a call from
+- * cardmgr (device still open, pcmcia_release not done) and the device
+- * is put in a STALE_LINK state and remains in memory.
+- *
+- * This function run through our current list of device and attempt
+- * another time to remove them. We hope that since last time the
+- * device has properly been closed.
+- *
+- * (called by wavelan_attach() & cleanup_module())
+- */
+-static void
+-wv_flush_stale_links(void)
+-{
+-  dev_link_t *        link;           /* Current node in linked list */
+-  dev_link_t *        next;           /* Next node in linked list */
+-
+-#ifdef DEBUG_CONFIG_TRACE
+-  printk(KERN_DEBUG "-> wv_flush_stale_links(0x%p)\n", dev_list);
+-#endif
+-
+-  /* Go through the list */
+-  for (link = dev_list; link; link = next)
+-    {
+-      next = link->next;
+-
+-      /* Check if in need of being removed */
+-      if((link->state & DEV_STALE_LINK) ||
+-       (! (link->state & DEV_PRESENT)))
+-      wavelan_detach(link);
+-
+-    }
+-
+-#ifdef DEBUG_CONFIG_TRACE
+-  printk(KERN_DEBUG "<- wv_flush_stale_links()\n");
+-#endif
++  if (link->state & DEV_STALE_CONFIG)
++        wavelan_detach(link);
+ }
+ /************************ INTERRUPT HANDLING ************************/
+@@ -4705,9 +4669,6 @@
+   printk(KERN_DEBUG "-> wavelan_attach()\n");
+ #endif
+-  /* Perform some cleanup */
+-  wv_flush_stale_links();
+-
+   /* Initialize the dev_link_t structure */
+   link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+   if (!link) return NULL;
+@@ -4859,7 +4820,6 @@
+         printk(KERN_DEBUG "wavelan_detach: detach postponed,"
+                " '%s' still locked\n", link->dev->dev_name);
+ #endif
+-        link->state |= DEV_STALE_LINK;
+         return;
+       }
+     }
+@@ -5039,9 +4999,6 @@
+ static void __exit
+ exit_wavelan_cs(void)
+ {
+-      /* Do some cleanup of the device list */
+-      wv_flush_stale_links();
+-
+       pcmcia_unregister_driver(&wavelan_driver);
+ }
+Index: linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.p.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/wavelan_cs.p.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/wavelan_cs.p.h      2003-09-27 11:38:28.849142648 +0800
+@@ -761,8 +761,7 @@
+ static inline int
+       wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */
+ static void
+-      wv_pcmcia_release(dev_link_t *),/* Remove a device */
+-      wv_flush_stale_links(void);     /* "detach" all possible devices */
++      wv_pcmcia_release(dev_link_t *);/* Remove a device */
+ /* ---------------------- INTERRUPT HANDLING ---------------------- */
+ static irqreturn_t
+       wavelan_interrupt(int,  /* Interrupt handler */
+Index: linux-2.6.0-test5/drivers/net/wireless/wl3501_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/wireless/wl3501_cs.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/wireless/wl3501_cs.c 2003-09-27 11:38:28.867139912 +0800
+@@ -82,7 +82,7 @@
+ MODULE_PARM(pc_debug, "i");
+ #define dprintk(n, format, args...) \
+       { if (pc_debug > (n)) \
+-              printk(KERN_INFO "%s: " format "\n", __FUNCTION__, ##args); }
++              printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##args); }
+ #else
+ #define dprintk(n, format, args...)
+ #endif
+@@ -638,8 +638,10 @@
+               .sig_id           = WL3501_SIG_JOIN_REQ,
+               .timeout          = 10,
+               .ds_pset = {
+-                      .el.id  = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
+-                      .el.len = 1,
++                      .el = {
++                              .id  = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
++                              .len = 1,
++                      },
+                       .chan   = this->chan,
+               },
+       };
+@@ -655,13 +657,17 @@
+               .beacon_period          = 400,
+               .dtim_period            = 1,
+               .ds_pset = {
+-                      .el.id  = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
+-                      .el.len = 1,
++                      .el = {
++                              .id  = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
++                              .len = 1,
++                      },
+                       .chan   = this->chan,
+               },
+               .bss_basic_rset = {
+-                      .el.id  = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
+-                      .el.len = 2,
++                      .el = {
++                              .id     = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
++                              .len = 2,
++                      },
+                       .data_rate_labels = {
+                               [0] = IW_MGMT_RATE_LABEL_MANDATORY |
+                                     IW_MGMT_RATE_LABEL_1MBIT,
+@@ -670,8 +676,10 @@
+                       },
+               },
+               .operational_rset       = {
+-                      .el.id  = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
+-                      .el.len = 2,
++                      .el = {
++                              .id     = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
++                              .len = 2,
++                      },
+                       .data_rate_labels = {
+                               [0] = IW_MGMT_RATE_LABEL_MANDATORY |
+                                     IW_MGMT_RATE_LABEL_1MBIT,
+@@ -680,8 +688,10 @@
+                       },
+               },
+               .ibss_pset              = {
+-                      .el.id       = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
+-                      .el.len      = 2,
++                      .el = {
++                              .id      = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
++                              .len     = 2,
++                      },
+                       .atim_window = 10,
+               },
+               .bss_type               = wl3501_fw_bss_type(this),
+@@ -1571,7 +1581,6 @@
+               printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' "
+                      "still locked\n", link->dev->dev_name);
+ #endif
+-              link->state |= DEV_STALE_LINK;
+               goto out;
+       }
+@@ -1589,22 +1598,6 @@
+       return;
+ }
+-/**
+- * wl3501_flush_stale_links - Remove zombie instances
+- *
+- * Remove zombie instances (card removed, detach pending)
+- */
+-static void wl3501_flush_stale_links(void)
+-{
+-      dev_link_t *link, *next;
+-
+-      for (link = wl3501_dev_list; link; link = next) {
+-              next = link->next;
+-              if (link->state & DEV_STALE_LINK)
+-                      wl3501_detach(link);
+-      }
+-}
+-
+ static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info,
+                          union iwreq_data *wrqu, char *extra)
+ {
+@@ -2033,8 +2026,6 @@
+       struct net_device *dev;
+       int ret, i;
+-      wl3501_flush_stale_links();
+-
+       /* Initialize the dev_link_t structure */
+       link = kmalloc(sizeof(*link), GFP_KERNEL);
+       if (!link)
+@@ -2263,7 +2254,7 @@
+       CardServices(ReleaseIRQ, link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+-      if (link->state & DEV_STALE_LINK)
++      if (link->state & DEV_STALE_CONFIG)
+               wl3501_detach(link);
+ out:
+       return;
+Index: linux-2.6.0-test5/drivers/parisc/asp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/asp.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/asp.c     2003-09-27 11:38:28.869139608 +0800
+@@ -76,8 +76,6 @@
+       printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
+               asp->name, asp->version, dev->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+-               asp->name, asp->version);
+       /* the IRQ ASP should use */
+       ret = -EBUSY;
+Index: linux-2.6.0-test5/drivers/parisc/ccio-dma.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/ccio-dma.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/ccio-dma.c        2003-09-27 11:38:28.881137784 +0800
+@@ -129,6 +129,92 @@
+         volatile uint32_t   io_io_high;             /* Offset 15 */
+ };
++/*
++** IOA Registers
++** -------------
++**
++** Runway IO_CONTROL Register (+0x38)
++** 
++** The Runway IO_CONTROL register controls the forwarding of transactions.
++**
++** | 0  ...  13  |  14 15 | 16 ... 21 | 22 | 23 24 |  25 ... 31 |
++** |    HV       |   TLB  |  reserved | HV | mode  |  reserved  |
++**
++** o mode field indicates the address translation of transactions
++**   forwarded from Runway to GSC+:
++**       Mode Name     Value        Definition
++**       Off (default)   0          Opaque to matching addresses.
++**       Include         1          Transparent for matching addresses.
++**       Peek            3          Map matching addresses.
++**
++**       + "Off" mode: Runway transactions which match the I/O range
++**         specified by the IO_IO_LOW/IO_IO_HIGH registers will be ignored.
++**       + "Include" mode: all addresses within the I/O range specified
++**         by the IO_IO_LOW and IO_IO_HIGH registers are transparently
++**         forwarded. This is the I/O Adapter's normal operating mode.
++**       + "Peek" mode: used during system configuration to initialize the
++**         GSC+ bus. Runway Write_Shorts in the address range specified by
++**         IO_IO_LOW and IO_IO_HIGH are forwarded through the I/O Adapter
++**         *AND* the GSC+ address is remapped to the Broadcast Physical
++**         Address space by setting the 14 high order address bits of the
++**         32 bit GSC+ address to ones.
++**
++** o TLB field affects transactions which are forwarded from GSC+ to Runway.
++**   "Real" mode is the poweron default.
++** 
++**   TLB Mode  Value  Description
++**   Real        0    No TLB translation. Address is directly mapped and the
++**                    virtual address is composed of selected physical bits.
++**   Error       1    Software fills the TLB manually.
++**   Normal      2    IOA fetches IO TLB misses from IO PDIR (in host memory).
++**
++**
++** IO_IO_LOW_HV         +0x60 (HV dependent)
++** IO_IO_HIGH_HV  +0x64 (HV dependent)
++** IO_IO_LOW      +0x78       (Architected register)
++** IO_IO_HIGH     +0x7c       (Architected register)
++**
++** IO_IO_LOW and IO_IO_HIGH set the lower and upper bounds of the
++** I/O Adapter address space, respectively.
++**
++** 0  ... 7 | 8 ... 15 |  16   ...   31 |
++** 11111111 | 11111111 |      address   |
++**
++** Each LOW/HIGH pair describes a disjoint address space region.
++** (2 per GSC+ port). Each incoming Runway transaction address is compared
++** with both sets of LOW/HIGH registers. If the address is in the range
++** greater than or equal to IO_IO_LOW and less than IO_IO_HIGH the transaction
++** for forwarded to the respective GSC+ bus.
++** Specify IO_IO_LOW equal to or greater than IO_IO_HIGH to avoid specifying
++** an address space region.
++**
++** In order for a Runway address to reside within GSC+ extended address space:
++**    Runway Address [0:7]    must identically compare to 8'b11111111
++**    Runway Address [8:11]   must be equal to IO_IO_LOW(_HV)[16:19]
++**    Runway Address [12:23]  must be greater than or equal to
++**               IO_IO_LOW(_HV)[20:31] and less than IO_IO_HIGH(_HV)[20:31].
++**    Runway Address [24:39]  is not used in the comparison.
++**
++** When the Runway transaction is forwarded to GSC+, the GSC+ address is
++** as follows:
++**    GSC+ Address[0:3]       4'b1111
++**    GSC+ Address[4:29]      Runway Address[12:37]
++**    GSC+ Address[30:31]     2'b00
++**
++** All 4 Low/High registers must be initialized (by PDC) once the lower bus
++** is interrogated and address space is defined. The operating system will
++** modify the architectural IO_IO_LOW and IO_IO_HIGH registers following
++** the PDC initialization.  However, the hardware version dependent IO_IO_LOW
++** and IO_IO_HIGH registers should not be subsequently altered by the OS.
++** 
++** Writes to both sets of registers will take effect immediately, bypassing
++** the queues, which ensures that subsequent Runway transactions are checked
++** against the updated bounds values. However reads are queued, introducing
++** the possibility of a read being bypassed by a subsequent write to the same
++** register. This sequence can be avoided by having software wait for read
++** returns before issuing subsequent writes.
++*/
++
+ struct ioc {
+       struct ioa_registers *ioc_hpa;  /* I/O MMU base address */
+       u8  *res_map;                   /* resource map, bit == pdir entry */
+@@ -1448,13 +1534,74 @@
+                       (unsigned long)&ioc->ioc_hpa->io_io_low_hv);
+ }
+-static void expand_ioc_area(struct ioc *ioc, unsigned long size,
+-              unsigned long min, unsigned long max, unsigned long align)
++static int expand_resource(struct resource *res, unsigned long size,
++                         unsigned long align)
+ {
+-#ifdef NASTY_HACK_FOR_K_CLASS
+-      __raw_writel(0xfffff600, (unsigned long)&(ioc->ioc_hpa->io_io_high));
+-      ioc->mmio_region[0].end = 0xf5ffffff;
+-#endif
++      struct resource *temp_res;
++      unsigned long start = res->start;
++      unsigned long end ;
++
++      /* see if we can expand above */
++      end = (res->end + size + align - 1) & ~(align - 1);;
++      
++      temp_res = __request_region(res->parent, res->end, end - res->end,
++                                  "expansion");
++      if(!temp_res) {
++              /* now try below */
++              start = ((res->start - size + align) & ~(align - 1)) - align;
++              end = res->end;
++              temp_res = __request_region(res->parent, start, size,
++                                          "expansion");       
++              if(!temp_res) {
++                      return -ENOMEM;
++              }
++      } 
++      release_resource(temp_res);
++      temp_res = res->parent;
++      release_resource(res);
++      res->start = start;
++      res->end = end;
++
++      /* This could be caused by some sort of race.  Basically, if
++       * this tripped something stole the region we just reserved
++       * and then released to check for expansion */
++      BUG_ON(request_resource(temp_res, res) != 0);
++
++      return 0;
++}
++
++static void expand_ioc_area(struct resource *parent, struct ioc *ioc,
++                          unsigned long size, unsigned long min,
++                          unsigned long max, unsigned long align)
++{
++      if(ioc == NULL)
++              /* no IOC, so nothing to expand */
++              return;
++
++      if (expand_resource(parent, size, align) != 0) {
++              printk(KERN_ERR "Unable to expand %s window by 0x%lx\n",
++                     parent->name, size);
++              return;
++      }
++
++      /* OK, we have the memory, now expand the window */
++      if (parent == &ioc->mmio_region[0]) {
++              __raw_writel(((parent->start)>>16) | 0xffff0000,
++                           (unsigned long)&(ioc->ioc_hpa->io_io_low));
++              __raw_writel(((parent->end)>>16) | 0xffff0000,
++                           (unsigned long)&(ioc->ioc_hpa->io_io_high));
++      } else if (parent == &ioc->mmio_region[1]) {
++              __raw_writel(((parent->start)>>16) | 0xffff0000,
++                           (unsigned long)&(ioc->ioc_hpa->io_io_low_hv));
++              __raw_writel(((parent->end)>>16) | 0xffff0000,
++                           (unsigned long)&(ioc->ioc_hpa->io_io_high_hv));
++      } else {
++              /* This should be impossible.  It means
++               * expand_ioc_area got called with a resource that
++               * didn't belong to the ioc
++               */
++              BUG();
++      }
+ }
+ static struct resource *ccio_get_resource(struct ioc* ioc,
+@@ -1488,7 +1635,7 @@
+                       alignf_data))
+               return 0;
+-      expand_ioc_area(ioc, size, min, max, align);
++      expand_ioc_area(parent, ioc, size, min, max, align);
+       return allocate_resource(parent, res, size, min, max, align, alignf,
+                       alignf_data);
+ }
+@@ -1522,7 +1669,6 @@
+       memset(ioc, 0, sizeof(struct ioc));
+       ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
+-      strlcpy(dev->dev.name, ioc->name, sizeof(dev->dev.name));
+       printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
+Index: linux-2.6.0-test5/drivers/parisc/dino.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/dino.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/dino.c    2003-09-27 11:38:28.889136568 +0800
+@@ -401,23 +401,7 @@
+       {
+               int irq;
+-              /*
+-               * Perform a binary search on set bits.
+-               * `Less than Fatal' and PS2 interrupts aren't supported.
+-               */
+-              if (mask & 0xf) {
+-                      if (mask & 0x3) {
+-                              irq = (mask & 0x1) ? 0 : 1; /* PCI INT A, B */
+-                      } else {
+-                              irq = (mask & 0x4) ? 2 : 3; /* PCI INT C, D */
+-                      }
+-              } else {
+-                      if (mask & 0x30) {
+-                              irq = (mask & 0x10) ? 4 : 5; /* PCI INT E, F */
+-                      } else {
+-                              irq = (mask & 0x40) ? 6 : 10; /* GSC, RS232 */
+-                      }
+-              }
++              irq = __ffs(mask);
+               mask &= ~(1<<irq);
+@@ -440,7 +424,7 @@
+       if (mask) {
+               if (--ilr_loop > 0)
+                       goto ilr_again;
+-              printk("Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask);
++              printk(KERN_ERR "Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask);
+               return IRQ_NONE;
+       }
+       return IRQ_HANDLED;
+@@ -479,15 +463,35 @@
+       int i;
+       struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
+       struct resource *res;
++      char name[128];
++      int size;
+       res = &dino_dev->hba.lmmio_space;
+       res->flags = IORESOURCE_MEM;
++      size = snprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->dev->bus_id);
++      res->name = kmalloc(size+1, GFP_KERNEL);
++      if(res->name)
++              strcpy((char *)res->name, name);
++      else
++              res->name = dino_dev->hba.lmmio_space.name;
++      
+       if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB,
+-                              (unsigned long) 0xfffffffff0000000UL | _8MB,
+-                              0xffffffffffffffffUL &~ _8MB, _8MB,
++                              F_EXTEND(0xf0000000UL) | _8MB,
++                              F_EXTEND(0xffffffffUL) &~ _8MB, _8MB,
+                               NULL, NULL) < 0) {
+-              printk(KERN_WARNING "Dino: Failed to allocate memory region\n");
++              struct list_head *ln, *tmp_ln;
++
++              printk(KERN_ERR "Dino: cannot attach bus %s\n",
++                     bus->dev->bus_id);
++              /* kill the bus, we can't do anything with it */
++              list_for_each_safe(ln, tmp_ln, &bus->devices) {
++                      struct pci_dev *dev = pci_dev_b(ln);
++
++                      list_del(&dev->global_list);
++                      list_del(&dev->bus_list);
++              }
++                      
+               return;
+       }
+       bus->resource[1] = res;
+@@ -495,9 +499,11 @@
+       /* Now tell dino what range it has */
+       for (i = 1; i < 31; i++) {
+-              if (res->start == (0xfffffffff0000000UL | i * _8MB))
++              if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB)))
+                       break;
+       }
++      DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %lx\n",
++          i, res->start, base_addr + DINO_IO_ADDR_EN);
+       gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
+       pci_bus_assign_resources(bus);
+@@ -521,7 +527,7 @@
+       ** Set Latency Timer to 0xff (not a shared bus)
+       ** Set CACHELINE_SIZE.
+       */
+-      dino_cfg_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 16, 0xff00 | L1_CACHE_BYTES/4); 
++      dino_cfg_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); 
+       /*
+       ** Program INT_LINE for card-mode devices.
+@@ -532,13 +538,13 @@
+       ** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range.
+       ** The additional "-1" adjusts for skewing the IRQ<->slot.
+       */
+-      dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 8, &irq_pin); 
++      dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); 
+       dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
+       /* Shouldn't really need to do this but it's in case someone tries
+       ** to bypass PCI services and look at the card themselves.
+       */
+-      dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 8, dev->irq); 
++      dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq); 
+ }
+@@ -585,8 +591,8 @@
+ #ifdef __LP64__
+                       /* Sign Extend MMIO addresses */
+                       else if (res->flags & IORESOURCE_MEM) {
+-                              res->start |= 0xffffffff00000000UL;
+-                              res->end   |= 0xffffffff00000000UL;
++                              res->start |= F_EXTEND(0UL);
++                              res->end   |= F_EXTEND(0UL);
+                       }
+ #endif
+               }
+@@ -789,8 +795,8 @@
+       return 0;
+ }
+-#define CUJO_RAVEN_ADDR               0xfffffffff1000000UL
+-#define CUJO_FIREHAWK_ADDR    0xfffffffff1604000UL
++#define CUJO_RAVEN_ADDR               F_EXTEND(0xf1000000UL)
++#define CUJO_FIREHAWK_ADDR    F_EXTEND(0xf1604000UL)
+ #define CUJO_RAVEN_BADPAGE    0x01003000UL
+ #define CUJO_FIREHAWK_BADPAGE 0x01607000UL
+@@ -818,9 +824,16 @@
+ {
+       struct dino_device *dino_dev;   // Dino specific control struct
+       const char *version = "unknown";
+-      const char *name = "Dino";
++      const int name_len = 32;
++      char *name;
+       int is_cujo = 0;
++      name = kmalloc(name_len, GFP_KERNEL);
++      if(name)
++              snprintf(name, name_len, "Dino %s", dev->dev.bus_id);
++      else
++              name = "Dino";
++
+       if (is_card_dino(&dev->id)) {
+               version = "3.x (card mode)";
+       } else {
+@@ -838,8 +851,6 @@
+       }
+       printk("%s version %s found at 0x%lx\n", name, version, dev->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), 
+-               "%s version %s", name, version);
+       if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) {
+               printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n",
+Index: linux-2.6.0-test5/drivers/parisc/eisa.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/eisa.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/eisa.c    2003-09-27 11:38:28.893135960 +0800
+@@ -327,14 +327,13 @@
+       printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
+               name, dev->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), "%s EISA", name);
+       eisa_dev.hba.dev = dev;
+       eisa_dev.hba.iommu = ccio_get_iommu(dev);
+       eisa_dev.hba.lmmio_space.name = "EISA";
+-      eisa_dev.hba.lmmio_space.start = (unsigned long) 0xfffffffffc000000;
+-      eisa_dev.hba.lmmio_space.end = (unsigned long) 0xffffffffffbfffff;
++      eisa_dev.hba.lmmio_space.start = F_EXTEND(0xfc000000);
++      eisa_dev.hba.lmmio_space.end = F_EXTEND(0xffbfffff);
+       eisa_dev.hba.lmmio_space.flags = IORESOURCE_MEM;
+       result = ccio_request_resource(dev, &eisa_dev.hba.lmmio_space);
+       if (result < 0) {
+Index: linux-2.6.0-test5/drivers/parisc/hppb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/hppb.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/hppb.c    2003-09-27 11:38:28.895135656 +0800
+@@ -70,7 +70,6 @@
+               card = card->next;
+       }
+         printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), "GeckoBoa");
+       card->hpa = dev->hpa;
+       card->mmio_region.name = "HP-PB Bus";
+Index: linux-2.6.0-test5/drivers/parisc/iosapic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/iosapic.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/iosapic.c 2003-09-27 11:38:28.904134288 +0800
+@@ -643,7 +643,7 @@
+       if (NULL == isi) {
+               printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
+-                      pcidev->dev.name);
++                      pci_name(pcidev));
+               return(-1);
+       }
+Index: linux-2.6.0-test5/drivers/parisc/lasi.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/lasi.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/lasi.c    2003-09-27 11:38:28.906133984 +0800
+@@ -185,8 +185,6 @@
+       lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
+       printk(KERN_INFO "%s version %d at 0x%lx found.\n",
+               lasi->name, lasi->version, lasi->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+-               lasi->name, lasi->version);
+       /* initialize the chassis LEDs really early */ 
+       lasi_led_init(lasi->hpa);
+Index: linux-2.6.0-test5/drivers/parisc/lba_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/lba_pci.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/lba_pci.c 2003-09-27 11:38:28.917132312 +0800
+@@ -782,7 +782,7 @@
+               int i;
+               struct pci_dev *dev = pci_dev_b(ln);
+-              DBG("lba_fixup_bus() %s\n", dev->name);
++              DBG("lba_fixup_bus() %s\n", pci_name(dev));
+               /* Virtualize Device/Bridge Resources. */
+               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+@@ -1358,8 +1358,6 @@
+       printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+               MODULE_NAME, version, func_class & 0xf, dev->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+-               MODULE_NAME, version);
+       /* Just in case we find some prototypes... */
+       if (func_class < 2) {
+Index: linux-2.6.0-test5/drivers/parisc/led.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/led.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/led.c     2003-09-27 11:38:28.923131400 +0800
+@@ -91,7 +91,7 @@
+ /* LCD_CMD and LCD_DATA for KittyHawk machines */
+-#define KITTYHAWK_LCD_CMD  (0xfffffffff0190000UL) /* 64bit-ready */
++#define KITTYHAWK_LCD_CMD  F_EXTEND(0xf0190000UL) /* 64bit-ready */
+ #define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1)
+ /* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's 
+Index: linux-2.6.0-test5/drivers/parisc/sba_iommu.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/sba_iommu.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/sba_iommu.c       2003-09-27 11:38:28.938129120 +0800
+@@ -1978,8 +1978,6 @@
+       printk(KERN_INFO "%s found %s at 0x%lx\n",
+               MODULE_NAME, version, dev->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+-               MODULE_NAME, version);
+ #ifdef DEBUG_SBA_INIT
+       sba_dump_tlb(dev->hpa);
+Index: linux-2.6.0-test5/drivers/parisc/wax.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/parisc/wax.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/parisc/wax.c     2003-09-27 11:38:28.940128816 +0800
+@@ -83,8 +83,6 @@
+       wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
+       printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
+-      snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+-               wax->name, wax->version);
+       /* Stop wax hissing for a bit */
+       wax_init_irq(wax);
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_core.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_core.c       2003-09-27 11:38:28.944128208 +0800
+@@ -1,12 +1,12 @@
+ /*
+  * ACPI PCI Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002,2003 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002,2003 NEC Corporation
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_glue.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_glue.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_glue.c       2003-09-27 11:38:28.952126992 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * ACPI PCI HotPlug glue functions to ACPI CA subsystem
+  *
+- * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002,2003 NEC Corporation
++ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002,2003 NEC Corporation
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp.h    2003-09-27 11:38:28.955126536 +0800
+@@ -1,12 +1,12 @@
+ /*
+  * ACPI PCI Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002,2003 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002,2003 NEC Corporation
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_pci.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_pci.c        2003-09-27 11:38:28.959125928 +0800
+@@ -1,12 +1,12 @@
+ /*
+  * ACPI PCI HotPlug PCI configuration space management
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2002 IBM Corp.
+- * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2002 IBM Corp.
++ * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002 NEC Corporation
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_res.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/acpiphp_res.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/acpiphp_res.c        2003-09-27 11:38:28.965125016 +0800
+@@ -1,12 +1,12 @@
+ /*
+  * ACPI PCI HotPlug Utility functions
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
+- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+- * Copyright (c) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+- * Copyright (c) 2002 NEC Corporation
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
++ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
++ * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
++ * Copyright (C) 2002 NEC Corporation
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpci_hotplug_core.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_core.c  2003-09-27 11:38:28.971124104 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * CompactPCI Hot Plug Driver
+  *
+- * Copyright (c) 2002 SOMA Networks, Inc.
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 2002 SOMA Networks, Inc.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpci_hotplug.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug.h       2003-09-27 11:38:28.972123952 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * CompactPCI Hot Plug Core Functions
+  *
+- * Copyright (c) 2002 SOMA Networks, Inc.
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 2002 SOMA Networks, Inc.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpci_hotplug_pci.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpci_hotplug_pci.c   2003-09-27 11:38:28.977123192 +0800
+@@ -1,7 +1,7 @@
+ /*
+  * CompactPCI Hot Plug Driver PCI functions
+  *
+- * Copyright (c) 2002 by SOMA Networks, Inc.
++ * Copyright (C) 2002 by SOMA Networks, Inc.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_core.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_core.c        2003-09-27 11:38:28.987121672 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * Compaq Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_ctrl.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_ctrl.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_ctrl.c        2003-09-27 11:38:29.007118632 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * Compaq Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp.h     2003-09-27 11:38:29.015117416 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * Compaq Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_nvram.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.c       2003-09-27 11:38:29.019116808 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * Compaq Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_nvram.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_nvram.h       2003-09-27 11:38:29.020116656 +0800
+@@ -1,8 +1,8 @@
+ /*
+  * Compaq Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_pci.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_pci.c 2003-09-27 11:38:29.031114984 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * Compaq Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_sysfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/cpqphp_sysfs.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/cpqphp_sysfs.c       2003-09-27 11:38:29.034114528 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * Compaq Hot Plug Controller Driver
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/fakephp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/fakephp.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/fakephp.c    2003-09-27 11:38:29.036114224 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * Fake PCI Hot Plug Controller Driver
+  *
+- * Copyright (c) 2003 Greg Kroah-Hartman <greg@kroah.com>
+- * Copyright (c) 2003 IBM Corp.
+- * Copyright (c) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
++ * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
++ * Copyright (C) 2003 IBM Corp.
++ * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
+  *
+  * Based on ideas and code from:
+  *    Vladimir Kondratiev <vladimir.kondratiev@intel.com>
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_core.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_core.c        2003-09-27 11:38:29.046112704 +0800
+@@ -3,8 +3,8 @@
+  *
+  * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+  *
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2003 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_ebda.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_ebda.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_ebda.c        2003-09-27 11:38:29.056111184 +0800
+@@ -3,8 +3,8 @@
+  *
+  * Written By: Tong Yu, IBM Corporation
+  *
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2003 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp.h     2003-09-27 11:38:29.064109968 +0800
+@@ -6,8 +6,8 @@
+  *
+  * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+  *
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2003 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_hpc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_hpc.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_hpc.c 2003-09-27 11:38:29.073108600 +0800
+@@ -3,7 +3,7 @@
+  *
+  * Written By: Jyoti Shah, IBM Corporation
+  *
+- * Copyright (c) 2001-2003 IBM Corp.
++ * Copyright (C) 2001-2003 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_pci.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_pci.c 2003-09-27 11:38:29.088106320 +0800
+@@ -3,8 +3,8 @@
+  * 
+  * Written By: Irene Zubarev, IBM Corporation
+  * 
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2002 IBM Corp.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2002 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_res.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/ibmphp_res.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/ibmphp_res.c 2003-09-27 11:38:29.104103888 +0800
+@@ -3,8 +3,8 @@
+  *
+  * Written By: Irene Zubarev, IBM Corporation
+  *
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2002 IBM Corp.
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2002 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/pci_hotplug_core.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug_core.c   2003-09-27 11:38:29.110102976 +0800
+@@ -1,8 +1,8 @@
+ /*
+  * PCI HotPlug Controller Core
+  *
+- * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001-2002 IBM Corp.
++ * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001-2002 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/pci_hotplug.h   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/pci_hotplug.h        2003-09-27 11:38:29.112102672 +0800
+@@ -1,9 +1,9 @@
+ /*
+  * PCI HotPlug Core Functions
+  *
+- * Copyright (c) 1995,2001 Compaq Computer Corporation
+- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001 IBM Corp.
++ * Copyright (C) 1995,2001 Compaq Computer Corporation
++ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/hotplug/pcihp_skeleton.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/hotplug/pcihp_skeleton.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/hotplug/pcihp_skeleton.c     2003-09-27 11:38:29.116102064 +0800
+@@ -1,8 +1,8 @@
+ /*
+  * PCI Hot Plug Controller Skeleton Driver - 0.2
+  *
+- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+- * Copyright (c) 2001,2003 IBM Corp.
++ * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
++ * Copyright (C) 2001,2003 IBM Corp.
+  *
+  * All rights reserved.
+  *
+Index: linux-2.6.0-test5/drivers/pci/pci-driver.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/pci-driver.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/pci-driver.c 2003-09-27 11:38:29.121101304 +0800
+@@ -35,6 +35,173 @@
+       return NULL;
+ }
++/*
++ * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
++ */
++
++#ifdef CONFIG_HOTPLUG
++/**
++ * pci_device_probe_dynamic()
++ *
++ * Walk the dynamic ID list looking for a match.
++ * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
++ */
++static int
++pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
++{
++      int error = -ENODEV;
++      struct list_head *pos;
++      struct dynid *dynid;
++
++      spin_lock(&drv->dynids.lock);
++      list_for_each(pos, &drv->dynids.list) {
++              dynid = list_entry(pos, struct dynid, node);
++              if (pci_match_one_device(&dynid->id, pci_dev)) {
++                      spin_unlock(&drv->dynids.lock);
++                      error = drv->probe(pci_dev, &dynid->id);
++                      if (error >= 0) {
++                              pci_dev->driver = drv;
++                              return 0;
++                      }
++                      return error;
++              }
++      }
++      spin_unlock(&drv->dynids.lock);
++      return error;
++}
++
++static inline void
++dynid_init(struct dynid *dynid)
++{
++      memset(dynid, 0, sizeof(*dynid));
++      INIT_LIST_HEAD(&dynid->node);
++}
++
++/**
++ * store_new_id
++ *
++ * Adds a new dynamic pci device ID to this driver,
++ * and causes the driver to probe for all devices again.
++ */
++static inline ssize_t
++store_new_id(struct device_driver *driver, const char *buf, size_t count)
++{
++      struct dynid *dynid;
++      struct bus_type * bus;
++      struct pci_driver *pdrv = to_pci_driver(driver);
++      __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
++              subdevice=PCI_ANY_ID, class=0, class_mask=0;
++      unsigned long driver_data=0;
++      int fields=0;
++
++      fields = sscanf(buf, "%x %x %x %x %x %x %lux",
++                      &vendor, &device, &subvendor, &subdevice,
++                      &class, &class_mask, &driver_data);
++      if (fields < 0)
++              return -EINVAL;
++
++      dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
++      if (!dynid)
++              return -ENOMEM;
++      dynid_init(dynid);
++
++      dynid->id.vendor = vendor;
++      dynid->id.device = device;
++      dynid->id.subvendor = subvendor;
++      dynid->id.subdevice = subdevice;
++      dynid->id.class = class;
++      dynid->id.class_mask = class_mask;
++      dynid->id.driver_data = pdrv->dynids.use_driver_data ?
++              driver_data : 0UL;
++
++      spin_lock(&pdrv->dynids.lock);
++      list_add_tail(&pdrv->dynids.list, &dynid->node);
++      spin_unlock(&pdrv->dynids.lock);
++
++      bus = get_bus(pdrv->driver.bus);
++      if (bus) {
++              if (get_driver(&pdrv->driver)) {
++                      down_write(&bus->subsys.rwsem);
++                      driver_attach(&pdrv->driver);
++                      up_write(&bus->subsys.rwsem);
++                      put_driver(&pdrv->driver);
++              }
++              put_bus(bus);
++      }
++
++      return count;
++}
++
++static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
++static inline void
++pci_init_dynids(struct pci_dynids *dynids)
++{
++      memset(dynids, 0, sizeof(*dynids));
++      spin_lock_init(&dynids->lock);
++      INIT_LIST_HEAD(&dynids->list);
++}
++
++static void
++pci_free_dynids(struct pci_driver *drv)
++{
++      struct list_head *pos, *n;
++      struct dynid *dynid;
++
++      spin_lock(&drv->dynids.lock);
++      list_for_each_safe(pos, n, &drv->dynids.list) {
++              dynid = list_entry(pos, struct dynid, node);
++              list_del(&dynid->node);
++              kfree(dynid);
++      }
++      spin_unlock(&drv->dynids.lock);
++}
++
++static int
++pci_create_newid_file(struct pci_driver *drv)
++{
++      int error = 0;
++      if (drv->probe != NULL)
++              error = sysfs_create_file(&drv->driver.kobj,
++                                        &driver_attr_new_id.attr);
++      return error;
++}
++
++static int
++pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
++{
++      struct list_head *pos;
++      struct dynid *dynid;
++
++      spin_lock(&pci_drv->dynids.lock);
++      list_for_each(pos, &pci_drv->dynids.list) {
++              dynid = list_entry(pos, struct dynid, node);
++              if (pci_match_one_device(&dynid->id, pci_dev)) {
++                      spin_unlock(&pci_drv->dynids.lock);
++                      return 1;
++              }
++      }
++      spin_unlock(&pci_drv->dynids.lock);
++      return 0;
++}
++
++#else /* !CONFIG_HOTPLUG */
++static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
++{
++      return -ENODEV;
++}
++static inline void dynid_init(struct dynid *dynid) {}
++static inline void pci_init_dynids(struct pci_dynids *dynids) {}
++static inline void pci_free_dynids(struct pci_driver *drv) {}
++static inline int pci_create_newid_file(struct pci_driver *drv)
++{
++      return 0;
++}
++static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
++{
++      return 0;
++}
++#endif
++
+ /**
+  * pci_match_device - Tell if a PCI device structure has a matching
+  *                    PCI device id structure
+@@ -80,36 +247,6 @@
+ }
+ /**
+- * pci_device_probe_dynamic()
+- * 
+- * Walk the dynamic ID list looking for a match.
+- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
+- */
+-static int
+-pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
+-{                
+-      int error = -ENODEV;
+-      struct list_head *pos;
+-      struct dynid *dynid;
+-
+-      spin_lock(&drv->dynids.lock);
+-      list_for_each(pos, &drv->dynids.list) {
+-              dynid = list_entry(pos, struct dynid, node);
+-              if (pci_match_one_device(&dynid->id, pci_dev)) {
+-                      spin_unlock(&drv->dynids.lock);
+-                      error = drv->probe(pci_dev, &dynid->id);
+-                      if (error >= 0) {
+-                              pci_dev->driver = drv;
+-                              return 0;
+-                      }
+-                      return error;
+-              }
+-      }
+-      spin_unlock(&drv->dynids.lock);
+-      return error;
+-}
+-
+-/**
+  * __pci_device_probe()
+  * 
+  * returns 0  on success, else error.
+@@ -178,72 +315,6 @@
+       return 0;
+ }
+-static inline void
+-dynid_init(struct dynid *dynid)
+-{
+-      memset(dynid, 0, sizeof(*dynid));
+-      INIT_LIST_HEAD(&dynid->node);
+-}
+-
+-/**
+- * store_new_id
+- * @ pdrv
+- * @ buf
+- * @ count
+- *
+- * Adds a new dynamic pci device ID to this driver,
+- * and causes the driver to probe for all devices again.
+- */
+-static inline ssize_t
+-store_new_id(struct device_driver * driver, const char * buf, size_t count)
+-{
+-      struct dynid *dynid;
+-      struct bus_type * bus;
+-      struct pci_driver *pdrv = to_pci_driver(driver);
+-      __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
+-              subdevice=PCI_ANY_ID, class=0, class_mask=0;
+-      unsigned long driver_data=0;
+-      int fields=0;
+-
+-      fields = sscanf(buf, "%x %x %x %x %x %x %lux",
+-                      &vendor, &device, &subvendor, &subdevice,
+-                      &class, &class_mask, &driver_data);
+-      if (fields < 0)
+-              return -EINVAL;
+-
+-      dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
+-      if (!dynid)
+-              return -ENOMEM;
+-      dynid_init(dynid);
+-
+-      dynid->id.vendor = vendor;
+-      dynid->id.device = device;
+-      dynid->id.subvendor = subvendor;
+-      dynid->id.subdevice = subdevice;
+-      dynid->id.class = class;
+-      dynid->id.class_mask = class_mask;
+-      dynid->id.driver_data = pdrv->dynids.use_driver_data ?
+-              driver_data : 0UL;
+-
+-      spin_lock(&pdrv->dynids.lock);
+-      list_add_tail(&pdrv->dynids.list, &dynid->node);
+-      spin_unlock(&pdrv->dynids.lock);
+-
+-      bus = get_bus(pdrv->driver.bus);
+-      if (bus) {
+-              if (get_driver(&pdrv->driver)) {
+-                      down_write(&bus->subsys.rwsem);
+-                      driver_attach(&pdrv->driver);
+-                      up_write(&bus->subsys.rwsem);
+-                      put_driver(&pdrv->driver);
+-              }
+-              put_bus(bus);
+-      }
+-      
+-      return count;
+-}
+-
+-static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+ #define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
+ #define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
+@@ -288,40 +359,11 @@
+ };
+ static int
+-pci_populate_driver_dir(struct pci_driver * drv)
+-{
+-      int error = 0;
+-
+-      if (drv->probe != NULL)
+-              error = sysfs_create_file(&drv->driver.kobj,
+-                                        &driver_attr_new_id.attr);
+-      return error;
+-}
+-
+-static inline void
+-pci_init_dynids(struct pci_dynids *dynids)
+-{
+-      memset(dynids, 0, sizeof(*dynids));
+-      spin_lock_init(&dynids->lock);
+-      INIT_LIST_HEAD(&dynids->list);
+-}
+-
+-static void
+-pci_free_dynids(struct pci_driver *drv)
++pci_populate_driver_dir(struct pci_driver *drv)
+ {
+-      struct list_head *pos, *n;
+-      struct dynid *dynid;
+-
+-      spin_lock(&drv->dynids.lock);
+-      list_for_each_safe(pos, n, &drv->dynids.list) {
+-              dynid = list_entry(pos, struct dynid, node);
+-              list_del(&dynid->node);
+-              kfree(dynid);
+-      }
+-      spin_unlock(&drv->dynids.lock);
++      return pci_create_newid_file(drv);
+ }
+-
+ /**
+  * pci_register_driver - register a new pci driver
+  * @drv: the driver structure to register
+@@ -411,8 +453,6 @@
+       struct pci_driver * pci_drv = to_pci_driver(drv);
+       const struct pci_device_id * ids = pci_drv->id_table;
+       const struct pci_device_id *found_id;
+-      struct list_head *pos;
+-      struct dynid *dynid;
+       if (!ids)
+               return 0;
+@@ -421,17 +461,7 @@
+       if (found_id)
+               return 1;
+-      spin_lock(&pci_drv->dynids.lock);
+-      list_for_each(pos, &pci_drv->dynids.list) {
+-              dynid = list_entry(pos, struct dynid, node);
+-              if (pci_match_one_device(&dynid->id, pci_dev)) {
+-                      spin_unlock(&pci_drv->dynids.lock);
+-                      return 1;
+-              }
+-      }
+-      spin_unlock(&pci_drv->dynids.lock);
+-
+-      return 0;
++      return pci_bus_match_dynids(pci_dev, pci_drv);
+ }
+ /**
+Index: linux-2.6.0-test5/drivers/pci/probe.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pci/probe.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pci/probe.c      2003-09-27 11:38:29.126100544 +0800
+@@ -176,7 +176,7 @@
+               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 @@
+       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 @@
+               }
+ #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;
+Index: linux-2.6.0-test5/drivers/pcmcia/cardbus.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/cardbus.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/cardbus.c 2003-09-27 11:38:29.128100240 +0800
+@@ -29,18 +29,11 @@
+     the provisions above, a recipient may use your version of this
+     file under either the MPL or the GPL.
+     
+-    These routines handle allocating resources for Cardbus cards, as
+-    well as setting up and shutting down Cardbus sockets.  They are
+-    called from cs.c in response to Request/ReleaseConfiguration and
+-    Request/ReleaseIO calls.
+-
+ ======================================================================*/
+ /*
+- * This file is going away.  Cardbus handling has been re-written to be
+- * more of a PCI bridge thing, and the PCI code basically does all the
+- * resource handling. This has wrappers to make the rest of the PCMCIA
+- * subsystem not notice that it's not here any more.
++ * Cardbus handling has been re-written to be more of a PCI bridge thing,
++ * and the PCI code basically does all the resource handling.
+  *
+  *            Linus, Jan 2000
+  */
+Index: linux-2.6.0-test5/drivers/pcmcia/cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/cs.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/cs.c      2003-09-27 11:38:29.148097200 +0800
+@@ -244,13 +244,10 @@
+ static int socket_resume(struct pcmcia_socket *skt);
+ static int socket_suspend(struct pcmcia_socket *skt);
+-int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level)
++int pcmcia_socket_dev_suspend(struct device *dev, u32 state)
+ {
+       struct pcmcia_socket *socket;
+-      if (level != SUSPEND_SAVE_STATE)
+-              return 0;
+-
+       down_read(&pcmcia_socket_list_rwsem);
+       list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+               if (socket->dev.dev != dev)
+@@ -265,13 +262,10 @@
+ }
+ EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
+-int pcmcia_socket_dev_resume(struct device *dev, u32 level)
++int pcmcia_socket_dev_resume(struct device *dev)
+ {
+       struct pcmcia_socket *socket;
+-      if (level != RESUME_RESTORE_STATE)
+-              return 0;
+-
+       down_read(&pcmcia_socket_list_rwsem);
+       list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
+               if (socket->dev.dev != dev)
+@@ -287,72 +281,29 @@
+ EXPORT_SYMBOL(pcmcia_socket_dev_resume);
+-static int pccardd(void *__skt);
+-#define to_class_data(dev) dev->class_data
+-
+-static int pcmcia_add_socket(struct class_device *class_dev)
+-{
+-      struct pcmcia_socket *socket = class_get_devdata(class_dev);
+-      int ret = 0;
+-
+-      /* base address = 0, map = 0 */
+-      socket->cis_mem.flags = 0;
+-      socket->cis_mem.speed = cis_speed;
+-      socket->erase_busy.next = socket->erase_busy.prev = &socket->erase_busy;
+-      INIT_LIST_HEAD(&socket->cis_cache);
+-      spin_lock_init(&socket->lock);
+-
+-      init_completion(&socket->thread_done);
+-      init_waitqueue_head(&socket->thread_wait);
+-      init_MUTEX(&socket->skt_sem);
+-      spin_lock_init(&socket->thread_lock);
+-
+-      socket->socket = dead_socket;
+-      socket->ops->init(socket);
+-
+-      ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
+-      if (ret < 0)
+-              return ret;
+-
+-      wait_for_completion(&socket->thread_done);
+-      BUG_ON(!socket->thread);
+-      pcmcia_parse_events(socket, SS_DETECT);
+-
+-      return 0;
+-}
+-
+-static void pcmcia_remove_socket(struct class_device *class_dev)
++static void pcmcia_release_socket(struct class_device *class_dev)
+ {
+       struct pcmcia_socket *socket = class_get_devdata(class_dev);
+       client_t *client;
+-      if (socket->thread) {
+-              init_completion(&socket->thread_done);
+-              socket->thread = NULL;
+-              wake_up(&socket->thread_wait);
+-              wait_for_completion(&socket->thread_done);
+-      }
+-      release_cis_mem(socket);
+       while (socket->clients) {
+               client = socket->clients;
+               socket->clients = socket->clients->next;
+               kfree(client);
+       }
+-      socket->ops = NULL;
+-}
+-static void pcmcia_release_socket(struct class_device *class_dev)
+-{
+-      struct pcmcia_socket *socket = class_get_devdata(class_dev);
+       complete(&socket->socket_released);
+ }
++static int pccardd(void *__skt);
+ /**
+  * pcmcia_register_socket - add a new pcmcia socket device
+  */
+ int pcmcia_register_socket(struct pcmcia_socket *socket)
+ {
++      int ret;
++
+       if (!socket || !socket->ops || !socket->dev.dev)
+               return -EINVAL;
+@@ -387,15 +338,34 @@
+       socket->dev.class = &pcmcia_socket_class;
+       snprintf(socket->dev.class_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
+-      /* register with the device core */
+-      if (class_device_register(&socket->dev)) {
+-              down_write(&pcmcia_socket_list_rwsem);
+-              list_del(&socket->socket_list);
+-              up_write(&pcmcia_socket_list_rwsem);
+-              return -EINVAL;
+-      }
++      /* base address = 0, map = 0 */
++      socket->cis_mem.flags = 0;
++      socket->cis_mem.speed = cis_speed;
++      socket->erase_busy.next = socket->erase_busy.prev = &socket->erase_busy;
++      INIT_LIST_HEAD(&socket->cis_cache);
++      spin_lock_init(&socket->lock);
++
++      init_completion(&socket->socket_released);
++      init_completion(&socket->thread_done);
++      init_waitqueue_head(&socket->thread_wait);
++      init_MUTEX(&socket->skt_sem);
++      spin_lock_init(&socket->thread_lock);
++
++      ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
++      if (ret < 0)
++              goto err;
++
++      wait_for_completion(&socket->thread_done);
++      BUG_ON(!socket->thread);
++      pcmcia_parse_events(socket, SS_DETECT);
+       return 0;
++
++ err:
++      down_write(&pcmcia_socket_list_rwsem);
++      list_del(&socket->socket_list);
++      up_write(&pcmcia_socket_list_rwsem);
++      return ret;
+ } /* pcmcia_register_socket */
+ EXPORT_SYMBOL(pcmcia_register_socket);
+@@ -410,10 +380,13 @@
+       DEBUG(0, "cs: pcmcia_unregister_socket(0x%p)\n", socket->ops);
+-      init_completion(&socket->socket_released);
+-
+-      /* remove from the device core */
+-      class_device_unregister(&socket->dev);
++      if (socket->thread) {
++              init_completion(&socket->thread_done);
++              socket->thread = NULL;
++              wake_up(&socket->thread_wait);
++              wait_for_completion(&socket->thread_done);
++      }
++      release_cis_mem(socket);
+       /* remove from our own list */
+       down_write(&pcmcia_socket_list_rwsem);
+@@ -657,7 +630,7 @@
+               pcmcia_error(skt, "unsupported voltage key.\n");
+               return CS_BAD_TYPE;
+       }
+-      skt->socket.flags = SS_DEBOUNCED;
++      skt->socket.flags = 0;
+       skt->ops->set_socket(skt, &skt->socket);
+       /*
+@@ -690,7 +663,6 @@
+               }
+ #endif
+               send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+-              skt->socket.flags &= ~SS_DEBOUNCED;
+       } else {
+               socket_shutdown(skt);
+               cs_socket_put(skt);
+@@ -739,7 +711,6 @@
+               } else {
+                       send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
+               }
+-              skt->socket.flags &= ~SS_DEBOUNCED;
+       } else {
+               socket_shutdown(skt);
+               cs_socket_put(skt);
+@@ -791,11 +762,22 @@
+ {
+       struct pcmcia_socket *skt = __skt;
+       DECLARE_WAITQUEUE(wait, current);
++      int ret;
+       daemonize("pccardd");
+       skt->thread = current;
+       complete(&skt->thread_done);
++      skt->socket = dead_socket;
++      skt->ops->init(skt);
++
++      /* register with the device core */
++      ret = class_device_register(&skt->dev);
++      if (ret) {
++              printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
++                      skt);
++      }
++
+       add_wait_queue(&skt->thread_wait, &wait);
+       for (;;) {
+               unsigned long flags;
+@@ -831,6 +813,9 @@
+       }
+       remove_wait_queue(&skt->thread_wait, &wait);
++      /* remove from the device core */
++      class_device_unregister(&skt->dev);
++
+       complete_and_exit(&skt->thread_done, 0);
+ }
+@@ -2509,12 +2494,6 @@
+ };
+ EXPORT_SYMBOL(pcmcia_socket_class);
+-static struct class_interface pcmcia_socket = {
+-      .class = &pcmcia_socket_class,
+-      .add = &pcmcia_add_socket,
+-      .remove = &pcmcia_remove_socket,
+-};
+-
+ static int __init init_pcmcia_cs(void)
+ {
+@@ -2522,7 +2501,6 @@
+     printk(KERN_INFO "  %s\n", options);
+     DEBUG(0, "%s\n", version);
+     class_register(&pcmcia_socket_class);
+-    class_interface_register(&pcmcia_socket);
+     return 0;
+ }
+@@ -2531,7 +2509,6 @@
+ {
+     printk(KERN_INFO "unloading Kernel Card Services\n");
+     release_resource_db();
+-    class_interface_unregister(&pcmcia_socket);
+     class_unregister(&pcmcia_socket_class);
+ }
+Index: linux-2.6.0-test5/drivers/pcmcia/cs_internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/cs_internal.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/cs_internal.h     2003-09-27 11:38:29.150096896 +0800
+@@ -100,11 +100,8 @@
+ /* Flags in socket state */
+ #define SOCKET_PRESENT                0x0008
+ #define SOCKET_INUSE          0x0010
+-#define SOCKET_SHUTDOWN_PENDING       0x0020
+-#define SOCKET_RESET_PENDING  0x0040
+ #define SOCKET_SUSPEND                0x0080
+ #define SOCKET_WIN_REQ(i)     (0x0100<<(i))
+-#define SOCKET_IO_REQ(i)      (0x1000<<(i))
+ #define SOCKET_REGION_INFO    0x4000
+ #define SOCKET_CARDBUS                0x8000
+ #define SOCKET_CARDBUS_CONFIG 0x10000
+Index: linux-2.6.0-test5/drivers/pcmcia/hd64465_ss.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/hd64465_ss.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/hd64465_ss.c      2003-09-27 11:38:29.196089904 +0800
+@@ -867,19 +867,32 @@
+       local_irq_restore(flags);
+ }
++static int hd64465_suspend(struct device *dev, u32 state, u32 level)
++{
++      int ret = 0;
++      if (level == SUSPEND_SAVE_STATE)
++              ret = pcmcia_socket_dev_suspend(dev, state);
++      return ret;
++}
++
++static int hd64465_resume(struct device *dev, u32 level)
++{
++      int ret = 0;
++      if (level == RESUME_RESTORE_STATE)
++              ret = pcmcia_socket_dev_resume(dev);
++      return ret;
++}
++
+ static struct device_driver hd64465_driver = {
+       .name = "hd64465-pcmcia",
+       .bus = &platform_bus_type,
+-      .suspend = pcmcia_socket_dev_suspend,
+-      .resume = pcmcia_socket_dev_resume,
++      .suspend = hd64465_suspend,
++      .resume = hd64465_resume,
+ };
+ static struct platform_device hd64465_device = {
+       .name = "hd64465-pcmcia",
+       .id = 0,
+-      .dev = {
+-              .name = "hd64465-pcmcia",
+-      },
+ };
+ static int __init init_hs(void)
+Index: linux-2.6.0-test5/drivers/pcmcia/i82092.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/i82092.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/i82092.c  2003-09-27 11:38:29.215087016 +0800
+@@ -44,12 +44,12 @@
+ static int i82092aa_socket_suspend (struct pci_dev *dev, u32 state)
+ {
+-      return pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE);
++      return pcmcia_socket_dev_suspend(&dev->dev, state);
+ }
+ static int i82092aa_socket_resume (struct pci_dev *dev)
+ {
+-      return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
++      return pcmcia_socket_dev_resume(&dev->dev);
+ }
+ static struct pci_driver i82092aa_pci_drv = {
+@@ -92,7 +92,7 @@
+ static int socket_count;  /* shortcut */                                                                              
+-static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
++static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ {
+       unsigned char configbyte;
+       int i, ret;
+Index: linux-2.6.0-test5/drivers/pcmcia/i82365.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/i82365.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/i82365.c  2003-09-27 11:38:29.230084736 +0800
+@@ -1351,11 +1351,27 @@
+ /*====================================================================*/
++static int i82365_suspend(struct device *dev, u32 state, u32 level)
++{
++      int ret = 0;
++      if (level == SUSPEND_SAVE_STATE)
++              ret = pcmcia_socket_dev_suspend(dev, state);
++      return ret;
++}
++
++static int i82365_resume(struct device *dev, u32 level)
++{
++      int ret = 0;
++      if (level == RESUME_RESTORE_STATE)
++              ret = pcmcia_socket_dev_resume(dev);
++      return ret;
++}
++
+ static struct device_driver i82365_driver = {
+       .name = "i82365",
+       .bus = &platform_bus_type,
+-      .suspend = pcmcia_socket_dev_suspend,
+-      .resume = pcmcia_socket_dev_resume,
++      .suspend = i82365_suspend,
++      .resume = i82365_resume,
+ };
+ static struct platform_device i82365_device = {
+Index: linux-2.6.0-test5/drivers/pcmcia/ricoh.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/ricoh.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/ricoh.h   2003-09-27 11:38:29.241083064 +0800
+@@ -109,7 +109,7 @@
+ /* 16-bit IO and memory timing registers */
+ #define RL5C4XX_16BIT_IO_0            0x0088  /* 16 bit */
+-#define RL5C4XX_16BIT_MEM_0           0x0088  /* 16 bit */
++#define RL5C4XX_16BIT_MEM_0           0x008a  /* 16 bit */
+ #define  RL5C4XX_SETUP_MASK           0x0007
+ #define  RL5C4XX_SETUP_SHIFT          0
+ #define  RL5C4XX_CMD_MASK             0x01f0
+Index: linux-2.6.0-test5/drivers/pcmcia/rsrc_mgr.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/rsrc_mgr.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/rsrc_mgr.c        2003-09-27 11:38:29.295074856 +0800
+@@ -491,7 +491,7 @@
+ void validate_mem(struct pcmcia_socket *s)
+ {
+-    resource_map_t *m, *n;
++    resource_map_t *m, mm;
+     static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
+     static int hi = 0, lo = 0;
+     u_long b, i, ok = 0;
+@@ -510,18 +510,18 @@
+     }
+     if (lo++)
+       goto out;
+-    for (m = mem_db.next; m != &mem_db; m = n) {
+-      n = m->next;
++    for (m = mem_db.next; m != &mem_db; m = mm.next) {
++      mm = *m;
+       /* Only probe < 1 MB */
+-      if (m->base >= 0x100000) continue;
+-      if ((m->base | m->num) & 0xffff) {
+-          ok += do_mem_probe(m->base, m->num, s);
++      if (mm.base >= 0x100000) continue;
++      if ((mm.base | mm.num) & 0xffff) {
++          ok += do_mem_probe(mm.base, mm.num, s);
+           continue;
+       }
+       /* Special probe for 64K-aligned block */
+       for (i = 0; i < 4; i++) {
+           b = order[i] << 12;
+-          if ((b >= m->base) && (b+0x10000 <= m->base+m->num)) {
++          if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
+               if (ok >= mem_limit)
+                   sub_interval(&mem_db, b, 0x10000);
+               else
+@@ -537,14 +537,14 @@
+ void validate_mem(struct pcmcia_socket *s)
+ {
+-    resource_map_t *m, *n;
++    resource_map_t *m, mm;
+     static int done = 0;
+     
+     if (probe_mem && done++ == 0) {
+       down(&rsrc_sem);
+-      for (m = mem_db.next; m != &mem_db; m = n) {
+-          n = m->next;
+-          if (do_mem_probe(m->base, m->num, s))
++      for (m = mem_db.next; m != &mem_db; m = mm.next) {
++          mm = *m;
++          if (do_mem_probe(mm.base, mm.num, s))
+               break;
+       }
+       up(&rsrc_sem);
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1100_assabet.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1100_assabet.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1100_assabet.c  2003-09-27 11:38:29.318071360 +0800
+@@ -4,7 +4,6 @@
+  * PCMCIA implementation routines for Assabet
+  *
+  */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1100_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1100_generic.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1100_generic.c  2003-09-27 11:38:29.337068472 +0800
+@@ -100,13 +100,29 @@
+       return ret;
+ }
++static int sa11x0_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
++{
++      int ret = 0;
++      if (level == SUSPEND_SAVE_STATE)
++              ret = pcmcia_socket_dev_suspend(dev, state);
++      return ret;
++}
++
++static int sa11x0_drv_pcmcia_resume(struct device *dev, u32 level)
++{
++      int ret = 0;
++      if (level == RESUME_RESTORE_STATE)
++              ret = pcmcia_socket_dev_resume(dev);
++      return ret;
++}
++
+ static struct device_driver sa11x0_pcmcia_driver = {
+       .probe          = sa11x0_drv_pcmcia_probe,
+       .remove         = sa11xx_drv_pcmcia_remove,
+       .name           = "sa11x0-pcmcia",
+       .bus            = &platform_bus_type,
+-      .suspend        = pcmcia_socket_dev_suspend,
+-      .resume         = pcmcia_socket_dev_resume,
++      .suspend        = sa11x0_drv_pcmcia_suspend,
++      .resume         = sa11x0_drv_pcmcia_resume,
+ };
+ /* sa11x0_pcmcia_init()
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1100_simpad.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1100_simpad.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1100_simpad.c   2003-09-27 11:38:29.382061632 +0800
+@@ -13,6 +13,7 @@
+ #include <asm/hardware.h>
+ #include <asm/mach-types.h>
+ #include <asm/irq.h>
++#include <asm/arch/simpad.h>
+ #include "sa1100_generic.h"
+  
+ extern long get_cs3_shadow(void);
+@@ -25,9 +26,6 @@
+ static int simpad_pcmcia_hw_init(struct sa1100_pcmcia_socket *skt)
+ {
+-      set_cs3_bit(PCMCIA_RESET);
+-      clear_cs3_bit(PCMCIA_BUFF_DIS);
+-      clear_cs3_bit(PCMCIA_RESET);
+       clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+@@ -71,7 +69,7 @@
+ simpad_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
+                              const socket_state_t *state)
+ {
+-      unsigned long value, flags;
++      unsigned long flags;
+       local_irq_save(flags);
+@@ -82,8 +80,8 @@
+               break;
+       case 33:  
+-              clear_cs3_bit(VCC_3V_EN|EN0);
+-              set_cs3_bit(VCC_5V_EN|EN1);
++              clear_cs3_bit(VCC_3V_EN|EN1);
++              set_cs3_bit(VCC_5V_EN|EN0);
+               break;
+       case 50:
+@@ -99,7 +97,7 @@
+               return -1;
+       }
+-      /* Silently ignore Vpp, output enable, speaker enable. */
++
+       local_irq_restore(flags);
+       return 0;
+@@ -113,6 +111,7 @@
+ static void simpad_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
+ {
+       sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
++      set_cs3_bit(PCMCIA_RESET);
+ }
+ static struct pcmcia_low_level simpad_pcmcia_ops = { 
+Index: linux-2.6.0-test5/drivers/pcmcia/sa1111_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa1111_generic.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa1111_generic.c  2003-09-27 11:38:29.438053120 +0800
+@@ -5,6 +5,7 @@
+  * basically means we handle everything except controlling the
+  * power.  Power is machine specific...
+  */
++#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/ioport.h>
+@@ -171,12 +172,12 @@
+ static int pcmcia_suspend(struct sa1111_dev *dev, u32 state)
+ {
+-      return pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE);
++      return pcmcia_socket_dev_suspend(&dev->dev, state);
+ }
+ static int pcmcia_resume(struct sa1111_dev *dev)
+ {
+-      return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
++      return pcmcia_socket_dev_resume(&dev->dev);
+ }
+ static struct sa1111_driver pcmcia_driver = {
+Index: linux-2.6.0-test5/drivers/pcmcia/sa11xx_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/sa11xx_core.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/sa11xx_core.c     2003-09-27 11:38:29.468048560 +0800
+@@ -556,7 +556,6 @@
+       { SS_DMA_MODE,          "SS_DMA_MODE"   },
+       { SS_SPKR_ENA,          "SS_SPKR_ENA"   },
+       { SS_OUTPUT_ENA,        "SS_OUTPUT_ENA" },
+-      { SS_DEBOUNCED,         "SS_DEBOUNCED"  },
+ };
+ static void
+Index: linux-2.6.0-test5/drivers/pcmcia/tcic.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/tcic.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/tcic.c    2003-09-27 11:38:29.520040656 +0800
+@@ -362,11 +362,27 @@
+ /*====================================================================*/
++static int tcic_drv_suspend(struct device *dev, u32 state, u32 level)
++{
++      int ret = 0;
++      if (level == SUSPEND_SAVE_STATE)
++              ret = pcmcia_socket_dev_suspend(dev, state);
++      return ret;
++}
++
++static int tcic_drv_resume(struct device *dev, u32 level)
++{
++      int ret = 0;
++      if (level == RESUME_RESTORE_STATE)
++              ret = pcmcia_socket_dev_resume(dev);
++      return ret;
++}
++
+ static struct device_driver tcic_driver = {
+       .name = "tcic-pcmcia",
+       .bus = &platform_bus_type,
+-      .suspend = pcmcia_socket_dev_suspend,
+-      .resume = pcmcia_socket_dev_resume,
++      .suspend = tcic_drv_suspend,
++      .resume = tcic_drv_resume,
+ };
+ static struct platform_device tcic_device = {
+Index: linux-2.6.0-test5/drivers/pcmcia/yenta_socket.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pcmcia/yenta_socket.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pcmcia/yenta_socket.c    2003-09-27 11:38:29.564033968 +0800
+@@ -248,10 +248,6 @@
+       struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+       u16 bridge;
+-      if (state->flags & SS_DEBOUNCED) {
+-              /* The insertion debounce period has ended.  Clear any pending insertion events */
+-              state->flags &= ~SS_DEBOUNCED;          /* SS_DEBOUNCED is oneshot */
+-      }
+       yenta_set_power(socket, state);
+       socket->io_irq = state->io_irq;
+       bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
+@@ -937,7 +933,7 @@
+       struct yenta_socket *socket = pci_get_drvdata(dev);
+       int ret;
+-      ret = pcmcia_socket_dev_suspend(&dev->dev, state, SUSPEND_SAVE_STATE);
++      ret = pcmcia_socket_dev_suspend(&dev->dev, state);
+       if (socket) {
+               if (socket->type && socket->type->save_state)
+@@ -969,7 +965,7 @@
+                       socket->type->restore_state(socket);
+       }
+-      return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
++      return pcmcia_socket_dev_resume(&dev->dev);
+ }
+Index: linux-2.6.0-test5/drivers/pnp/card.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/card.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/card.c       2003-09-27 11:38:29.600028496 +0800
+@@ -62,8 +62,14 @@
+               if (drv->probe) {
+                       if (drv->probe(clink, id)>=0)
+                               return 1;
+-                      else
++                      else {
++                              struct pnp_dev * dev;
++                              card_for_each_dev(card, dev) {
++                                      if (dev->card_link == clink)
++                                              pnp_release_card_device(dev);
++                              }
+                               kfree(clink);
++                      }
+               } else
+                       return 1;
+       }
+Index: linux-2.6.0-test5/drivers/pnp/isapnp/compat.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/isapnp/compat.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/isapnp/compat.c      2003-09-27 11:38:29.654020288 +0800
+@@ -9,7 +9,6 @@
+ /* TODO: see if more isapnp functions are needed here */
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/isapnp.h>
+ #include <linux/string.h>
+Index: linux-2.6.0-test5/drivers/pnp/isapnp/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/isapnp/core.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/isapnp/core.c        2003-09-27 11:38:29.702012992 +0800
+@@ -35,7 +35,6 @@
+  */
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -65,7 +64,6 @@
+ MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
+ MODULE_PARM(isapnp_reset, "i");
+ MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
+-MODULE_PARM(isapnp_allow_dma0, "i");
+ MODULE_PARM(isapnp_verbose, "i");
+ MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
+ MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/pnp/isapnp/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/isapnp/proc.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/isapnp/proc.c        2003-09-27 11:38:29.754005088 +0800
+@@ -20,7 +20,6 @@
+  */
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/isapnp.h>
+ #include <linux/proc_fs.h>
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/bioscalls.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/bioscalls.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/bioscalls.c  2003-09-27 11:38:29.792999160 +0800
+@@ -23,41 +23,7 @@
+ #include <asm/system.h>
+ #include <asm/byteorder.h>
+-
+-/* PnP BIOS signature: "$PnP" */
+-#define PNP_SIGNATURE   (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
+-
+-#pragma pack(1)
+-union pnp_bios_expansion_header {
+-      struct {
+-              u32 signature;    /* "$PnP" */
+-              u8 version;       /* in BCD */
+-              u8 length;        /* length in bytes, currently 21h */
+-              u16 control;      /* system capabilities */
+-              u8 checksum;      /* all bytes must add up to 0 */
+-
+-              u32 eventflag;    /* phys. address of the event flag */
+-              u16 rmoffset;     /* real mode entry point */
+-              u16 rmcseg;
+-              u16 pm16offset;   /* 16 bit protected mode entry */
+-              u32 pm16cseg;
+-              u32 deviceID;     /* EISA encoded system ID or 0 */
+-              u16 rmdseg;       /* real mode data segment */
+-              u32 pm16dseg;     /* 16 bit pm data segment base */
+-      } fields;
+-      char chars[0x21];         /* To calculate the checksum */
+-};
+-#pragma pack()
+-
+-static union pnp_bios_expansion_header * pnp_bios_hdr = NULL;
+-
+-/*
+- * Call this only after init time
+- */
+-static int pnp_bios_present(void)
+-{
+-      return (pnp_bios_hdr != NULL);
+-}
++#include "pnpbios.h"
+ static struct {
+       u16     offset;
+@@ -557,10 +523,10 @@
+ /*
+- * Probing and Initialization
++ * Initialization
+  */
+-static void pnpbios_prepare_bios_calls(union pnp_bios_expansion_header *header)
++void pnpbios_calls_init(union pnp_bios_install_struct *header)
+ {
+       int i;
+       spin_lock_init(&pnp_bios_lock);
+@@ -576,52 +542,3 @@
+               Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024);
+       }
+ }
+-
+-int pnpbios_probe_installation(void)
+-{
+-      union pnp_bios_expansion_header *check;
+-      u8 sum;
+-      int length, i;
+-
+-      printk(KERN_INFO "PnPBIOS: Scanning system for PnP BIOS support...\n");
+-
+-      /*
+-       * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
+-       * structure and, if one is found, sets up the selectors and
+-       * entry points
+-       */
+-      for (check = (union pnp_bios_expansion_header *) __va(0xf0000);
+-           check < (union pnp_bios_expansion_header *) __va(0xffff0);
+-           ((void *) (check)) += 16) {
+-              if (check->fields.signature != PNP_SIGNATURE)
+-                      continue;
+-              printk(KERN_INFO "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n", check);
+-              length = check->fields.length;
+-              if (!length) {
+-                      printk(KERN_ERR "PnPBIOS: installation structure is invalid, skipping\n");
+-                      continue;
+-              }
+-              for (sum = 0, i = 0; i < length; i++)
+-                      sum += check->chars[i];
+-              if (sum) {
+-                      printk(KERN_ERR "PnPBIOS: installation structure is corrupted, skipping\n");
+-                      continue;
+-              }
+-              if (check->fields.version < 0x10) {
+-                      printk(KERN_WARNING "PnPBIOS: PnP BIOS version %d.%d is not supported\n",
+-                             check->fields.version >> 4,
+-                             check->fields.version & 15);
+-                      continue;
+-              }
+-              printk(KERN_INFO "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n",
+-                       check->fields.version >> 4, check->fields.version & 15,
+-                     check->fields.pm16cseg, check->fields.pm16offset,
+-                     check->fields.pm16dseg);
+-              pnp_bios_hdr = check;
+-              pnpbios_prepare_bios_calls(check);
+-              return 1;
+-      }
+-
+-      printk(KERN_INFO "PnPBIOS: PnP BIOS support was not detected.\n");
+-      return 0;
+-}
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/core.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/core.c       2003-09-27 11:38:29.835992624 +0800
+@@ -74,6 +74,13 @@
+  *
+  */
++static union pnp_bios_install_struct * pnp_bios_install = NULL;
++
++int pnp_bios_present(void)
++{
++      return (pnp_bios_install != NULL);
++}
++
+ struct pnp_dev_node_info node_info;
+ void *pnpbios_kmalloc(size_t size, int f)
+@@ -410,7 +417,56 @@
+ __setup("pnpbios=", pnpbios_setup);
+ #endif
+-subsys_initcall(pnpbios_init);
++/* PnP BIOS signature: "$PnP" */
++#define PNP_SIGNATURE   (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
++
++int __init pnpbios_probe_system(void)
++{
++      union pnp_bios_install_struct *check;
++      u8 sum;
++      int length, i;
++
++      printk(KERN_INFO "PnPBIOS: Scanning system for PnP BIOS support...\n");
++
++      /*
++       * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
++       * structure and, if one is found, sets up the selectors and
++       * entry points
++       */
++      for (check = (union pnp_bios_install_struct *) __va(0xf0000);
++           check < (union pnp_bios_install_struct *) __va(0xffff0);
++           ((void *) (check)) += 16) {
++              if (check->fields.signature != PNP_SIGNATURE)
++                      continue;
++              printk(KERN_INFO "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n", check);
++              length = check->fields.length;
++              if (!length) {
++                      printk(KERN_ERR "PnPBIOS: installation structure is invalid, skipping\n");
++                      continue;
++              }
++              for (sum = 0, i = 0; i < length; i++)
++                      sum += check->chars[i];
++              if (sum) {
++                      printk(KERN_ERR "PnPBIOS: installation structure is corrupted, skipping\n");
++                      continue;
++              }
++              if (check->fields.version < 0x10) {
++                      printk(KERN_WARNING "PnPBIOS: PnP BIOS version %d.%d is not supported\n",
++                             check->fields.version >> 4,
++                             check->fields.version & 15);
++                      continue;
++              }
++              printk(KERN_INFO "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n",
++                       check->fields.version >> 4, check->fields.version & 15,
++                     check->fields.pm16cseg, check->fields.pm16offset,
++                     check->fields.pm16dseg);
++              pnp_bios_install = check;
++              return 1;
++      }
++
++      printk(KERN_INFO "PnPBIOS: PnP BIOS support was not detected.\n");
++      return 0;
++}
+ int __init pnpbios_init(void)
+ {
+@@ -421,24 +477,30 @@
+       }
+       /* scan the system for pnpbios support */
+-      if (!pnpbios_probe_installation())
++      if (!pnpbios_probe_system())
+               return -ENODEV;
++      /* make preparations for bios calls */
++      pnpbios_calls_init(pnp_bios_install);
++
+       /* read the node info */
+-      if (pnp_bios_dev_node_info(&node_info)) {
++      ret = pnp_bios_dev_node_info(&node_info);
++      if (ret) {
+               printk(KERN_ERR "PnPBIOS: Unable to get node info.  Aborting.\n");
+-              return -EIO;
++              return ret;
+       }
+       /* register with the pnp layer */
+-      pnp_register_protocol(&pnpbios_protocol);
++      ret = pnp_register_protocol(&pnpbios_protocol);
++      if (ret) {
++              printk(KERN_ERR "PnPBIOS: Unable to register driver.  Aborting.\n");
++              return ret;
++      }
+-#ifdef CONFIG_PROC_FS
+       /* start the proc interface */
+       ret = pnpbios_proc_init();
+       if (ret)
+-              return ret;
+-#endif
++              printk(KERN_ERR "PnPBIOS: Failed to create proc interface.\n");
+       /* scan for pnpbios devices */
+       build_devlist();
+@@ -446,6 +508,8 @@
+       return 0;
+ }
++subsys_initcall(pnpbios_init);
++
+ static int __init pnpbios_thread_init(void)
+ {
+ #ifdef CONFIG_HOTPLUG
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/pnpbios.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/pnpbios.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/pnpbios.h    2003-09-27 11:38:29.888984568 +0800
+@@ -1,11 +1,47 @@
+ /*
+- * pnpbios.h - contains definitions for functions used only locally.
++ * pnpbios.h - contains local definitions
+  */
++#pragma pack(1)
++union pnp_bios_install_struct {
++      struct {
++              u32 signature;    /* "$PnP" */
++              u8 version;       /* in BCD */
++              u8 length;        /* length in bytes, currently 21h */
++              u16 control;      /* system capabilities */
++              u8 checksum;      /* all bytes must add up to 0 */
++
++              u32 eventflag;    /* phys. address of the event flag */
++              u16 rmoffset;     /* real mode entry point */
++              u16 rmcseg;
++              u16 pm16offset;   /* 16 bit protected mode entry */
++              u32 pm16cseg;
++              u32 deviceID;     /* EISA encoded system ID or 0 */
++              u16 rmdseg;       /* real mode data segment */
++              u32 pm16dseg;     /* 16 bit pm data segment base */
++      } fields;
++      char chars[0x21];         /* To calculate the checksum */
++};
++#pragma pack()
++
++extern int pnp_bios_present(void);
++extern int  pnpbios_dont_use_current_config;
++extern void *pnpbios_kmalloc(size_t size, int f);
++
+ extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node);
+ extern int pnpbios_read_resources_from_node(struct pnp_resource_table *res, struct pnp_bios_node * node);
+ extern int pnpbios_write_resources_to_node(struct pnp_resource_table *res, struct pnp_bios_node * node);
+ extern void pnpid32_to_pnpid(u32 id, char *str);
+ extern void pnpbios_print_status(const char * module, u16 status);
+-extern int pnpbios_probe_installation(void);
++extern void pnpbios_calls_init(union pnp_bios_install_struct * header);
++
++#ifdef CONFIG_PROC_FS
++extern int pnpbios_interface_attach_device(struct pnp_bios_node * node);
++extern int pnpbios_proc_init (void);
++extern void pnpbios_proc_exit (void);
++#else
++static inline int pnpbios_interface_attach_device(struct pnp_bios_node * node) { return 0; }
++static inline int pnpbios_proc_init (void) { return 0; }
++static inline void pnpbios_proc_exit (void) { ; }
++#endif /* CONFIG_PROC */
+Index: linux-2.6.0-test5/drivers/pnp/pnpbios/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/pnpbios/proc.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/pnpbios/proc.c       2003-09-27 11:38:29.927978640 +0800
+@@ -31,6 +31,8 @@
+ #include <asm/uaccess.h>
++#include "pnpbios.h"
++
+ static struct proc_dir_entry *proc_pnp = NULL;
+ static struct proc_dir_entry *proc_pnp_boot = NULL;
+@@ -213,6 +215,9 @@
+       struct proc_dir_entry *ent;
+       sprintf(name, "%02x", node->handle);
++
++      if (!proc_pnp)
++              return -EIO;
+       if ( !pnpbios_dont_use_current_config ) {
+               ent = create_proc_entry(name, 0, proc_pnp);
+               if (ent) {
+@@ -221,6 +226,9 @@
+                       ent->data = (void *)(long)(node->handle);
+               }
+       }
++
++      if (!proc_pnp_boot)
++              return -EIO;
+       ent = create_proc_entry(name, 0, proc_pnp_boot);
+       if (ent) {
+               ent->read_proc = proc_read_node;
+@@ -228,6 +236,7 @@
+               ent->data = (void *)(long)(node->handle+0x100);
+               return 0;
+       }
++
+       return -EIO;
+ }
+@@ -257,8 +266,9 @@
+ {
+       int i;
+       char name[3];
+-      
+-      if (!proc_pnp) return;
++
++      if (!proc_pnp)
++              return;
+       for (i=0; i<0xff; i++) {
+               sprintf(name, "%02x", i);
+Index: linux-2.6.0-test5/drivers/pnp/quirks.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/quirks.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/quirks.c     2003-09-27 11:38:29.987969520 +0800
+@@ -111,28 +111,6 @@
+       return;
+ }
+-extern int pnp_allow_dma0;
+-static void quirk_opl3sax_resources(struct pnp_dev *dev)
+-{
+-      /* This really isn't a device quirk but isapnp core code
+-       * doesn't allow a DMA channel of 0, afflicted card is an
+-       * OPL3Sax where x=4.
+-       */
+-      struct pnp_option *res;
+-      int max;
+-      res = dev->dependent;
+-      max = 0;
+-      for (; res; res = res->next) {
+-              if (res->dma->map > max)
+-                      max = res->dma->map;
+-      }
+-      if (max == 1 && pnp_allow_dma0 == -1) {
+-              printk(KERN_INFO "pnp: opl3sa4 quirk: Allowing dma 0.\n");
+-              pnp_allow_dma0 = 1;
+-      }
+-      return;
+-}
+-
+ /*
+  *  PnP Quirks
+  *  Cards or devices that need some tweaking due to incomplete resource info
+@@ -153,7 +131,6 @@
+       { "CTL0043", quirk_sb16audio_resources },
+       { "CTL0044", quirk_sb16audio_resources },
+       { "CTL0045", quirk_sb16audio_resources },
+-      { "YMH0021", quirk_opl3sax_resources },
+       { "" }
+ };
+@@ -170,4 +147,3 @@
+               i++;
+       }
+ }
+-
+Index: linux-2.6.0-test5/drivers/pnp/resource.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/pnp/resource.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/pnp/resource.c   2003-09-27 11:38:30.050959944 +0800
+@@ -21,8 +21,6 @@
+ #include <linux/pnp.h>
+ #include "base.h"
+-int pnp_allow_dma0 = -1;                      /* allow dma 0 during auto activation:
+-                                               * -1=off (:default), 0=off (set by user), 1=on */
+ int pnp_skip_pci_scan;                                /* skip PCI resource scanning */
+ int pnp_reserve_irq[16] = { [0 ... 15] = -1 };        /* reserve (don't use) some IRQ */
+ int pnp_reserve_dma[8] = { [0 ... 7] = -1 };  /* reserve (don't use) some DMA */
+@@ -426,7 +424,7 @@
+ int pnp_check_dma(struct pnp_dev * dev, int idx)
+ {
+-      int tmp, mindma = 1;
++      int tmp;
+       struct pnp_dev *tdev;
+       unsigned long * dma = &dev->res.dma_resource[idx].start;
+@@ -435,9 +433,7 @@
+               return 1;
+       /* check if the resource is valid */
+-      if (pnp_allow_dma0 == 1)
+-              mindma = 0;
+-      if (*dma < mindma || *dma == 4 || *dma > 7)
++      if (*dma < 0 || *dma == 4 || *dma > 7)
+               return 0;
+       /* check if the resource is reserved */
+@@ -488,16 +484,6 @@
+ EXPORT_SYMBOL(pnp_register_mem_resource);
+-/* format is: allowdma0 */
+-
+-static int __init pnp_allowdma0(char *str)
+-{
+-        pnp_allow_dma0 = 1;
+-      return 1;
+-}
+-
+-__setup("allowdma0", pnp_allowdma0);
+-
+ /* format is: pnp_reserve_irq=irq1[,irq2] .... */
+ static int __init pnp_setup_reserve_irq(char *str)
+Index: linux-2.6.0-test5/drivers/s390/block/dasd_int.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/s390/block/dasd_int.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/s390/block/dasd_int.h    2003-09-27 11:38:30.068957208 +0800
+@@ -14,7 +14,8 @@
+ #ifdef __KERNEL__
+-#define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS))
++/* we keep old device allocation scheme; IOW, minors are still in 0..255 */
++#define DASD_PER_MAJOR ( 1U<<(8-DASD_PARTN_BITS))
+ #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
+ /*
+Index: linux-2.6.0-test5/drivers/sbus/char/bpp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/sbus/char/bpp.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/sbus/char/bpp.c  2003-09-27 11:38:30.124948696 +0800
+@@ -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/sched.h>
+Index: linux-2.6.0-test5/drivers/sbus/char/cpwatchdog.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/sbus/char/cpwatchdog.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/sbus/char/cpwatchdog.c   2003-09-27 11:38:30.134947176 +0800
+@@ -17,7 +17,6 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/fs.h>
+ #include <linux/errno.h>
+ #include <linux/major.h>
+Index: linux-2.6.0-test5/drivers/sbus/char/display7seg.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/sbus/char/display7seg.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/sbus/char/display7seg.c  2003-09-27 11:38:30.180940184 +0800
+@@ -9,7 +9,6 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/fs.h>
+ #include <linux/errno.h>
+ #include <linux/major.h>
+Index: linux-2.6.0-test5/drivers/scsi/aic7xxx/aicasm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/aic7xxx/aicasm/Makefile        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/aic7xxx/aicasm/Makefile     2003-09-27 11:38:30.225933344 +0800
+@@ -49,14 +49,18 @@
+ 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
+Index: linux-2.6.0-test5/drivers/scsi/aic7xxx/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/aic7xxx/Makefile       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/aic7xxx/Makefile    2003-09-27 11:38:31.142793960 +0800
+@@ -58,7 +58,9 @@
+       -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 @@
+       -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
+Index: linux-2.6.0-test5/drivers/scsi/aic7xxx_old/aic7xxx_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/aic7xxx_old/aic7xxx_proc.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/aic7xxx_old/aic7xxx_proc.c  2003-09-27 11:38:31.227781040 +0800
+@@ -92,7 +92,7 @@
+   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)
+Index: linux-2.6.0-test5/drivers/scsi/gdth.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/gdth.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/gdth.c      2003-09-27 11:38:31.324766296 +0800
+@@ -2048,7 +2048,7 @@
+         for (j = 0; j < 12; ++j) 
+             rtc[j] = CMOS_READ(j);
+     } while (rtc[0] != CMOS_READ(0));
+-    spin_lock_irqrestore(&rtc_lock, flags);
++    spin_unlock_irqrestore(&rtc_lock, flags);
+     TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0],
+             *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]));
+     /* 3. send to controller firmware */
+Index: linux-2.6.0-test5/drivers/scsi/imm.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/imm.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/imm.h       2003-09-27 11:38:31.375758544 +0800
+@@ -100,8 +100,9 @@
+       [IMM_NIBBLE]     = "SPP",
+       [IMM_PS2]        = "PS/2",
+       [IMM_EPP_8]      = "EPP 8 bit",
+-#ifdef CONFIG_SCSI_IZIP_EPP16
+       [IMM_EPP_16]     = "EPP 16 bit",
++#ifdef CONFIG_SCSI_IZIP_EPP16
++      [IMM_EPP_32]     = "EPP 16 bit",
+ #else
+       [IMM_EPP_32]     = "EPP 32 bit",
+ #endif
+Index: linux-2.6.0-test5/drivers/scsi/NCR5380.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/NCR5380.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/NCR5380.c   2003-09-27 11:38:31.519736656 +0800
+@@ -372,7 +372,7 @@
+       {
+               r = NCR5380_read(reg);
+               if((r & bit) == val)
+-                      return r;
++                      return 0;
+               cpu_relax();
+       }
+       
+@@ -381,7 +381,7 @@
+       {
+               r = NCR5380_read(reg);
+               if((r & bit) == val)
+-                      return r; 
++                      return 0;
+               if(!in_interrupt())
+                       yield();
+               else
+Index: linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_glue.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/sym53c8xx_2/sym_glue.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_glue.c      2003-09-27 11:38:31.628720088 +0800
+@@ -2287,8 +2287,7 @@
+       }
+       if (chip->features & FE_WRIE) {
+-              if (pci_set_mwi(pdev))
+-                      return -1;
++              pci_set_mwi(pdev);
+       }
+       /*
+Index: linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_hipd.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/scsi/sym53c8xx_2/sym_hipd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/scsi/sym53c8xx_2/sym_hipd.c      2003-09-27 11:38:31.747702000 +0800
+@@ -831,7 +831,8 @@
+       }
+ #endif
+-      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;
+Index: linux-2.6.0-test5/drivers/serial/8250.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/8250.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/8250.c    2003-09-27 11:38:31.841687712 +0800
+@@ -122,6 +122,7 @@
+       struct uart_port        port;
+       struct timer_list       timer;          /* "no irq" timer */
+       struct list_head        list;           /* ports on this IRQ */
++      unsigned int            capabilities;   /* port capabilities */
+       unsigned short          rev;
+       unsigned char           acr;
+       unsigned char           ier;
+@@ -683,6 +684,7 @@
+       serial_outp(up, UART_LCR, save_lcr);
+       up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
++      up->capabilities = uart_config[up->port.type].flags;
+       if (up->port.type == PORT_UNKNOWN)
+               goto out;
+@@ -823,7 +825,7 @@
+               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;
+@@ -1184,12 +1186,23 @@
+       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) {
+               /* Wake up and initialize UART */
+               up->acr = 0;
+@@ -1215,7 +1228,7 @@
+        * Clear the FIFO buffers and disable them.
+        * (they will be reeanbled in set_termios())
+        */
+-      if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) {
++      if (up->capabilities & UART_CLEAR_FIFO) {
+               serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+               serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+                               UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+@@ -1428,7 +1441,7 @@
+           up->rev == 0x5201)
+               quot ++;
+-      if (uart_config[up->port.type].flags & UART_USE_FIFO) {
++      if (up->capabilities & UART_USE_FIFO) {
+               if (baud < 2400)
+                       fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+ #ifdef CONFIG_SERIAL_8250_RSA
+@@ -1489,13 +1502,13 @@
+       serial_out(up, UART_IER, up->ier);
+-      if (uart_config[up->port.type].flags & UART_STARTECH) {
++      if (up->capabilities & UART_STARTECH) {
+               serial_outp(up, UART_LCR, 0xBF);
+               serial_outp(up, UART_EFR,
+                           termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0);
+       }
+-      if (uart_config[up->port.type].flags & UART_NATSEMI) {
++      if (up->capabilities & UART_NATSEMI) {
+               /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
+               serial_outp(up, UART_LCR, 0xe0);
+       } else {
+@@ -1524,7 +1537,7 @@
+       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       if (state) {
+               /* sleep */
+-              if (uart_config[up->port.type].flags & UART_STARTECH) {
++              if (up->capabilities & UART_STARTECH) {
+                       /* Arrange to enter sleep mode */
+                       serial_outp(up, UART_LCR, 0xBF);
+                       serial_outp(up, UART_EFR, UART_EFR_ECB);
+@@ -1543,7 +1556,7 @@
+                       up->pm(port, state, oldstate);
+       } else {
+               /* wake */
+-              if (uart_config[up->port.type].flags & UART_STARTECH) {
++              if (up->capabilities & UART_STARTECH) {
+                       /* Wake up UART */
+                       serial_outp(up, UART_LCR, 0xBF);
+                       serial_outp(up, UART_EFR, UART_EFR_ECB);
+@@ -1853,6 +1866,10 @@
+       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,9 +2118,9 @@
+  *
+  *    Suspend one serial port.
+  */
+-void serial8250_suspend_port(int line, u32 level)
++void serial8250_suspend_port(int line)
+ {
+-      uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port, level);
++      uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
+ }
+ /**
+@@ -2112,10 +2129,35 @@
+  *
+  *    Resume one serial port.
+  */
+-void serial8250_resume_port(int line, u32 level)
++void serial8250_resume_port(int line)
+ {
+-      uart_resume_port(&serial8250_reg, &serial8250_ports[line].port, level);
++      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)
+ {
+Index: linux-2.6.0-test5/drivers/serial/8250.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/8250.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/8250.h    2003-09-27 11:38:31.879681936 +0800
+@@ -27,8 +27,8 @@
+ int serial8250_register_probe(struct serial8250_probe *probe);
+ void serial8250_unregister_probe(struct serial8250_probe *probe);
+ void serial8250_get_irq_map(unsigned int *map);
+-void serial8250_suspend_port(int line, u32 level);
+-void serial8250_resume_port(int line, u32 level);
++void serial8250_suspend_port(int line);
++void serial8250_resume_port(int line);
+ struct old_serial_port {
+       unsigned int uart;
+Index: linux-2.6.0-test5/drivers/serial/8250_pci.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/8250_pci.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/8250_pci.c        2003-09-27 11:38:31.968668408 +0800
+@@ -1600,19 +1600,6 @@
+       }
+ }
+-static int pciserial_save_state_one(struct pci_dev *dev, u32 state)
+-{
+-      struct serial_private *priv = pci_get_drvdata(dev);
+-
+-      if (priv) {
+-              int i;
+-
+-              for (i = 0; i < priv->nr; i++)
+-                      serial8250_suspend_port(priv->line[i], SUSPEND_SAVE_STATE);
+-      }
+-      return 0;
+-}
+-
+ static int pciserial_suspend_one(struct pci_dev *dev, u32 state)
+ {
+       struct serial_private *priv = pci_get_drvdata(dev);
+@@ -1621,7 +1608,7 @@
+               int i;
+               for (i = 0; i < priv->nr; i++)
+-                      serial8250_suspend_port(priv->line[i], SUSPEND_POWER_DOWN);
++                      serial8250_suspend_port(priv->line[i]);
+       }
+       return 0;
+ }
+@@ -1639,10 +1626,8 @@
+               if (priv->quirk->init)
+                       priv->quirk->init(dev);
+-              for (i = 0; i < priv->nr; i++) {
+-                      serial8250_resume_port(priv->line[i], RESUME_POWER_ON);
+-                      serial8250_resume_port(priv->line[i], RESUME_RESTORE_STATE);
+-              }
++              for (i = 0; i < priv->nr; i++)
++                      serial8250_resume_port(priv->line[i]);
+       }
+       return 0;
+ }
+@@ -2040,7 +2025,6 @@
+       .name           = "serial",
+       .probe          = pciserial_init_one,
+       .remove         = __devexit_p(pciserial_remove_one),
+-      .save_state     = pciserial_save_state_one,
+       .suspend        = pciserial_suspend_one,
+       .resume         = pciserial_resume_one,
+       .id_table       = serial_pci_tbl,
+Index: linux-2.6.0-test5/drivers/serial/clps711x.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/clps711x.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/clps711x.c        2003-09-27 11:38:32.032658680 +0800
+@@ -104,7 +104,7 @@
+ {
+ }
+-static void clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
+ {
+       struct uart_port *port = dev_id;
+       struct tty_struct *tty = port->info->tty;
+@@ -139,7 +139,7 @@
+       }
+  out:
+       tty_flip_buffer_push(tty);
+-      return;
++      return IRQ_HANDLED;
+  handle_error:
+       if (ch & UARTDR_PARERR)
+@@ -180,7 +180,7 @@
+       goto error_return;
+ }
+-static void clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
+ {
+       struct uart_port *port = dev_id;
+       struct circ_buf *xmit = &port->info->xmit;
+@@ -190,11 +190,11 @@
+               clps_writel(port->x_char, UARTDR(port));
+               port->icount.tx++;
+               port->x_char = 0;
+-              return;
++              return IRQ_HANDLED;
+       }
+       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+               clps711xuart_stop_tx(port, 0);
+-              return;
++              return IRQ_HANDLED;
+       }
+       count = port->fifosize >> 1;
+@@ -211,6 +211,8 @@
+       if (uart_circ_empty(xmit))
+               clps711xuart_stop_tx(port, 0);
++
++      return IRQ_HANDLED;
+ }
+ static unsigned int clps711xuart_tx_empty(struct uart_port *port)
+Index: linux-2.6.0-test5/drivers/serial/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/Kconfig      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/Kconfig   2003-09-27 11:38:32.089650016 +0800
+@@ -10,6 +10,7 @@
+ # The new 8250/16550 serial drivers
+ config SERIAL_8250
+       tristate "8250/16550 and compatible serial support"
++      select SERIAL_CORE
+       ---help---
+         This selects whether you want to include the driver for the standard
+         serial ports.  The standard answer is Y.  People who might say N
+@@ -41,6 +42,7 @@
+ config SERIAL_8250_CONSOLE
+       bool "Console on 8250/16550 and compatible serial port"
+       depends on SERIAL_8250=y
++      select SERIAL_CORE_CONSOLE
+       ---help---
+         If you say Y here, it will be possible to use a serial port as the
+         system console (the system console is the device which receives all
+@@ -167,12 +169,14 @@
+ config SERIAL_ANAKIN
+       bool "Anakin serial port support"
+       depends on ARM && ARCH_ANAKIN
++      select SERIAL_CORE
+       help
+         ::: To be written :::
+ config SERIAL_ANAKIN_CONSOLE
+       bool "Console on Anakin serial port"
+       depends on SERIAL_ANAKIN
++      select SERIAL_CORE_CONSOLE
+       help
+         Even if you say Y here, the currently visible virtual console
+         (/dev/tty0) will still be used as the system console by default, but
+@@ -190,7 +194,8 @@
+ config SERIAL_AMBA
+       tristate "ARM AMBA serial port support"
+-      depends on ARM && ARCH_INTEGRATOR
++      depends on ARM_AMBA
++      select SERIAL_CORE
+       help
+         This selects the ARM(R) AMBA(R) PrimeCell UART.  If you have an
+         Integrator platform, say Y or M here.
+@@ -200,6 +205,7 @@
+ config SERIAL_AMBA_CONSOLE
+       bool "Support for console on AMBA serial port"
+       depends on SERIAL_AMBA=y
++      select SERIAL_CORE_CONSOLE
+       ---help---
+         Say Y here if you wish to use an AMBA PrimeCell UART as the system
+         console (the system console is the device which receives all kernel
+@@ -214,18 +220,20 @@
+ config SERIAL_INTEGRATOR
+       bool
+-      depends on SERIAL_AMBA=y
++      depends on SERIAL_AMBA && ARCH_INTEGRATOR
+       default y
+ config SERIAL_CLPS711X
+       tristate "CLPS711X serial port support"
+       depends on ARM && ARCH_CLPS711X
++      select SERIAL_CORE
+       help
+         ::: To be written :::
+ config SERIAL_CLPS711X_CONSOLE
+       bool "Support for console on CLPS711X serial port"
+       depends on SERIAL_CLPS711X=y
++      select SERIAL_CORE_CONSOLE
+       help
+         Even if you say Y here, the currently visible virtual console
+         (/dev/tty0) will still be used as the system console by default, but
+@@ -243,6 +251,7 @@
+ config SERIAL_21285
+       tristate "DC21285 serial port support"
+       depends on ARM && FOOTBRIDGE
++      select SERIAL_CORE
+       help
+         If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
+         PCI bridge you can enable its onboard serial port by enabling this
+@@ -258,6 +267,7 @@
+ config SERIAL_21285_CONSOLE
+       bool "Console on DC21285 serial port"
+       depends on SERIAL_21285=y
++      select SERIAL_CORE_CONSOLE
+       help
+         If you have enabled the serial port on the 21285 footbridge you can
+         make it the console by answering Y to this option.
+@@ -272,6 +282,7 @@
+ config SERIAL_UART00
+       bool "Excalibur serial port (uart00) support"
+       depends on ARM && ARCH_CAMELOT
++      select SERIAL_CORE
+       help
+         Say Y here if you want to use the hard logic uart on Excalibur. This
+         driver also supports soft logic implentations of this uart core.
+@@ -279,6 +290,7 @@
+ config SERIAL_UART00_CONSOLE
+       bool "Support for console on Excalibur serial port"
+       depends on SERIAL_UART00
++      select SERIAL_CORE_CONSOLE
+       help
+         Say Y here if you want to support a serial console on an Excalibur
+         hard logic uart or uart00 IP core.
+@@ -293,6 +305,7 @@
+ config SERIAL_SA1100
+       bool "SA1100 serial port support"
+       depends on ARM && ARCH_SA1100
++      select SERIAL_CORE
+       help
+         If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
+         can enable its onboard serial port by enabling this option.
+@@ -302,6 +315,7 @@
+ config SERIAL_SA1100_CONSOLE
+       bool "Console on SA1100 serial port"
+       depends on SERIAL_SA1100
++      select SERIAL_CORE_CONSOLE
+       help
+         If you have enabled the serial port on the SA1100/SA1110 StrongARM
+         CPU you can make it the console by answering Y to this option.
+@@ -316,6 +330,8 @@
+ config SERIAL_SUNCORE
+       bool
+       depends on SPARC32 || SPARC64
++      select SERIAL_CORE
++      select SERIAL_CORE_CONSOLE
+       default y
+ config SERIAL_SUNZILOG
+@@ -352,6 +368,7 @@
+ config SERIAL_MUX
+       tristate "Serial MUX support"
+       depends on PARISC
++      select SERIAL_CORE
+       default y
+       ---help---
+         Saying Y here will enable the hardware MUX serial driver for
+@@ -369,6 +386,7 @@
+ config SERIAL_MUX_CONSOLE
+         bool "Support for console on serial MUX"
+         depends on SERIAL_MUX
++      select SERIAL_CORE_CONSOLE
+         default y
+ config PDC_CONSOLE
+@@ -406,6 +424,7 @@
+ config V850E_UART
+       bool "NEC V850E on-chip UART support"
+       depends on V850E_MA1 || V850E_ME2 || V850E_TEG || V850E2_ANNA || V850E_AS85EP1
++      select SERIAL_CORE
+       default y
+ config V850E_UARTB
+@@ -416,10 +435,12 @@
+ config V850E_UART_CONSOLE
+       bool "Use NEC V850E on-chip UART for console"
+       depends on V850E_UART
++      select SERIAL_CORE_CONSOLE
+ config SERIAL98
+       tristate "PC-9800 8251-based primary serial port support"
+       depends on X86_PC9800
++      select SERIAL_CORE
+       help
+         If you want to use standard primary serial ports on PC-9800, 
+         say Y.  Otherwise, say N.
+@@ -427,16 +448,13 @@
+ config SERIAL98_CONSOLE
+         bool "Support for console on PC-9800 standard serial port"
+         depends on SERIAL98=y
++      select SERIAL_CORE_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_UART && SERIAL_PMACZILOG!=y && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m || SERIAL_PMACZILOG=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 || SERIAL_PMACZILOG=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_UART_CONSOLE || SERIAL98_CONSOLE || SERIAL_PMACZILOG_CONSOLE
+-      default y
+ config SERIAL_68328
+       bool "68328 serial support"
+@@ -476,6 +494,7 @@
+ config SERIAL_PMACZILOG
+       tristate "PowerMac z85c30 ESCC support"
+       depends on PPC_OF
++      select SERIAL_CORE
+       help
+         This driver supports the Zilog z85C30 serial ports found on
+         PowerMac machines.
+@@ -484,6 +503,7 @@
+ config SERIAL_PMACZILOG_CONSOLE
+       bool "Console on PowerMac z85c30 serial port"
+       depends on SERIAL_PMACZILOG=y
++      select SERIAL_CORE_CONSOLE
+       help
+         If you would like to be able to use the z85c30 serial port
+         on your PowerMac as the console, you can do so by answering
+Index: linux-2.6.0-test5/drivers/serial/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/Makefile     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/Makefile  2003-09-27 11:38:32.113646368 +0800
+@@ -11,10 +11,10 @@
+ serial-8250-$(CONFIG_SERIAL_8250_HCDP) += 8250_hcdp.o
+ serial-8250-$(CONFIG_SERIAL_8250_ACPI) += 8250_acpi.o
+-obj-$(CONFIG_SERIAL_CORE) += core.o
++obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+ obj-$(CONFIG_SERIAL_21285) += 21285.o
+ obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
+-obj-$(CONFIG_SERIAL_8250_CS) += 8250_cs.o
++obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
+ obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
+ obj-$(CONFIG_SERIAL_ANAKIN) += anakin.o
+ obj-$(CONFIG_SERIAL_AMBA) += amba.o
+Index: linux-2.6.0-test5/drivers/serial/sa1100.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/sa1100.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/serial/sa1100.c  2003-09-27 11:38:32.166638312 +0800
+@@ -862,8 +862,8 @@
+ {
+       struct sa1100_port *sport = dev_get_drvdata(_dev);
+-      if (sport)
+-              uart_suspend_port(&sa1100_reg, &sport->port, level);
++      if (sport && level == SUSPEND_DISABLE)
++              uart_suspend_port(&sa1100_reg, &sport->port);
+       return 0;
+ }
+@@ -872,8 +872,8 @@
+ {
+       struct sa1100_port *sport = dev_get_drvdata(_dev);
+-      if (sport)
+-              uart_resume_port(&sa1100_reg, &sport->port, level);
++      if (sport && level == RESUME_ENABLE)
++              uart_resume_port(&sa1100_reg, &sport->port);
+       return 0;
+ }
+Index: linux-2.6.0-test5/drivers/serial/serial_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/serial_core.c        2003-09-27 11:38:18.463721472 +0800
++++ linux-2.6.0-test5/drivers/serial/serial_core.c     2003-09-27 11:38:32.171637552 +0800
+@@ -0,0 +1,2425 @@
++/*
++ *  linux/drivers/char/core.c
++ *
++ *  Driver core for serial ports
++ *
++ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
++ *
++ *  Copyright 1999 ARM Limited
++ *  Copyright (C) 2000-2001 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/config.h>
++#include <linux/module.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/serial_core.h>
++#include <linux/smp_lock.h>
++#include <linux/device.h>
++#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++
++#undef        DEBUG
++#ifdef DEBUG
++#define DPRINTK(x...) printk(x)
++#else
++#define DPRINTK(x...) do { } while (0)
++#endif
++
++/*
++ * This is used to lock changes in serial line configuration.
++ */
++static DECLARE_MUTEX(port_sem);
++
++#define HIGH_BITS_OFFSET      ((sizeof(long)-sizeof(int))*8)
++
++#define uart_users(state)     ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
++
++#ifdef CONFIG_SERIAL_CORE_CONSOLE
++#define uart_console(port)    ((port)->cons && (port)->cons->index == (port)->line)
++#else
++#define uart_console(port)    (0)
++#endif
++
++static void uart_change_speed(struct uart_state *state, struct termios *old_termios);
++static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
++static void uart_change_pm(struct uart_state *state, int pm_state);
++
++/*
++ * This routine is used by the interrupt handler to schedule processing in
++ * the software interrupt portion of the driver.
++ */
++void uart_write_wakeup(struct uart_port *port)
++{
++      struct uart_info *info = port->info;
++      tasklet_schedule(&info->tlet);
++}
++
++static void uart_stop(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++      unsigned long flags;
++
++      spin_lock_irqsave(&port->lock, flags);
++      port->ops->stop_tx(port, 1);
++      spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void __uart_start(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++
++      if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf &&
++          !tty->stopped && !tty->hw_stopped)
++              port->ops->start_tx(port, 1);
++}
++
++static void uart_start(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++      unsigned long flags;
++
++      spin_lock_irqsave(&port->lock, flags);
++      __uart_start(tty);
++      spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void uart_tasklet_action(unsigned long data)
++{
++      struct uart_state *state = (struct uart_state *)data;
++      struct tty_struct *tty;
++
++      tty = state->info->tty;
++      if (tty) {
++              if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++                  tty->ldisc.write_wakeup)
++                      tty->ldisc.write_wakeup(tty);
++              wake_up_interruptible(&tty->write_wait);
++      }
++}
++
++static inline void
++uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
++{
++      unsigned long flags;
++      unsigned int old;
++
++      spin_lock_irqsave(&port->lock, flags);
++      old = port->mctrl;
++      port->mctrl = (old & ~clear) | set;
++      if (old != port->mctrl)
++              port->ops->set_mctrl(port, port->mctrl);
++      spin_unlock_irqrestore(&port->lock, flags);
++}
++
++#define uart_set_mctrl(port,set)      uart_update_mctrl(port,set,0)
++#define uart_clear_mctrl(port,clear)  uart_update_mctrl(port,0,clear)
++
++/*
++ * Startup the port.  This will be called once per open.  All calls
++ * will be serialised by the per-port semaphore.
++ */
++static int uart_startup(struct uart_state *state, int init_hw)
++{
++      struct uart_info *info = state->info;
++      struct uart_port *port = state->port;
++      unsigned long page;
++      int retval = 0;
++
++      if (info->flags & UIF_INITIALIZED)
++              return 0;
++
++      /*
++       * Set the TTY IO error marker - we will only clear this
++       * once we have successfully opened the port.  Also set
++       * up the tty->alt_speed kludge
++       */
++      if (info->tty)
++              set_bit(TTY_IO_ERROR, &info->tty->flags);
++
++      if (port->type == PORT_UNKNOWN)
++              return 0;
++
++      /*
++       * Initialise and allocate the transmit and temporary
++       * buffer.
++       */
++      if (!info->xmit.buf) {
++              page = get_zeroed_page(GFP_KERNEL);
++              if (!page)
++                      return -ENOMEM;
++
++              info->xmit.buf = (unsigned char *) page;
++              info->tmpbuf = info->xmit.buf + UART_XMIT_SIZE;
++              init_MUTEX(&info->tmpbuf_sem);
++              uart_circ_clear(&info->xmit);
++      }
++
++      port->mctrl = 0;
++
++      retval = port->ops->startup(port);
++      if (retval == 0) {
++              if (init_hw) {
++                      /*
++                       * Initialise the hardware port settings.
++                       */
++                      uart_change_speed(state, NULL);
++
++                      /*
++                       * Setup the RTS and DTR signals once the
++                       * port is open and ready to respond.
++                       */
++                      if (info->tty->termios->c_cflag & CBAUD)
++                              uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
++              }
++
++              info->flags |= UIF_INITIALIZED;
++
++              clear_bit(TTY_IO_ERROR, &info->tty->flags);
++      }
++
++      if (retval && capable(CAP_SYS_ADMIN))
++              retval = 0;
++
++      return retval;
++}
++
++/*
++ * This routine will shutdown a serial port; interrupts are disabled, and
++ * DTR is dropped if the hangup on close termio flag is on.  Calls to
++ * uart_shutdown are serialised by the per-port semaphore.
++ */
++static void uart_shutdown(struct uart_state *state)
++{
++      struct uart_info *info = state->info;
++      struct uart_port *port = state->port;
++
++      if (!(info->flags & UIF_INITIALIZED))
++              return;
++
++      /*
++       * Turn off DTR and RTS early.
++       */
++      if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
++              uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
++
++      /*
++       * clear delta_msr_wait queue to avoid mem leaks: we may free
++       * the irq here so the queue might never be woken up.  Note
++       * that we won't end up waiting on delta_msr_wait again since
++       * any outstanding file descriptors should be pointing at
++       * hung_up_tty_fops now.
++       */
++      wake_up_interruptible(&info->delta_msr_wait);
++
++      /*
++       * Free the IRQ and disable the port.
++       */
++      port->ops->shutdown(port);
++
++      /*
++       * Ensure that the IRQ handler isn't running on another CPU.
++       */
++      synchronize_irq(port->irq);
++
++      /*
++       * Free the transmit buffer page.
++       */
++      if (info->xmit.buf) {
++              free_page((unsigned long)info->xmit.buf);
++              info->xmit.buf = NULL;
++              info->tmpbuf = NULL;
++      }
++
++      /*
++       * kill off our tasklet
++       */
++      tasklet_kill(&info->tlet);
++      if (info->tty)
++              set_bit(TTY_IO_ERROR, &info->tty->flags);
++
++      info->flags &= ~UIF_INITIALIZED;
++}
++
++/**
++ *    uart_update_timeout - update per-port FIFO timeout.
++ *    @port: uart_port structure describing the port.
++ *    @cflag: termios cflag value
++ *    @quot: uart clock divisor quotient
++ *
++ *    Set the port FIFO timeout value.  The @cflag value should
++ *    reflect the actual hardware settings.
++ */
++void
++uart_update_timeout(struct uart_port *port, unsigned int cflag,
++                  unsigned int baud)
++{
++      unsigned int bits;
++
++      /* byte size and parity */
++      switch (cflag & CSIZE) {
++      case CS5:
++              bits = 7;
++              break;
++      case CS6:
++              bits = 8;
++              break;
++      case CS7:
++              bits = 9;
++              break;
++      default:
++              bits = 10;
++              break; // CS8
++      }
++
++      if (cflag & CSTOPB)
++              bits++;
++      if (cflag & PARENB)
++              bits++;
++
++      /*
++       * The total number of bits to be transmitted in the fifo.
++       */
++      bits = bits * port->fifosize;
++
++      /*
++       * Figure the timeout to send the above number of bits.
++       * Add .02 seconds of slop
++       */
++      port->timeout = (HZ * bits) / baud + HZ/50;
++}
++
++EXPORT_SYMBOL(uart_update_timeout);
++
++/**
++ *    uart_get_baud_rate - return baud rate for a particular port
++ *    @port: uart_port structure describing the port in question.
++ *    @termios: desired termios settings.
++ *    @old: old termios (or NULL)
++ *    @min: minimum acceptable baud rate
++ *    @max: maximum acceptable baud rate
++ *
++ *    Decode the termios structure into a numeric baud rate,
++ *    taking account of the magic 38400 baud rate (with spd_*
++ *    flags), and mapping the %B0 rate to 9600 baud.
++ *
++ *    If the new baud rate is invalid, try the old termios setting.
++ *    If it's still invalid, we try 9600 baud.
++ *
++ *    Update the @termios structure to reflect the baud rate
++ *    we're actually going to be using.
++ */
++unsigned int
++uart_get_baud_rate(struct uart_port *port, struct termios *termios,
++                 struct termios *old, unsigned int min, unsigned int max)
++{
++      unsigned int try, baud, altbaud = 38400;
++      unsigned int flags = port->flags & UPF_SPD_MASK;
++
++      if (flags == UPF_SPD_HI)
++              altbaud = 57600;
++      if (flags == UPF_SPD_VHI)
++              altbaud = 115200;
++      if (flags == UPF_SPD_SHI)
++              altbaud = 230400;
++      if (flags == UPF_SPD_WARP)
++              altbaud = 460800;
++
++      for (try = 0; try < 2; try++) {
++              baud = tty_termios_baud_rate(termios);
++
++              /*
++               * The spd_hi, spd_vhi, spd_shi, spd_warp kludge...
++               * Die! Die! Die!
++               */
++              if (baud == 38400)
++                      baud = altbaud;
++
++              /*
++               * Special case: B0 rate.
++               */
++              if (baud == 0)
++                      baud = 9600;
++
++              if (baud >= min && baud <= max)
++                      return baud;
++
++              /*
++               * Oops, the quotient was zero.  Try again with
++               * the old baud rate if possible.
++               */
++              termios->c_cflag &= ~CBAUD;
++              if (old) {
++                      termios->c_cflag |= old->c_cflag & CBAUD;
++                      old = NULL;
++                      continue;
++              }
++
++              /*
++               * As a last resort, if the quotient is zero,
++               * default to 9600 bps
++               */
++              termios->c_cflag |= B9600;
++      }
++
++      return 0;
++}
++
++EXPORT_SYMBOL(uart_get_baud_rate);
++
++/**
++ *    uart_get_divisor - return uart clock divisor
++ *    @port: uart_port structure describing the port.
++ *    @baud: desired baud rate
++ *
++ *    Calculate the uart clock divisor for the port.
++ */
++unsigned int
++uart_get_divisor(struct uart_port *port, unsigned int baud)
++{
++      unsigned int quot;
++
++      /*
++       * Old custom speed handling.
++       */
++      if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
++              quot = port->custom_divisor;
++      else
++              quot = port->uartclk / (16 * baud);
++
++      return quot;
++}
++
++EXPORT_SYMBOL(uart_get_divisor);
++
++static void
++uart_change_speed(struct uart_state *state, struct termios *old_termios)
++{
++      struct tty_struct *tty = state->info->tty;
++      struct uart_port *port = state->port;
++      struct termios *termios;
++
++      /*
++       * If we have no tty, termios, or the port does not exist,
++       * then we can't set the parameters for this port.
++       */
++      if (!tty || !tty->termios || port->type == PORT_UNKNOWN)
++              return;
++
++      termios = tty->termios;
++
++      /*
++       * Set flags based on termios cflag
++       */
++      if (termios->c_cflag & CRTSCTS)
++              state->info->flags |= UIF_CTS_FLOW;
++      else
++              state->info->flags &= ~UIF_CTS_FLOW;
++
++      if (termios->c_cflag & CLOCAL)
++              state->info->flags &= ~UIF_CHECK_CD;
++      else
++              state->info->flags |= UIF_CHECK_CD;
++
++      port->ops->set_termios(port, termios, old_termios);
++}
++
++static inline void
++__uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
++{
++      unsigned long flags;
++
++      if (!circ->buf)
++              return;
++
++      spin_lock_irqsave(&port->lock, flags);
++      if (uart_circ_chars_free(circ) != 0) {
++              circ->buf[circ->head] = c;
++              circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
++      }
++      spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static inline int
++__uart_user_write(struct uart_port *port, struct circ_buf *circ,
++                const unsigned char *buf, int count)
++{
++      unsigned long flags;
++      int c, ret = 0;
++
++      if (down_interruptible(&port->info->tmpbuf_sem))
++              return -EINTR;
++
++      while (1) {
++              int c1;
++              c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
++              if (count < c)
++                      c = count;
++              if (c <= 0)
++                      break;
++
++              c -= copy_from_user(port->info->tmpbuf, buf, c);
++              if (!c) {
++                      if (!ret)
++                              ret = -EFAULT;
++                      break;
++              }
++              spin_lock_irqsave(&port->lock, flags);
++              c1 = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
++              if (c1 < c)
++                      c = c1;
++              memcpy(circ->buf + circ->head, port->info->tmpbuf, c);
++              circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
++              spin_unlock_irqrestore(&port->lock, flags);
++              buf += c;
++              count -= c;
++              ret += c;
++      }
++      up(&port->info->tmpbuf_sem);
++
++      return ret;
++}
++
++static inline int
++__uart_kern_write(struct uart_port *port, struct circ_buf *circ,
++                const unsigned char *buf, int count)
++{
++      unsigned long flags;
++      int c, ret = 0;
++
++      spin_lock_irqsave(&port->lock, flags);
++      while (1) {
++              c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
++              if (count < c)
++                      c = count;
++              if (c <= 0)
++                      break;
++              memcpy(circ->buf + circ->head, buf, c);
++              circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
++              buf += c;
++              count -= c;
++              ret += c;
++      }
++      spin_unlock_irqrestore(&port->lock, flags);
++
++      return ret;
++}
++
++static void uart_put_char(struct tty_struct *tty, unsigned char ch)
++{
++      struct uart_state *state = tty->driver_data;
++
++      if (tty)
++              __uart_put_char(state->port, &state->info->xmit, ch);
++}
++
++static void uart_flush_chars(struct tty_struct *tty)
++{
++      uart_start(tty);
++}
++
++static int
++uart_write(struct tty_struct *tty, int from_user, const unsigned char * buf,
++         int count)
++{
++      struct uart_state *state = tty->driver_data;
++      int ret;
++
++      if (!tty || !state->info->xmit.buf)
++              return 0;
++
++      if (from_user)
++              ret = __uart_user_write(state->port, &state->info->xmit, buf, count);
++      else
++              ret = __uart_kern_write(state->port, &state->info->xmit, buf, count);
++
++      uart_start(tty);
++      return ret;
++}
++
++static int uart_write_room(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++
++      return uart_circ_chars_free(&state->info->xmit);
++}
++
++static int uart_chars_in_buffer(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++
++      return uart_circ_chars_pending(&state->info->xmit);
++}
++
++static void uart_flush_buffer(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++      unsigned long flags;
++
++      DPRINTK("uart_flush_buffer(%d) called\n", tty->index);
++
++      spin_lock_irqsave(&port->lock, flags);
++      uart_circ_clear(&state->info->xmit);
++      spin_unlock_irqrestore(&port->lock, flags);
++      wake_up_interruptible(&tty->write_wait);
++      if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++          tty->ldisc.write_wakeup)
++              (tty->ldisc.write_wakeup)(tty);
++}
++
++/*
++ * This function is used to send a high-priority XON/XOFF character to
++ * the device
++ */
++static void uart_send_xchar(struct tty_struct *tty, char ch)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++      unsigned long flags;
++
++      if (port->ops->send_xchar)
++              port->ops->send_xchar(port, ch);
++      else {
++              port->x_char = ch;
++              if (ch) {
++                      spin_lock_irqsave(&port->lock, flags);
++                      port->ops->start_tx(port, 0);
++                      spin_unlock_irqrestore(&port->lock, flags);
++              }
++      }
++}
++
++static void uart_throttle(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++
++      if (I_IXOFF(tty))
++              uart_send_xchar(tty, STOP_CHAR(tty));
++
++      if (tty->termios->c_cflag & CRTSCTS)
++              uart_clear_mctrl(state->port, TIOCM_RTS);
++}
++
++static void uart_unthrottle(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++
++      if (I_IXOFF(tty)) {
++              if (port->x_char)
++                      port->x_char = 0;
++              else
++                      uart_send_xchar(tty, START_CHAR(tty));
++      }
++
++      if (tty->termios->c_cflag & CRTSCTS)
++              uart_set_mctrl(port, TIOCM_RTS);
++}
++
++static int uart_get_info(struct uart_state *state, struct serial_struct *retinfo)
++{
++      struct uart_port *port = state->port;
++      struct serial_struct tmp;
++
++      memset(&tmp, 0, sizeof(tmp));
++      tmp.type            = port->type;
++      tmp.line            = port->line;
++      tmp.port            = port->iobase;
++      if (HIGH_BITS_OFFSET)
++              tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET;
++      tmp.irq             = port->irq;
++      tmp.flags           = port->flags;
++      tmp.xmit_fifo_size  = port->fifosize;
++      tmp.baud_base       = port->uartclk / 16;
++      tmp.close_delay     = state->close_delay;
++      tmp.closing_wait    = state->closing_wait;
++      tmp.custom_divisor  = port->custom_divisor;
++      tmp.hub6            = port->hub6;
++      tmp.io_type         = port->iotype;
++      tmp.iomem_reg_shift = port->regshift;
++      tmp.iomem_base      = (void *)port->mapbase;
++
++      if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
++              return -EFAULT;
++      return 0;
++}
++
++static int
++uart_set_info(struct uart_state *state, struct serial_struct *newinfo)
++{
++      struct serial_struct new_serial;
++      struct uart_port *port = state->port;
++      unsigned long new_port;
++      unsigned int change_irq, change_port, old_flags;
++      unsigned int old_custom_divisor;
++      int retval = 0;
++
++      if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
++              return -EFAULT;
++
++      new_port = new_serial.port;
++      if (HIGH_BITS_OFFSET)
++              new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
++
++      new_serial.irq = irq_canonicalize(new_serial.irq);
++
++      /*
++       * This semaphore protects state->count.  It is also
++       * very useful to prevent opens.  Also, take the
++       * port configuration semaphore to make sure that a
++       * module insertion/removal doesn't change anything
++       * under us.
++       */
++      down(&state->sem);
++
++      change_irq  = new_serial.irq != port->irq;
++
++      /*
++       * Since changing the 'type' of the port changes its resource
++       * allocations, we should treat type changes the same as
++       * IO port changes.
++       */
++      change_port = new_port != port->iobase ||
++                    (unsigned long)new_serial.iomem_base != port->mapbase ||
++                    new_serial.hub6 != port->hub6 ||
++                    new_serial.io_type != port->iotype ||
++                    new_serial.iomem_reg_shift != port->regshift ||
++                    new_serial.type != port->type;
++
++      old_flags = port->flags;
++      old_custom_divisor = port->custom_divisor;
++
++      if (!capable(CAP_SYS_ADMIN)) {
++              retval = -EPERM;
++              if (change_irq || change_port ||
++                  (new_serial.baud_base != port->uartclk / 16) ||
++                  (new_serial.close_delay != state->close_delay) ||
++                  (new_serial.closing_wait != state->closing_wait) ||
++                  (new_serial.xmit_fifo_size != port->fifosize) ||
++                  (((new_serial.flags ^ old_flags) & ~UPF_USR_MASK) != 0))
++                      goto exit;
++              port->flags = ((port->flags & ~UPF_USR_MASK) |
++                             (new_serial.flags & UPF_USR_MASK));
++              port->custom_divisor = new_serial.custom_divisor;
++              goto check_and_exit;
++      }
++
++      /*
++       * Ask the low level driver to verify the settings.
++       */
++      if (port->ops->verify_port)
++              retval = port->ops->verify_port(port, &new_serial);
++
++      if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
++          (new_serial.baud_base < 9600))
++              retval = -EINVAL;
++
++      if (retval)
++              goto exit;
++
++      if (change_port || change_irq) {
++              retval = -EBUSY;
++
++              /*
++               * Make sure that we are the sole user of this port.
++               */
++              if (uart_users(state) > 1)
++                      goto exit;
++
++              /*
++               * We need to shutdown the serial port at the old
++               * port/type/irq combination.
++               */
++              uart_shutdown(state);
++      }
++
++      if (change_port) {
++              unsigned long old_iobase, old_mapbase;
++              unsigned int old_type, old_iotype, old_hub6, old_shift;
++
++              old_iobase = port->iobase;
++              old_mapbase = port->mapbase;
++              old_type = port->type;
++              old_hub6 = port->hub6;
++              old_iotype = port->iotype;
++              old_shift = port->regshift;
++
++              /*
++               * Free and release old regions
++               */
++              if (old_type != PORT_UNKNOWN)
++                      port->ops->release_port(port);
++
++              port->iobase = new_port;
++              port->type = new_serial.type;
++              port->hub6 = new_serial.hub6;
++              port->iotype = new_serial.io_type;
++              port->regshift = new_serial.iomem_reg_shift;
++              port->mapbase = (unsigned long)new_serial.iomem_base;
++
++              /*
++               * Claim and map the new regions
++               */
++              if (port->type != PORT_UNKNOWN) {
++                      retval = port->ops->request_port(port);
++              } else {
++                      /* Always success - Jean II */
++                      retval = 0;
++              }
++
++              /*
++               * If we fail to request resources for the
++               * new port, try to restore the old settings.
++               */
++              if (retval && old_type != PORT_UNKNOWN) {
++                      port->iobase = old_iobase;
++                      port->type = old_type;
++                      port->hub6 = old_hub6;
++                      port->iotype = old_iotype;
++                      port->regshift = old_shift;
++                      port->mapbase = old_mapbase;
++                      retval = port->ops->request_port(port);
++                      /*
++                       * If we failed to restore the old settings,
++                       * we fail like this.
++                       */
++                      if (retval)
++                              port->type = PORT_UNKNOWN;
++
++                      /*
++                       * We failed anyway.
++                       */
++                      retval = -EBUSY;
++              }
++      }
++
++      port->irq              = new_serial.irq;
++      port->uartclk          = new_serial.baud_base * 16;
++      port->flags            = (port->flags & ~UPF_CHANGE_MASK) |
++                               (new_serial.flags & UPF_CHANGE_MASK);
++      port->custom_divisor   = new_serial.custom_divisor;
++      state->close_delay     = new_serial.close_delay * HZ / 100;
++      state->closing_wait    = new_serial.closing_wait * HZ / 100;
++      port->fifosize         = new_serial.xmit_fifo_size;
++      if (state->info->tty)
++              state->info->tty->low_latency =
++                      (port->flags & UPF_LOW_LATENCY) ? 1 : 0;
++
++ check_and_exit:
++      retval = 0;
++      if (port->type == PORT_UNKNOWN)
++              goto exit;
++      if (state->info->flags & UIF_INITIALIZED) {
++              if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
++                  old_custom_divisor != port->custom_divisor) {
++                      /* If they're setting up a custom divisor or speed,
++                       * instead of clearing it, then bitch about it. No
++                       * need to rate-limit; it's CAP_SYS_ADMIN only. */
++                      if (port->flags & UPF_SPD_MASK) {
++                              printk(KERN_NOTICE "%s sets custom speed on %s%d. This is deprecated.\n",
++                                     current->comm, state->info->tty->driver->name, 
++                                     state->port->line);
++                      }
++                      uart_change_speed(state, NULL);
++              }
++      } else
++              retval = uart_startup(state, 1);
++ exit:
++      up(&state->sem);
++      return retval;
++}
++
++
++/*
++ * uart_get_lsr_info - get line status register info.
++ * Note: uart_ioctl protects us against hangups.
++ */
++static int uart_get_lsr_info(struct uart_state *state, unsigned int *value)
++{
++      struct uart_port *port = state->port;
++      unsigned int result;
++
++      result = port->ops->tx_empty(port);
++
++      /*
++       * If we're about to load something into the transmit
++       * register, we'll pretend the transmitter isn't empty to
++       * avoid a race condition (depending on when the transmit
++       * interrupt happens).
++       */
++      if (port->x_char ||
++          ((uart_circ_chars_pending(&state->info->xmit) > 0) &&
++           !state->info->tty->stopped && !state->info->tty->hw_stopped))
++              result &= ~TIOCSER_TEMT;
++      
++      return put_user(result, value);
++}
++
++static int uart_tiocmget(struct tty_struct *tty, struct file *file)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++      int result = -EIO;
++
++      down(&state->sem);
++      if ((!file || !tty_hung_up_p(file)) &&
++          !(tty->flags & (1 << TTY_IO_ERROR))) {
++              result = port->mctrl;
++              result |= port->ops->get_mctrl(port);
++      }
++      up(&state->sem);
++
++      return result;
++}
++
++static int
++uart_tiocmset(struct tty_struct *tty, struct file *file,
++            unsigned int set, unsigned int clear)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++      int ret = -EIO;
++
++      down(&state->sem);
++      if ((!file || !tty_hung_up_p(file)) &&
++          !(tty->flags & (1 << TTY_IO_ERROR))) {
++              uart_update_mctrl(port, set, clear);
++              ret = 0;
++      }
++      up(&state->sem);
++      return ret;
++}
++
++static void uart_break_ctl(struct tty_struct *tty, int break_state)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++
++      BUG_ON(!kernel_locked());
++
++      down(&state->sem);
++
++      if (port->type != PORT_UNKNOWN)
++              port->ops->break_ctl(port, break_state);
++
++      up(&state->sem);
++}
++
++static int uart_do_autoconfig(struct uart_state *state)
++{
++      struct uart_port *port = state->port;
++      int flags, ret;
++
++      if (!capable(CAP_SYS_ADMIN))
++              return -EPERM;
++
++      /*
++       * Take the per-port semaphore.  This prevents count from
++       * changing, and hence any extra opens of the port while
++       * we're auto-configuring.
++       */
++      if (down_interruptible(&state->sem))
++              return -ERESTARTSYS;
++
++      ret = -EBUSY;
++      if (uart_users(state) == 1) {
++              uart_shutdown(state);
++
++              /*
++               * If we already have a port type configured,
++               * we must release its resources.
++               */
++              if (port->type != PORT_UNKNOWN)
++                      port->ops->release_port(port);
++
++              flags = UART_CONFIG_TYPE;
++              if (port->flags & UPF_AUTO_IRQ)
++                      flags |= UART_CONFIG_IRQ;
++
++              /*
++               * This will claim the ports resources if
++               * a port is found.
++               */
++              port->ops->config_port(port, flags);
++
++              ret = uart_startup(state, 1);
++      }
++      up(&state->sem);
++      return ret;
++}
++
++/*
++ * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
++ * - mask passed in arg for lines of interest
++ *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
++ * Caller should use TIOCGICOUNT to see which one it was
++ */
++static int
++uart_wait_modem_status(struct uart_state *state, unsigned long arg)
++{
++      struct uart_port *port = state->port;
++      DECLARE_WAITQUEUE(wait, current);
++      struct uart_icount cprev, cnow;
++      int ret;
++
++      /*
++       * note the counters on entry
++       */
++      spin_lock_irq(&port->lock);
++      memcpy(&cprev, &port->icount, sizeof(struct uart_icount));
++
++      /*
++       * Force modem status interrupts on
++       */
++      port->ops->enable_ms(port);
++      spin_unlock_irq(&port->lock);
++
++      add_wait_queue(&state->info->delta_msr_wait, &wait);
++      for (;;) {
++              spin_lock_irq(&port->lock);
++              memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
++              spin_unlock_irq(&port->lock);
++
++              set_current_state(TASK_INTERRUPTIBLE);
++
++              if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
++                  ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
++                  ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
++                  ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
++                      ret = 0;
++                      break;
++              }
++
++              schedule();
++
++              /* see if a signal did it */
++              if (signal_pending(current)) {
++                      ret = -ERESTARTSYS;
++                      break;
++              }
++
++              cprev = cnow;
++      }
++
++      current->state = TASK_RUNNING;
++      remove_wait_queue(&state->info->delta_msr_wait, &wait);
++
++      return ret;
++}
++
++/*
++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++ * Return: write counters to the user passed counter struct
++ * NB: both 1->0 and 0->1 transitions are counted except for
++ *     RI where only 0->1 is counted.
++ */
++static int
++uart_get_count(struct uart_state *state, struct serial_icounter_struct *icnt)
++{
++      struct serial_icounter_struct icount;
++      struct uart_icount cnow;
++      struct uart_port *port = state->port;
++
++      spin_lock_irq(&port->lock);
++      memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
++      spin_unlock_irq(&port->lock);
++
++      icount.cts         = cnow.cts;
++      icount.dsr         = cnow.dsr;
++      icount.rng         = cnow.rng;
++      icount.dcd         = cnow.dcd;
++      icount.rx          = cnow.rx;
++      icount.tx          = cnow.tx;
++      icount.frame       = cnow.frame;
++      icount.overrun     = cnow.overrun;
++      icount.parity      = cnow.parity;
++      icount.brk         = cnow.brk;
++      icount.buf_overrun = cnow.buf_overrun;
++
++      return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0;
++}
++
++/*
++ * Called via sys_ioctl under the BKL.  We can use spin_lock_irq() here.
++ */
++static int
++uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
++         unsigned long arg)
++{
++      struct uart_state *state = tty->driver_data;
++      int ret = -ENOIOCTLCMD;
++
++      BUG_ON(!kernel_locked());
++
++      /*
++       * These ioctls don't rely on the hardware to be present.
++       */
++      switch (cmd) {
++      case TIOCGSERIAL:
++              ret = uart_get_info(state, (struct serial_struct *)arg);
++              break;
++
++      case TIOCSSERIAL:
++              ret = uart_set_info(state, (struct serial_struct *)arg);
++              break;
++
++      case TIOCSERCONFIG:
++              ret = uart_do_autoconfig(state);
++              break;
++
++      case TIOCSERGWILD: /* obsolete */
++      case TIOCSERSWILD: /* obsolete */
++              ret = 0;
++              break;
++      }
++
++      if (ret != -ENOIOCTLCMD)
++              goto out;
++
++      if (tty->flags & (1 << TTY_IO_ERROR)) {
++              ret = -EIO;
++              goto out;
++      }
++
++      /*
++       * The following should only be used when hardware is present.
++       */
++      switch (cmd) {
++      case TIOCMIWAIT:
++              ret = uart_wait_modem_status(state, arg);
++              break;
++
++      case TIOCGICOUNT:
++              ret = uart_get_count(state, (struct serial_icounter_struct *)arg);
++              break;
++      }
++
++      if (ret != -ENOIOCTLCMD)
++              goto out;
++
++      down(&state->sem);
++
++      if (tty_hung_up_p(filp)) {
++              ret = -EIO;
++              goto out_up;
++      }
++
++      /*
++       * All these rely on hardware being present and need to be
++       * protected against the tty being hung up.
++       */
++      switch (cmd) {
++      case TIOCSERGETLSR: /* Get line status register */
++              ret = uart_get_lsr_info(state, (unsigned int *)arg);
++              break;
++
++      default: {
++              struct uart_port *port = state->port;
++              if (port->ops->ioctl)
++                      ret = port->ops->ioctl(port, cmd, arg);
++              break;
++      }
++      }
++ out_up:
++      up(&state->sem);
++ out:
++      return ret;
++}
++
++static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios)
++{
++      struct uart_state *state = tty->driver_data;
++      unsigned long flags;
++      unsigned int cflag = tty->termios->c_cflag;
++
++      BUG_ON(!kernel_locked());
++
++      /*
++       * These are the bits that are used to setup various
++       * flags in the low level driver.
++       */
++#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
++
++      if ((cflag ^ old_termios->c_cflag) == 0 &&
++          RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
++              return;
++
++      uart_change_speed(state, old_termios);
++
++      /* Handle transition to B0 status */
++      if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
++              uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR);
++
++      /* Handle transition away from B0 status */
++      if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
++              unsigned int mask = TIOCM_DTR;
++              if (!(cflag & CRTSCTS) ||
++                  !test_bit(TTY_THROTTLED, &tty->flags))
++                      mask |= TIOCM_RTS;
++              uart_set_mctrl(state->port, mask);
++      }
++
++      /* Handle turning off CRTSCTS */
++      if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
++              spin_lock_irqsave(&state->port->lock, flags);
++              tty->hw_stopped = 0;
++              __uart_start(tty);
++              spin_unlock_irqrestore(&state->port->lock, flags);
++      }
++
++#if 0
++      /*
++       * No need to wake up processes in open wait, since they
++       * sample the CLOCAL flag once, and don't recheck it.
++       * XXX  It's not clear whether the current behavior is correct
++       * or not.  Hence, this may change.....
++       */
++      if (!(old_termios->c_cflag & CLOCAL) &&
++          (tty->termios->c_cflag & CLOCAL))
++              wake_up_interruptible(&state->info->open_wait);
++#endif
++}
++
++/*
++ * In 2.4.5, calls to this will be serialized via the BKL in
++ *  linux/drivers/char/tty_io.c:tty_release()
++ *  linux/drivers/char/tty_io.c:do_tty_handup()
++ */
++static void uart_close(struct tty_struct *tty, struct file *filp)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++
++      BUG_ON(!kernel_locked());
++      DPRINTK("uart_close(%d) called\n", port->line);
++
++      down(&state->sem);
++
++      if (tty_hung_up_p(filp))
++              goto done;
++
++      if ((tty->count == 1) && (state->count != 1)) {
++              /*
++               * Uh, oh.  tty->count is 1, which means that the tty
++               * structure will be freed.  state->count should always
++               * be one in these conditions.  If it's greater than
++               * one, we've got real problems, since it means the
++               * serial port won't be shutdown.
++               */
++              printk("uart_close: bad serial port count; tty->count is 1, "
++                     "state->count is %d\n", state->count);
++              state->count = 1;
++      }
++      if (--state->count < 0) {
++              printk("rs_close: bad serial port count for %s: %d\n",
++                     tty->name, state->count);
++              state->count = 0;
++      }
++      if (state->count)
++              goto done;
++
++      /*
++       * Now we wait for the transmit buffer to clear; and we notify
++       * the line discipline to only process XON/XOFF characters by
++       * setting tty->closing.
++       */
++      tty->closing = 1;
++
++      if (state->closing_wait != USF_CLOSING_WAIT_NONE)
++              tty_wait_until_sent(tty, state->closing_wait);
++
++      /*
++       * At this point, we stop accepting input.  To do this, we
++       * disable the receive line status interrupts.
++       */
++      if (state->info->flags & UIF_INITIALIZED) {
++              unsigned long flags;
++              spin_lock_irqsave(&port->lock, flags);
++              port->ops->stop_rx(port);
++              spin_unlock_irqrestore(&port->lock, flags);
++              /*
++               * Before we drop DTR, make sure the UART transmitter
++               * has completely drained; this is especially
++               * important if there is a transmit FIFO!
++               */
++              uart_wait_until_sent(tty, port->timeout);
++      }
++
++      uart_shutdown(state);
++      uart_flush_buffer(tty);
++      if (tty->ldisc.flush_buffer)
++              tty->ldisc.flush_buffer(tty);
++      tty->closing = 0;
++      state->info->tty = NULL;
++
++      if (state->info->blocked_open) {
++              if (state->close_delay) {
++                      set_current_state(TASK_INTERRUPTIBLE);
++                      schedule_timeout(state->close_delay);
++                      set_current_state(TASK_RUNNING);
++              }
++      } else if (!uart_console(port)) {
++              uart_change_pm(state, 3);
++      }
++
++      /*
++       * Wake up anyone trying to open this port.
++       */
++      state->info->flags &= ~UIF_NORMAL_ACTIVE;
++      wake_up_interruptible(&state->info->open_wait);
++
++ done:
++      up(&state->sem);
++}
++
++static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
++{
++      struct uart_state *state = tty->driver_data;
++      struct uart_port *port = state->port;
++      unsigned long char_time, expire;
++
++      BUG_ON(!kernel_locked());
++
++      if (port->type == PORT_UNKNOWN || port->fifosize == 0)
++              return;
++
++      /*
++       * Set the check interval to be 1/5 of the estimated time to
++       * send a single character, and make it at least 1.  The check
++       * interval should also be less than the timeout.
++       *
++       * Note: we have to use pretty tight timings here to satisfy
++       * the NIST-PCTS.
++       */
++      char_time = (port->timeout - HZ/50) / port->fifosize;
++      char_time = char_time / 5;
++      if (char_time == 0)
++              char_time = 1;
++      if (timeout && timeout < char_time)
++              char_time = timeout;
++
++      /*
++       * If the transmitter hasn't cleared in twice the approximate
++       * amount of time to send the entire FIFO, it probably won't
++       * ever clear.  This assumes the UART isn't doing flow
++       * control, which is currently the case.  Hence, if it ever
++       * takes longer than port->timeout, this is probably due to a
++       * UART bug of some kind.  So, we clamp the timeout parameter at
++       * 2*port->timeout.
++       */
++      if (timeout == 0 || timeout > 2 * port->timeout)
++              timeout = 2 * port->timeout;
++
++      expire = jiffies + timeout;
++
++      DPRINTK("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n",
++              port->line, jiffies, expire);
++
++      /*
++       * Check whether the transmitter is empty every 'char_time'.
++       * 'timeout' / 'expire' give us the maximum amount of time
++       * we wait.
++       */
++      while (!port->ops->tx_empty(port)) {
++              set_current_state(TASK_INTERRUPTIBLE);
++              schedule_timeout(char_time);
++              if (signal_pending(current))
++                      break;
++              if (time_after(jiffies, expire))
++                      break;
++      }
++      set_current_state(TASK_RUNNING); /* might not be needed */
++}
++
++/*
++ * This is called with the BKL held in
++ *  linux/drivers/char/tty_io.c:do_tty_hangup()
++ * We're called from the eventd thread, so we can sleep for
++ * a _short_ time only.
++ */
++static void uart_hangup(struct tty_struct *tty)
++{
++      struct uart_state *state = tty->driver_data;
++
++      BUG_ON(!kernel_locked());
++      DPRINTK("uart_hangup(%d)\n", state->port->line);
++
++      down(&state->sem);
++      if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) {
++              uart_flush_buffer(tty);
++              uart_shutdown(state);
++              state->count = 0;
++              state->info->flags &= ~UIF_NORMAL_ACTIVE;
++              state->info->tty = NULL;
++              wake_up_interruptible(&state->info->open_wait);
++              wake_up_interruptible(&state->info->delta_msr_wait);
++      }
++      up(&state->sem);
++}
++
++/*
++ * Copy across the serial console cflag setting into the termios settings
++ * for the initial open of the port.  This allows continuity between the
++ * kernel settings, and the settings init adopts when it opens the port
++ * for the first time.
++ */
++static void uart_update_termios(struct uart_state *state)
++{
++      struct tty_struct *tty = state->info->tty;
++      struct uart_port *port = state->port;
++
++      if (uart_console(port) && port->cons->cflag) {
++              tty->termios->c_cflag = port->cons->cflag;
++              port->cons->cflag = 0;
++      }
++
++      /*
++       * If the device failed to grab its irq resources,
++       * or some other error occurred, don't try to talk
++       * to the port hardware.
++       */
++      if (!(tty->flags & (1 << TTY_IO_ERROR))) {
++              /*
++               * Make termios settings take effect.
++               */
++              uart_change_speed(state, NULL);
++
++              /*
++               * And finally enable the RTS and DTR signals.
++               */
++              if (tty->termios->c_cflag & CBAUD)
++                      uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
++      }
++}
++
++/*
++ * Block the open until the port is ready.  We must be called with
++ * the per-port semaphore held.
++ */
++static int
++uart_block_til_ready(struct file *filp, struct uart_state *state)
++{
++      DECLARE_WAITQUEUE(wait, current);
++      struct uart_info *info = state->info;
++      struct uart_port *port = state->port;
++
++      info->blocked_open++;
++      state->count--;
++
++      add_wait_queue(&info->open_wait, &wait);
++      while (1) {
++              set_current_state(TASK_INTERRUPTIBLE);
++
++              /*
++               * If we have been hung up, tell userspace/restart open.
++               */
++              if (tty_hung_up_p(filp) || info->tty == NULL)
++                      break;
++
++              /*
++               * If the port has been closed, tell userspace/restart open.
++               */
++              if (!(info->flags & UIF_INITIALIZED))
++                      break;
++
++              /*
++               * If non-blocking mode is set, or CLOCAL mode is set,
++               * we don't want to wait for the modem status lines to
++               * indicate that the port is ready.
++               *
++               * Also, if the port is not enabled/configured, we want
++               * to allow the open to succeed here.  Note that we will
++               * have set TTY_IO_ERROR for a non-existant port.
++               */
++              if ((filp->f_flags & O_NONBLOCK) ||
++                  (info->tty->termios->c_cflag & CLOCAL) ||
++                  (info->tty->flags & (1 << TTY_IO_ERROR))) {
++                      break;
++              }
++
++              /*
++               * Set DTR to allow modem to know we're waiting.  Do
++               * not set RTS here - we want to make sure we catch
++               * the data from the modem.
++               */
++              if (info->tty->termios->c_cflag & CBAUD)
++                      uart_set_mctrl(port, TIOCM_DTR);
++
++              /*
++               * and wait for the carrier to indicate that the
++               * modem is ready for us.
++               */
++              if (port->ops->get_mctrl(port) & TIOCM_CAR)
++                      break;
++
++              up(&state->sem);
++              schedule();
++              down(&state->sem);
++
++              if (signal_pending(current))
++                      break;
++      }
++      set_current_state(TASK_RUNNING);
++      remove_wait_queue(&info->open_wait, &wait);
++
++      state->count++;
++      info->blocked_open--;
++
++      if (signal_pending(current))
++              return -ERESTARTSYS;
++
++      if (!info->tty || tty_hung_up_p(filp))
++              return -EAGAIN;
++
++      return 0;
++}
++
++static struct uart_state *uart_get(struct uart_driver *drv, int line)
++{
++      struct uart_state *state;
++
++      down(&port_sem);
++      state = drv->state + line;
++      if (down_interruptible(&state->sem)) {
++              state = ERR_PTR(-ERESTARTSYS);
++              goto out;
++      }
++
++      state->count++;
++      if (!state->port) {
++              state->count--;
++              up(&state->sem);
++              state = ERR_PTR(-ENXIO);
++              goto out;
++      }
++
++      if (!state->info) {
++              state->info = kmalloc(sizeof(struct uart_info), GFP_KERNEL);
++              if (state->info) {
++                      memset(state->info, 0, sizeof(struct uart_info));
++                      init_waitqueue_head(&state->info->open_wait);
++                      init_waitqueue_head(&state->info->delta_msr_wait);
++
++                      /*
++                       * Link the info into the other structures.
++                       */
++                      state->port->info = state->info;
++
++                      tasklet_init(&state->info->tlet, uart_tasklet_action,
++                                   (unsigned long)state);
++              } else {
++                      state->count--;
++                      up(&state->sem);
++                      state = ERR_PTR(-ENOMEM);
++              }
++      }
++
++ out:
++      up(&port_sem);
++      return state;
++}
++
++/*
++ * In 2.4.5, calls to uart_open are serialised by the BKL in
++ *   linux/fs/devices.c:chrdev_open()
++ * Note that if this fails, then uart_close() _will_ be called.
++ *
++ * In time, we want to scrap the "opening nonpresent ports"
++ * behaviour and implement an alternative way for setserial
++ * to set base addresses/ports/types.  This will allow us to
++ * get rid of a certain amount of extra tests.
++ */
++static int uart_open(struct tty_struct *tty, struct file *filp)
++{
++      struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state;
++      struct uart_state *state;
++      int retval, line = tty->index;
++
++      BUG_ON(!kernel_locked());
++      DPRINTK("uart_open(%d) called\n", line);
++
++      /*
++       * tty->driver->num won't change, so we won't fail here with
++       * tty->driver_data set to something non-NULL (and therefore
++       * we won't get caught by uart_close()).
++       */
++      retval = -ENODEV;
++      if (line >= tty->driver->num)
++              goto fail;
++
++      /*
++       * We take the semaphore inside uart_get to guarantee that we won't
++       * be re-entered while allocating the info structure, or while we
++       * request any IRQs that the driver may need.  This also has the nice
++       * side-effect that it delays the action of uart_hangup, so we can
++       * guarantee that info->tty will always contain something reasonable.
++       */
++      state = uart_get(drv, line);
++      if (IS_ERR(state)) {
++              retval = PTR_ERR(state);
++              goto fail;
++      }
++
++      /*
++       * Once we set tty->driver_data here, we are guaranteed that
++       * uart_close() will decrement the driver module use count.
++       * Any failures from here onwards should not touch the count.
++       */
++      tty->driver_data = state;
++      tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
++      tty->alt_speed = 0;
++      state->info->tty = tty;
++
++      /*
++       * If the port is in the middle of closing, bail out now.
++       */
++      if (tty_hung_up_p(filp)) {
++              retval = -EAGAIN;
++              state->count--;
++              up(&state->sem);
++              goto fail;
++      }
++
++      /*
++       * Make sure the device is in D0 state.
++       */
++      if (state->count == 1)
++              uart_change_pm(state, 0);
++
++      /*
++       * Start up the serial port.
++       */
++      retval = uart_startup(state, 0);
++
++      /*
++       * If we succeeded, wait until the port is ready.
++       */
++      if (retval == 0)
++              retval = uart_block_til_ready(filp, state);
++      up(&state->sem);
++
++      /*
++       * If this is the first open to succeed, adjust things to suit.
++       */
++      if (retval == 0 && !(state->info->flags & UIF_NORMAL_ACTIVE)) {
++              state->info->flags |= UIF_NORMAL_ACTIVE;
++
++              uart_update_termios(state);
++      }
++
++ fail:
++      return retval;
++}
++
++static const char *uart_type(struct uart_port *port)
++{
++      const char *str = NULL;
++
++      if (port->ops->type)
++              str = port->ops->type(port);
++
++      if (!str)
++              str = "unknown";
++
++      return str;
++}
++
++#ifdef CONFIG_PROC_FS
++
++static int uart_line_info(char *buf, struct uart_driver *drv, int i)
++{
++      struct uart_state *state = drv->state + i;
++      struct uart_port *port = state->port;
++      char stat_buf[32];
++      unsigned int status;
++      int ret;
++
++      if (!port)
++              return 0;
++
++      ret = sprintf(buf, "%d: uart:%s port:%08X irq:%d",
++                      port->line, uart_type(port),
++                      port->iobase, port->irq);
++
++      if (port->type == PORT_UNKNOWN) {
++              strcat(buf, "\n");
++              return ret + 1;
++      }
++
++      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) - \
++                      strlen(stat_buf) - 2)
++#define STATBIT(bit,str) \
++      if (status & (bit)) \
++              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);
++      }
++#undef STATBIT
++#undef INFOBIT
++      return ret;
++}
++
++static int uart_read_proc(char *page, char **start, off_t off,
++                        int count, int *eof, void *data)
++{
++      struct tty_driver *ttydrv = data;
++      struct uart_driver *drv = ttydrv->driver_state;
++      int i, len = 0, l;
++      off_t begin = 0;
++
++      len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
++                      "", "", "");
++      for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) {
++              l = uart_line_info(page + len, drv, i);
++              len += l;
++              if (len + begin > off + count)
++                      goto done;
++              if (len + begin < off) {
++                      begin += len;
++                      len = 0;
++              }
++      }
++      *eof = 1;
++ done:
++      if (off >= len + begin)
++              return 0;
++      *start = page + (off - begin);
++      return (count < begin + len - off) ? count : (begin + len - off);
++}
++#endif
++
++#ifdef CONFIG_SERIAL_CORE_CONSOLE
++/*
++ *    Check whether an invalid uart number has been specified, and
++ *    if so, search for the first available port that does have
++ *    console support.
++ */
++struct uart_port * __init
++uart_get_console(struct uart_port *ports, int nr, struct console *co)
++{
++      int idx = co->index;
++
++      if (idx < 0 || idx >= nr || (ports[idx].iobase == 0 &&
++                                   ports[idx].membase == NULL))
++              for (idx = 0; idx < nr; idx++)
++                      if (ports[idx].iobase != 0 ||
++                          ports[idx].membase != NULL)
++                              break;
++
++      co->index = idx;
++
++      return ports + idx;
++}
++
++/**
++ *    uart_parse_options - Parse serial port baud/parity/bits/flow contro.
++ *    @options: pointer to option string
++ *    @baud: pointer to an 'int' variable for the baud rate.
++ *    @parity: pointer to an 'int' variable for the parity.
++ *    @bits: pointer to an 'int' variable for the number of data bits.
++ *    @flow: pointer to an 'int' variable for the flow control character.
++ *
++ *    uart_parse_options decodes a string containing the serial console
++ *    options.  The format of the string is <baud><parity><bits><flow>,
++ *    eg: 115200n8r
++ */
++void __init
++uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow)
++{
++      char *s = options;
++
++      *baud = simple_strtoul(s, NULL, 10);
++      while (*s >= '0' && *s <= '9')
++              s++;
++      if (*s)
++              *parity = *s++;
++      if (*s)
++              *bits = *s++ - '0';
++      if (*s)
++              *flow = *s;
++}
++
++struct baud_rates {
++      unsigned int rate;
++      unsigned int cflag;
++};
++
++static struct baud_rates baud_rates[] = {
++      { 921600, B921600 },
++      { 460800, B460800 },
++      { 230400, B230400 },
++      { 115200, B115200 },
++      {  57600, B57600  },
++      {  38400, B38400  },
++      {  19200, B19200  },
++      {   9600, B9600   },
++      {   4800, B4800   },
++      {   2400, B2400   },
++      {   1200, B1200   },
++      {      0, B38400  }
++};
++
++/**
++ *    uart_set_options - setup the serial console parameters
++ *    @port: pointer to the serial ports uart_port structure
++ *    @co: console pointer
++ *    @baud: baud rate
++ *    @parity: parity character - 'n' (none), 'o' (odd), 'e' (even)
++ *    @bits: number of data bits
++ *    @flow: flow control character - 'r' (rts)
++ */
++int __init
++uart_set_options(struct uart_port *port, struct console *co,
++               int baud, int parity, int bits, int flow)
++{
++      struct termios termios;
++      int i;
++
++      memset(&termios, 0, sizeof(struct termios));
++
++      termios.c_cflag = CREAD | HUPCL | CLOCAL;
++
++      /*
++       * Construct a cflag setting.
++       */
++      for (i = 0; baud_rates[i].rate; i++)
++              if (baud_rates[i].rate <= baud)
++                      break;
++
++      termios.c_cflag |= baud_rates[i].cflag;
++
++      if (bits == 7)
++              termios.c_cflag |= CS7;
++      else
++              termios.c_cflag |= CS8;
++
++      switch (parity) {
++      case 'o': case 'O':
++              termios.c_cflag |= PARODD;
++              /*fall through*/
++      case 'e': case 'E':
++              termios.c_cflag |= PARENB;
++              break;
++      }
++
++      if (flow == 'r')
++              termios.c_cflag |= CRTSCTS;
++
++      port->ops->set_termios(port, &termios, NULL);
++      co->cflag = termios.c_cflag;
++
++      return 0;
++}
++#endif /* CONFIG_SERIAL_CORE_CONSOLE */
++
++static void uart_change_pm(struct uart_state *state, int pm_state)
++{
++      struct uart_port *port = state->port;
++      if (port->ops->pm)
++              port->ops->pm(port, pm_state, state->pm_state);
++      state->pm_state = pm_state;
++}
++
++int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
++{
++      struct uart_state *state = drv->state + port->line;
++
++      down(&state->sem);
++
++      if (state->info && state->info->flags & UIF_INITIALIZED) {
++              struct uart_ops *ops = port->ops;
++
++              spin_lock_irq(&port->lock);
++              ops->stop_tx(port, 0);
++              ops->set_mctrl(port, 0);
++              ops->stop_rx(port);
++              spin_unlock_irq(&port->lock);
++
++              /*
++               * Wait for the transmitter to empty.
++               */
++              while (!ops->tx_empty(port)) {
++                      set_current_state(TASK_UNINTERRUPTIBLE);
++                      schedule_timeout(10*HZ/1000);
++              }
++              set_current_state(TASK_RUNNING);
++
++              ops->shutdown(port);
++      }
++
++      /*
++       * Disable the console device before suspending.
++       */
++      if (uart_console(port))
++              port->cons->flags &= ~CON_ENABLED;
++
++      uart_change_pm(state, 3);
++
++      up(&state->sem);
++
++      return 0;
++}
++
++int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
++{
++      struct uart_state *state = drv->state + port->line;
++
++      down(&state->sem);
++
++      uart_change_pm(state, 0);
++
++      /*
++       * Re-enable the console device after suspending.
++       */
++      if (uart_console(port)) {
++              uart_change_speed(state, NULL);
++              port->cons->flags |= CON_ENABLED;
++      }
++
++      if (state->info && state->info->flags & UIF_INITIALIZED) {
++              struct uart_ops *ops = port->ops;
++
++              ops->set_mctrl(port, 0);
++              ops->startup(port);
++              uart_change_speed(state, NULL);
++              spin_lock_irq(&port->lock);
++              ops->set_mctrl(port, port->mctrl);
++              ops->start_tx(port, 0);
++              spin_unlock_irq(&port->lock);
++      }
++
++      up(&state->sem);
++
++      return 0;
++}
++
++static inline void
++uart_report_port(struct uart_driver *drv, struct uart_port *port)
++{
++      printk("%s%d", drv->dev_name, port->line);
++      printk(" at ");
++      switch (port->iotype) {
++      case UPIO_PORT:
++              printk("I/O 0x%x", port->iobase);
++              break;
++      case UPIO_HUB6:
++              printk("I/O 0x%x offset 0x%x", port->iobase, port->hub6);
++              break;
++      case UPIO_MEM:
++              printk("MMIO 0x%lx", port->mapbase);
++              break;
++      }
++      printk(" (irq = %d) is a %s\n", port->irq, uart_type(port));
++}
++
++static void
++uart_configure_port(struct uart_driver *drv, struct uart_state *state,
++                  struct uart_port *port)
++{
++      unsigned int flags;
++
++#ifdef CONFIG_KGDB
++      if (port->kgdb)
++              return;
++#endif
++
++      /*
++       * If there isn't a port here, don't do anything further.
++       */
++      if (!port->iobase && !port->mapbase && !port->membase)
++              return;
++
++      /*
++       * Now do the auto configuration stuff.  Note that config_port
++       * is expected to claim the resources and map the port for us.
++       */
++      flags = UART_CONFIG_TYPE;
++      if (port->flags & UPF_AUTO_IRQ)
++              flags |= UART_CONFIG_IRQ;
++      if (port->flags & UPF_BOOT_AUTOCONF) {
++              port->type = PORT_UNKNOWN;
++              port->ops->config_port(port, flags);
++      }
++
++      if (port->type != PORT_UNKNOWN) {
++              unsigned long flags;
++
++              uart_report_port(drv, port);
++
++              /*
++               * Ensure that the modem control lines are de-activated.
++               * We probably don't need a spinlock around this, but
++               */
++              spin_lock_irqsave(&port->lock, flags);
++              port->ops->set_mctrl(port, 0);
++              spin_unlock_irqrestore(&port->lock, flags);
++
++              /*
++               * Power down all ports by default, except the
++               * console if we have one.
++               */
++              if (!uart_console(port))
++                      uart_change_pm(state, 3);
++      }
++}
++
++/*
++ * This reverses the effects of uart_configure_port, hanging up the
++ * port before removal.
++ */
++static void
++uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state)
++{
++      struct uart_port *port = state->port;
++      struct uart_info *info = state->info;
++
++      if (info && info->tty)
++              tty_vhangup(info->tty);
++
++      down(&state->sem);
++
++      state->info = NULL;
++
++      /*
++       * Free the port IO and memory resources, if any.
++       */
++      if (port->type != PORT_UNKNOWN)
++              port->ops->release_port(port);
++
++      /*
++       * Indicate that there isn't a port here anymore.
++       */
++      port->type = PORT_UNKNOWN;
++
++      /*
++       * Kill the tasklet, and free resources.
++       */
++      if (info) {
++              tasklet_kill(&info->tlet);
++              kfree(info);
++      }
++
++      up(&state->sem);
++}
++
++static struct tty_operations uart_ops = {
++      .open           = uart_open,
++      .close          = uart_close,
++      .write          = uart_write,
++      .put_char       = uart_put_char,
++      .flush_chars    = uart_flush_chars,
++      .write_room     = uart_write_room,
++      .chars_in_buffer= uart_chars_in_buffer,
++      .flush_buffer   = uart_flush_buffer,
++      .ioctl          = uart_ioctl,
++      .throttle       = uart_throttle,
++      .unthrottle     = uart_unthrottle,
++      .send_xchar     = uart_send_xchar,
++      .set_termios    = uart_set_termios,
++      .stop           = uart_stop,
++      .start          = uart_start,
++      .hangup         = uart_hangup,
++      .break_ctl      = uart_break_ctl,
++      .wait_until_sent= uart_wait_until_sent,
++#ifdef CONFIG_PROC_FS
++      .read_proc      = uart_read_proc,
++#endif
++      .tiocmget       = uart_tiocmget,
++      .tiocmset       = uart_tiocmset,
++};
++
++/**
++ *    uart_register_driver - register a driver with the uart core layer
++ *    @drv: low level driver structure
++ *
++ *    Register a uart driver with the core driver.  We in turn register
++ *    with the tty layer, and initialise the core driver per-port state.
++ *
++ *    We have a proc file in /proc/tty/driver which is named after the
++ *    normal driver.
++ *
++ *    drv->port should be NULL, and the per-port structures should be
++ *    registered using uart_add_one_port after this call has succeeded.
++ */
++int uart_register_driver(struct uart_driver *drv)
++{
++      struct tty_driver *normal = NULL;
++      int i, retval;
++
++      BUG_ON(drv->state);
++
++      /*
++       * Maybe we should be using a slab cache for this, especially if
++       * we have a large number of ports to handle.
++       */
++      drv->state = kmalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);
++      retval = -ENOMEM;
++      if (!drv->state)
++              goto out;
++
++      memset(drv->state, 0, sizeof(struct uart_state) * drv->nr);
++
++      normal  = alloc_tty_driver(drv->nr);
++      if (!normal)
++              goto out;
++
++      drv->tty_driver = normal;
++
++      normal->owner           = drv->owner;
++      normal->driver_name     = drv->driver_name;
++      normal->devfs_name      = drv->devfs_name;
++      normal->name            = drv->dev_name;
++      normal->major           = drv->major;
++      normal->minor_start     = drv->minor;
++      normal->type            = TTY_DRIVER_TYPE_SERIAL;
++      normal->subtype         = SERIAL_TYPE_NORMAL;
++      normal->init_termios    = tty_std_termios;
++      normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++      normal->flags           = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
++      normal->driver_state    = drv;
++      tty_set_operations(normal, &uart_ops);
++
++      /*
++       * Initialise the UART state(s).
++       */
++      for (i = 0; i < drv->nr; i++) {
++              struct uart_state *state = drv->state + i;
++
++              state->close_delay     = 5 * HZ / 10;
++              state->closing_wait    = 30 * HZ;
++
++              init_MUTEX(&state->sem);
++      }
++
++      retval = tty_register_driver(normal);
++ out:
++      if (retval < 0) {
++              put_tty_driver(normal);
++              kfree(drv->state);
++      }
++      return retval;
++}
++
++/**
++ *    uart_unregister_driver - remove a driver from the uart core layer
++ *    @drv: low level driver structure
++ *
++ *    Remove all references to a driver from the core driver.  The low
++ *    level driver must have removed all its ports via the
++ *    uart_remove_one_port() if it registered them with uart_add_one_port().
++ *    (ie, drv->port == NULL)
++ */
++void uart_unregister_driver(struct uart_driver *drv)
++{
++      struct tty_driver *p = drv->tty_driver;
++      tty_unregister_driver(p);
++      put_tty_driver(p);
++      kfree(drv->state);
++      drv->tty_driver = NULL;
++}
++
++struct tty_driver *uart_console_device(struct console *co, int *index)
++{
++      struct uart_driver *p = co->data;
++      *index = co->index;
++      return p->tty_driver;
++}
++
++/**
++ *    uart_add_one_port - attach a driver-defined port structure
++ *    @drv: pointer to the uart low level driver structure for this port
++ *    @port: uart port structure to use for this port.
++ *
++ *    This allows the driver to register its own uart_port structure
++ *    with the core driver.  The main purpose is to allow the low
++ *    level uart drivers to expand uart_port, rather than having yet
++ *    more levels of structures.
++ */
++int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
++{
++      struct uart_state *state;
++      int ret = 0;
++
++      BUG_ON(in_interrupt());
++
++      if (port->line >= drv->nr)
++              return -EINVAL;
++
++      state = drv->state + port->line;
++
++      down(&port_sem);
++      if (state->port) {
++              ret = -EINVAL;
++              goto out;
++      }
++
++      state->port = port;
++
++      spin_lock_init(&port->lock);
++      port->cons = drv->cons;
++      port->info = state->info;
++
++      uart_configure_port(drv, state, port);
++
++      /*
++       * Register the port whether it's detected or not.  This allows
++       * setserial to be used to alter this ports parameters.
++       */
++      tty_register_device(drv->tty_driver, port->line, NULL);
++
++ out:
++      up(&port_sem);
++
++      return ret;
++}
++
++/**
++ *    uart_remove_one_port - detach a driver defined port structure
++ *    @drv: pointer to the uart low level driver structure for this port
++ *    @port: uart port structure for this port
++ *
++ *    This unhooks (and hangs up) the specified port structure from the
++ *    core driver.  No further calls will be made to the low-level code
++ *    for this port.
++ */
++int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
++{
++      struct uart_state *state = drv->state + port->line;
++
++      BUG_ON(in_interrupt());
++
++      if (state->port != port)
++              printk(KERN_ALERT "Removing wrong port: %p != %p\n",
++                      state->port, port);
++
++      down(&port_sem);
++
++      /*
++       * Remove the devices from devfs
++       */
++      tty_unregister_device(drv->tty_driver, port->line);
++
++      uart_unconfigure_port(drv, state);
++      state->port = NULL;
++      up(&port_sem);
++
++      return 0;
++}
++
++/*
++ *    Are the two ports equivalent?
++ */
++static int uart_match_port(struct uart_port *port1, struct uart_port *port2)
++{
++      if (port1->iotype != port2->iotype)
++              return 0;
++
++      switch (port1->iotype) {
++      case UPIO_PORT:
++              return (port1->iobase == port2->iobase);
++      case UPIO_HUB6:
++              return (port1->iobase == port2->iobase) &&
++                     (port1->hub6   == port2->hub6);
++      case UPIO_MEM:
++              return (port1->membase == port2->membase);
++      }
++      return 0;
++}
++
++/*
++ *    Try to find an unused uart_state slot for a port.
++ */
++static struct uart_state *
++uart_find_match_or_unused(struct uart_driver *drv, struct uart_port *port)
++{
++      int i;
++
++      /*
++       * First, find a port entry which matches.  Note: if we do
++       * find a matching entry, and it has a non-zero use count,
++       * then we can't register the port.
++       */
++      for (i = 0; i < drv->nr; i++)
++              if (uart_match_port(drv->state[i].port, port))
++                      return &drv->state[i];
++
++      /*
++       * We didn't find a matching entry, so look for the first
++       * free entry.  We look for one which hasn't been previously
++       * used (indicated by zero iobase).
++       */
++      for (i = 0; i < drv->nr; i++)
++              if (drv->state[i].port->type == PORT_UNKNOWN &&
++                  drv->state[i].port->iobase == 0 &&
++                  drv->state[i].count == 0)
++                      return &drv->state[i];
++
++      /*
++       * That also failed.  Last resort is to find any currently
++       * entry which doesn't have a real port associated with it.
++       */
++      for (i = 0; i < drv->nr; i++)
++              if (drv->state[i].port->type == PORT_UNKNOWN &&
++                  drv->state[i].count == 0)
++                      return &drv->state[i];
++
++      return NULL;
++}
++
++/**
++ *    uart_register_port: register uart settings with a port
++ *    @drv: pointer to the uart low level driver structure for this port
++ *    @port: uart port structure describing the port
++ *
++ *    Register UART settings with the specified low level driver.  Detect
++ *    the type of the port if UPF_BOOT_AUTOCONF is set, and detect the
++ *    IRQ if UPF_AUTO_IRQ is set.
++ *
++ *    We try to pick the same port for the same IO base address, so that
++ *    when a modem is plugged in, unplugged and plugged back in, it gets
++ *    allocated the same port.
++ *
++ *    Returns negative error, or positive line number.
++ */
++int uart_register_port(struct uart_driver *drv, struct uart_port *port)
++{
++      struct uart_state *state;
++      int ret;
++
++      down(&port_sem);
++
++      state = uart_find_match_or_unused(drv, port);
++
++      if (state) {
++              /*
++               * Ok, we've found a line that we can use.
++               *
++               * If we find a port that matches this one, and it appears
++               * to be in-use (even if it doesn't have a type) we shouldn't
++               * alter it underneath itself - the port may be open and
++               * trying to do useful work.
++               */
++              if (uart_users(state) != 0) {
++                      ret = -EBUSY;
++                      goto out;
++              }
++
++              /*
++               * If the port is already initialised, don't touch it.
++               */
++              if (state->port->type == PORT_UNKNOWN) {
++                      state->port->iobase   = port->iobase;
++                      state->port->membase  = port->membase;
++                      state->port->irq      = port->irq;
++                      state->port->uartclk  = port->uartclk;
++                      state->port->fifosize = port->fifosize;
++                      state->port->regshift = port->regshift;
++                      state->port->iotype   = port->iotype;
++                      state->port->flags    = port->flags;
++                      state->port->line     = state - drv->state;
++                      state->port->mapbase  = port->mapbase;
++
++                      uart_configure_port(drv, state, state->port);
++              }
++
++              ret = state->port->line;
++      } else
++              ret = -ENOSPC;
++ out:
++      up(&port_sem);
++      return ret;
++}
++
++/**
++ *    uart_unregister_port - de-allocate a port
++ *    @drv: pointer to the uart low level driver structure for this port
++ *    @line: line index previously returned from uart_register_port()
++ *
++ *    Hang up the specified line associated with the low level driver,
++ *    and mark the port as unused.
++ */
++void uart_unregister_port(struct uart_driver *drv, int line)
++{
++      struct uart_state *state;
++
++      if (line < 0 || line >= drv->nr) {
++              printk(KERN_ERR "Attempt to unregister ");
++              printk("%s%d", drv->dev_name, line);
++              printk("\n");
++              return;
++      }
++
++      state = drv->state + line;
++
++      down(&port_sem);
++      uart_unconfigure_port(drv, state);
++      up(&port_sem);
++}
++
++EXPORT_SYMBOL(uart_write_wakeup);
++EXPORT_SYMBOL(uart_register_driver);
++EXPORT_SYMBOL(uart_unregister_driver);
++EXPORT_SYMBOL(uart_suspend_port);
++EXPORT_SYMBOL(uart_resume_port);
++EXPORT_SYMBOL(uart_register_port);
++EXPORT_SYMBOL(uart_unregister_port);
++EXPORT_SYMBOL(uart_add_one_port);
++EXPORT_SYMBOL(uart_remove_one_port);
++
++MODULE_DESCRIPTION("Serial driver core");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/serial/serial_cs.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/serial/serial_cs.c  2003-09-27 11:38:18.463721472 +0800
++++ linux-2.6.0-test5/drivers/serial/serial_cs.c       2003-09-27 11:38:32.173637248 +0800
+@@ -0,0 +1,712 @@
++/*======================================================================
++
++    A driver for PCMCIA serial devices
++
++    serial_cs.c 1.134 2002/05/04 05:48:53
++
++    The contents of this file are subject to the Mozilla Public
++    License Version 1.1 (the "License"); you may not use this file
++    except in compliance with the License. You may obtain a copy of
++    the License at http://www.mozilla.org/MPL/
++
++    Software distributed under the License is distributed on an "AS
++    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++    implied. See the License for the specific language governing
++    rights and limitations under the License.
++
++    The initial developer of the original code is David A. Hinds
++    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
++    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
++
++    Alternatively, the contents of this file may be used under the
++    terms of the GNU General Public License version 2 (the "GPL"), in which
++    case the provisions of the GPL are applicable instead of the
++    above.  If you wish to allow the use of your version of this file
++    only under the terms of the GPL and not to allow others to use
++    your version of this file under the MPL, indicate your decision
++    by deleting the provisions above and replace them with the notice
++    and other provisions required by the GPL.  If you do not delete
++    the provisions above, a recipient may use your version of this
++    file under either the MPL or the GPL.
++    
++======================================================================*/
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#include <linux/major.h>
++#include <asm/io.h>
++#include <asm/system.h>
++
++#include <pcmcia/version.h>
++#include <pcmcia/cs_types.h>
++#include <pcmcia/cs.h>
++#include <pcmcia/cistpl.h>
++#include <pcmcia/ciscode.h>
++#include <pcmcia/ds.h>
++#include <pcmcia/cisreg.h>
++
++#ifdef PCMCIA_DEBUG
++static int pc_debug = PCMCIA_DEBUG;
++MODULE_PARM(pc_debug, "i");
++#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
++static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
++#else
++#define DEBUG(n, args...)
++#endif
++
++/*====================================================================*/
++
++/* Parameters that can be set with 'insmod' */
++
++/* Bit map of interrupts to choose from */
++static u_int irq_mask = 0xdeb8;
++static int irq_list[4] = { -1 };
++
++/* Enable the speaker? */
++static int do_sound = 1;
++/* Skip strict UART tests? */
++static int buggy_uart;
++
++MODULE_PARM(irq_mask, "i");
++MODULE_PARM(irq_list, "1-4i");
++MODULE_PARM(do_sound, "i");
++MODULE_PARM(buggy_uart, "i");
++
++/*====================================================================*/
++
++/* Table of multi-port card ID's */
++
++struct multi_id {
++      u_short manfid;
++      u_short prodid;
++      int multi;              /* 1 = multifunction, > 1 = # ports */
++};
++
++static struct multi_id multi_id[] = {
++      { MANFID_OMEGA,   PRODID_OMEGA_QSP_100,         4 },
++      { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232,    2 },
++      { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
++      { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232,    4 },
++      { MANFID_SOCKET,  PRODID_SOCKET_DUAL_RS232,     2 },
++      { MANFID_INTEL,   PRODID_INTEL_DUAL_RS232,      2 },
++      { MANFID_NATINST, PRODID_NATINST_QUAD_RS232,    4 }
++};
++#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
++
++struct serial_info {
++      dev_link_t              link;
++      int                     ndev;
++      int                     multi;
++      int                     slave;
++      int                     manfid;
++      dev_node_t              node[4];
++      int                     line[4];
++};
++
++static void serial_config(dev_link_t * link);
++static int serial_event(event_t event, int priority,
++                      event_callback_args_t * args);
++
++static dev_info_t dev_info = "serial_cs";
++
++static dev_link_t *serial_attach(void);
++static void serial_detach(dev_link_t *);
++
++static dev_link_t *dev_list = NULL;
++
++/*======================================================================
++
++    After a card is removed, serial_remove() will unregister
++    the serial device(s), and release the PCMCIA configuration.
++    
++======================================================================*/
++
++static void serial_remove(dev_link_t *link)
++{
++      struct serial_info *info = link->priv;
++      int i;
++
++      link->state &= ~DEV_PRESENT;
++
++      DEBUG(0, "serial_release(0x%p)\n", link);
++
++      /*
++       * Recheck to see if the device is still configured.
++       */
++      if (info->link.state & DEV_CONFIG) {
++              for (i = 0; i < info->ndev; i++)
++                      unregister_serial(info->line[i]);
++
++              info->link.dev = NULL;
++
++              if (!info->slave) {
++                      CardServices(ReleaseConfiguration, info->link.handle);
++                      CardServices(ReleaseIO, info->link.handle, &info->link.io);
++                      CardServices(ReleaseIRQ, info->link.handle, &info->link.irq);
++              }
++
++              info->link.state &= ~DEV_CONFIG;
++      }
++}
++
++/*======================================================================
++
++    serial_attach() creates an "instance" of the driver, allocating
++    local data structures for one device.  The device is registered
++    with Card Services.
++
++======================================================================*/
++
++static dev_link_t *serial_attach(void)
++{
++      struct serial_info *info;
++      client_reg_t client_reg;
++      dev_link_t *link;
++      int i, ret;
++
++      DEBUG(0, "serial_attach()\n");
++
++      /* Create new serial device */
++      info = kmalloc(sizeof (*info), GFP_KERNEL);
++      if (!info)
++              return NULL;
++      memset(info, 0, sizeof (*info));
++      link = &info->link;
++      link->priv = info;
++
++      link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
++      link->io.NumPorts1 = 8;
++      link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
++      link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
++      if (irq_list[0] == -1)
++              link->irq.IRQInfo2 = irq_mask;
++      else
++              for (i = 0; i < 4; i++)
++                      link->irq.IRQInfo2 |= 1 << irq_list[i];
++      link->conf.Attributes = CONF_ENABLE_IRQ;
++      if (do_sound) {
++              link->conf.Attributes |= CONF_ENABLE_SPKR;
++              link->conf.Status = CCSR_AUDIO_ENA;
++      }
++      link->conf.IntType = INT_MEMORY_AND_IO;
++
++      /* Register with Card Services */
++      link->next = dev_list;
++      dev_list = link;
++      client_reg.dev_info = &dev_info;
++      client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
++      client_reg.EventMask =
++          CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
++          CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
++          CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
++      client_reg.event_handler = &serial_event;
++      client_reg.Version = 0x0210;
++      client_reg.event_callback_args.client_data = link;
++      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      if (ret != CS_SUCCESS) {
++              cs_error(link->handle, RegisterClient, ret);
++              serial_detach(link);
++              return NULL;
++      }
++
++      return link;
++}
++
++/*======================================================================
++
++    This deletes a driver "instance".  The device is de-registered
++    with Card Services.  If it has been released, all local data
++    structures are freed.  Otherwise, the structures will be freed
++    when the device is released.
++
++======================================================================*/
++
++static void serial_detach(dev_link_t * link)
++{
++      struct serial_info *info = link->priv;
++      dev_link_t **linkp;
++      int ret;
++
++      DEBUG(0, "serial_detach(0x%p)\n", link);
++
++      /* Locate device structure */
++      for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
++              if (*linkp == link)
++                      break;
++      if (*linkp == NULL)
++              return;
++
++      /*
++       * Ensure any outstanding scheduled tasks are completed.
++       */
++      flush_scheduled_work();
++
++      /*
++       * Ensure that the ports have been released.
++       */
++      serial_remove(link);
++
++      if (link->handle) {
++              ret = CardServices(DeregisterClient, link->handle);
++              if (ret != CS_SUCCESS)
++                      cs_error(link->handle, DeregisterClient, ret);
++      }
++
++      /* Unlink device structure, free bits */
++      *linkp = link->next;
++      kfree(info);
++}
++
++/*====================================================================*/
++
++static int setup_serial(struct serial_info * info, ioaddr_t port, int irq)
++{
++      struct serial_struct serial;
++      int line;
++
++      memset(&serial, 0, sizeof (serial));
++      serial.port = port;
++      serial.irq = irq;
++      serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ;
++      if (buggy_uart)
++              serial.flags |= UPF_BUGGY_UART;
++      line = register_serial(&serial);
++      if (line < 0) {
++              printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
++                     " irq %d failed\n", (u_long) serial.port, serial.irq);
++              return -EINVAL;
++      }
++
++      info->line[info->ndev] = line;
++      sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
++      info->node[info->ndev].major = TTY_MAJOR;
++      info->node[info->ndev].minor = 0x40 + line;
++      if (info->ndev > 0)
++              info->node[info->ndev - 1].next = &info->node[info->ndev];
++      info->ndev++;
++
++      return 0;
++}
++
++/*====================================================================*/
++
++static int
++get_tuple(int fn, client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
++{
++      int i;
++      i = CardServices(fn, handle, tuple);
++      if (i != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      i = CardServices(GetTupleData, handle, tuple);
++      if (i != CS_SUCCESS)
++              return i;
++      return CardServices(ParseTuple, handle, tuple, parse);
++}
++
++#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
++#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++
++/*====================================================================*/
++
++static int simple_config(dev_link_t * link)
++{
++      static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
++      client_handle_t handle = link->handle;
++      struct serial_info *info = link->priv;
++      tuple_t tuple;
++      u_char buf[256];
++      cisparse_t parse;
++      cistpl_cftable_entry_t *cf = &parse.cftable_entry;
++      config_info_t config;
++      int i, j, try;
++
++      /* If the card is already configured, look up the port and irq */
++      i = CardServices(GetConfigurationInfo, handle, &config);
++      if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
++              ioaddr_t port = 0;
++              if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
++                      port = config.BasePort2;
++                      info->slave = 1;
++              } else if ((info->manfid == MANFID_OSITECH) &&
++                         (config.NumPorts1 == 0x40)) {
++                      port = config.BasePort1 + 0x28;
++                      info->slave = 1;
++              }
++              if (info->slave)
++                      return setup_serial(info, port, config.AssignedIRQ);
++      }
++      link->conf.Vcc = config.Vcc;
++
++      /* First pass: look for a config entry that looks normal. */
++      tuple.TupleData = (cisdata_t *) buf;
++      tuple.TupleOffset = 0;
++      tuple.TupleDataMax = 255;
++      tuple.Attributes = 0;
++      tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
++      /* Two tries: without IO aliases, then with aliases */
++      for (try = 0; try < 2; try++) {
++              i = first_tuple(handle, &tuple, &parse);
++              while (i != CS_NO_MORE_ITEMS) {
++                      if (i != CS_SUCCESS)
++                              goto next_entry;
++                      if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
++                              link->conf.Vpp1 = link->conf.Vpp2 =
++                                  cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
++                      if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
++                          (cf->io.win[0].base != 0)) {
++                              link->conf.ConfigIndex = cf->index;
++                              link->io.BasePort1 = cf->io.win[0].base;
++                              link->io.IOAddrLines = (try == 0) ?
++                                  16 : cf->io.flags & CISTPL_IO_LINES_MASK;
++                              i =
++                                  CardServices(RequestIO, link->handle,
++                                               &link->io);
++                              if (i == CS_SUCCESS)
++                                      goto found_port;
++                      }
++                    next_entry:
++                      i = next_tuple(handle, &tuple, &parse);
++              }
++      }
++
++      /* Second pass: try to find an entry that isn't picky about
++         its base address, then try to grab any standard serial port
++         address, and finally try to get any free port. */
++      i = first_tuple(handle, &tuple, &parse);
++      while (i != CS_NO_MORE_ITEMS) {
++              if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
++                  ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
++                      link->conf.ConfigIndex = cf->index;
++                      for (j = 0; j < 5; j++) {
++                              link->io.BasePort1 = base[j];
++                              link->io.IOAddrLines = base[j] ? 16 : 3;
++                              i = CardServices(RequestIO, link->handle,
++                                               &link->io);
++                              if (i == CS_SUCCESS)
++                                      goto found_port;
++                      }
++              }
++              i = next_tuple(handle, &tuple, &parse);
++      }
++
++      found_port:
++      if (i != CS_SUCCESS) {
++              printk(KERN_NOTICE
++                     "serial_cs: no usable port range found, giving up\n");
++              cs_error(link->handle, RequestIO, i);
++              return -1;
++      }
++
++      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      if (i != CS_SUCCESS) {
++              cs_error(link->handle, RequestIRQ, i);
++              link->irq.AssignedIRQ = 0;
++      }
++      if (info->multi && (info->manfid == MANFID_3COM))
++              link->conf.ConfigIndex &= ~(0x08);
++      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      if (i != CS_SUCCESS) {
++              cs_error(link->handle, RequestConfiguration, i);
++              return -1;
++      }
++
++      return setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
++}
++
++static int multi_config(dev_link_t * link)
++{
++      client_handle_t handle = link->handle;
++      struct serial_info *info = link->priv;
++      tuple_t tuple;
++      u_char buf[256];
++      cisparse_t parse;
++      cistpl_cftable_entry_t *cf = &parse.cftable_entry;
++      config_info_t config;
++      int i, base2 = 0;
++
++      i = CardServices(GetConfigurationInfo, handle, &config);
++      if (i != CS_SUCCESS) {
++              cs_error(handle, GetConfigurationInfo, i);
++              return -1;
++      }
++      link->conf.Vcc = config.Vcc;
++
++      tuple.TupleData = (cisdata_t *) buf;
++      tuple.TupleOffset = 0;
++      tuple.TupleDataMax = 255;
++      tuple.Attributes = 0;
++      tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
++
++      /* First, look for a generic full-sized window */
++      link->io.NumPorts1 = info->multi * 8;
++      i = first_tuple(handle, &tuple, &parse);
++      while (i != CS_NO_MORE_ITEMS) {
++              /* The quad port cards have bad CIS's, so just look for a
++                 window larger than 8 ports and assume it will be right */
++              if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
++                  (cf->io.win[0].len > 8)) {
++                      link->conf.ConfigIndex = cf->index;
++                      link->io.BasePort1 = cf->io.win[0].base;
++                      link->io.IOAddrLines =
++                          cf->io.flags & CISTPL_IO_LINES_MASK;
++                      i = CardServices(RequestIO, link->handle, &link->io);
++                      base2 = link->io.BasePort1 + 8;
++                      if (i == CS_SUCCESS)
++                              break;
++              }
++              i = next_tuple(handle, &tuple, &parse);
++      }
++
++      /* If that didn't work, look for two windows */
++      if (i != CS_SUCCESS) {
++              link->io.NumPorts1 = link->io.NumPorts2 = 8;
++              info->multi = 2;
++              i = first_tuple(handle, &tuple, &parse);
++              while (i != CS_NO_MORE_ITEMS) {
++                      if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
++                              link->conf.ConfigIndex = cf->index;
++                              link->io.BasePort1 = cf->io.win[0].base;
++                              link->io.BasePort2 = cf->io.win[1].base;
++                              link->io.IOAddrLines =
++                                  cf->io.flags & CISTPL_IO_LINES_MASK;
++                              i =
++                                  CardServices(RequestIO, link->handle,
++                                               &link->io);
++                              base2 = link->io.BasePort2;
++                              if (i == CS_SUCCESS)
++                                      break;
++                      }
++                      i = next_tuple(handle, &tuple, &parse);
++              }
++      }
++
++      if (i != CS_SUCCESS) {
++              cs_error(link->handle, RequestIO, i);
++              return -1;
++      }
++
++      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      if (i != CS_SUCCESS) {
++              printk(KERN_NOTICE
++                     "serial_cs: no usable port range found, giving up\n");
++              cs_error(link->handle, RequestIRQ, i);
++              link->irq.AssignedIRQ = 0;
++      }
++      /* Socket Dual IO: this enables irq's for second port */
++      if (info->multi && (info->manfid == MANFID_SOCKET)) {
++              link->conf.Present |= PRESENT_EXT_STATUS;
++              link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
++      }
++      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      if (i != CS_SUCCESS) {
++              cs_error(link->handle, RequestConfiguration, i);
++              return -1;
++      }
++
++      /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
++         8 registers are for the UART, the others are extra registers */
++      if (info->manfid == MANFID_OXSEMI) {
++              if (cf->index == 1 || cf->index == 3) {
++                      setup_serial(info, base2, link->irq.AssignedIRQ);
++                      outb(12, link->io.BasePort1 + 1);
++              } else {
++                      setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
++                      outb(12, base2 + 1);
++              }
++              return 0;
++      }
++
++      setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
++      /* The Nokia cards are not really multiport cards */
++      if (info->manfid == MANFID_NOKIA)
++              return 0;
++      for (i = 0; i < info->multi - 1; i++)
++              setup_serial(info, base2 + (8 * i), link->irq.AssignedIRQ);
++
++      return 0;
++}
++
++/*======================================================================
++
++    serial_config() is scheduled to run after a CARD_INSERTION event
++    is received, to configure the PCMCIA socket, and to make the
++    serial device available to the system.
++
++======================================================================*/
++
++#define CS_CHECK(fn, args...) \
++while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++
++void serial_config(dev_link_t * link)
++{
++      client_handle_t handle = link->handle;
++      struct serial_info *info = link->priv;
++      tuple_t tuple;
++      u_short buf[128];
++      cisparse_t parse;
++      cistpl_cftable_entry_t *cf = &parse.cftable_entry;
++      int i, last_ret, last_fn;
++
++      DEBUG(0, "serial_config(0x%p)\n", link);
++
++      tuple.TupleData = (cisdata_t *) buf;
++      tuple.TupleOffset = 0;
++      tuple.TupleDataMax = 255;
++      tuple.Attributes = 0;
++      /* Get configuration register information */
++      tuple.DesiredTuple = CISTPL_CONFIG;
++      last_ret = first_tuple(handle, &tuple, &parse);
++      if (last_ret != CS_SUCCESS) {
++              last_fn = ParseTuple;
++              goto cs_failed;
++      }
++      link->conf.ConfigBase = parse.config.base;
++      link->conf.Present = parse.config.rmask[0];
++
++      /* Configure card */
++      link->state |= DEV_CONFIG;
++
++      /* Is this a compliant multifunction card? */
++      tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
++      tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
++      info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
++
++      /* Is this a multiport card? */
++      tuple.DesiredTuple = CISTPL_MANFID;
++      if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
++              info->manfid = le16_to_cpu(buf[0]);
++              for (i = 0; i < MULTI_COUNT; i++)
++                      if ((info->manfid == multi_id[i].manfid) &&
++                          (le16_to_cpu(buf[1]) == multi_id[i].prodid))
++                              break;
++              if (i < MULTI_COUNT)
++                      info->multi = multi_id[i].multi;
++      }
++
++      /* Another check for dual-serial cards: look for either serial or
++         multifunction cards that ask for appropriate IO port ranges */
++      tuple.DesiredTuple = CISTPL_FUNCID;
++      if ((info->multi == 0) &&
++          ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ||
++           (parse.funcid.func == CISTPL_FUNCID_MULTI) ||
++           (parse.funcid.func == CISTPL_FUNCID_SERIAL))) {
++              tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
++              if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
++                      if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
++                              info->multi = cf->io.win[0].len >> 3;
++                      if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
++                          (cf->io.win[1].len == 8))
++                              info->multi = 2;
++              }
++      }
++
++      if (info->multi > 1)
++              multi_config(link);
++      else
++              simple_config(link);
++
++      if (info->ndev == 0)
++              goto failed;
++
++      if (info->manfid == MANFID_IBM) {
++              conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
++              CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
++              reg.Action = CS_WRITE;
++              reg.Value = reg.Value | 1;
++              CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
++      }
++
++      link->dev = &info->node[0];
++      link->state &= ~DEV_CONFIG_PENDING;
++      return;
++
++ cs_failed:
++      cs_error(link->handle, last_fn, last_ret);
++ failed:
++      serial_remove(link);
++      link->state &= ~DEV_CONFIG_PENDING;
++}
++
++/*======================================================================
++
++    The card status event handler.  Mostly, this schedules other
++    stuff to run after an event is received.  A CARD_REMOVAL event
++    also sets some flags to discourage the serial drivers from
++    talking to the ports.
++    
++======================================================================*/
++
++static int
++serial_event(event_t event, int priority, event_callback_args_t * args)
++{
++      dev_link_t *link = args->client_data;
++      struct serial_info *info = link->priv;
++
++      DEBUG(1, "serial_event(0x%06x)\n", event);
++
++      switch (event) {
++      case CS_EVENT_CARD_REMOVAL:
++              serial_remove(link);
++              break;
++
++      case CS_EVENT_CARD_INSERTION:
++              link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
++              serial_config(link);
++              break;
++
++      case CS_EVENT_PM_SUSPEND:
++              link->state |= DEV_SUSPEND;
++              /* Fall through... */
++      case CS_EVENT_RESET_PHYSICAL:
++              if ((link->state & DEV_CONFIG) && !info->slave)
++                      CardServices(ReleaseConfiguration, link->handle);
++              break;
++
++      case CS_EVENT_PM_RESUME:
++              link->state &= ~DEV_SUSPEND;
++              /* Fall through... */
++      case CS_EVENT_CARD_RESET:
++              if (DEV_OK(link) && !info->slave)
++                      CardServices(RequestConfiguration, link->handle,
++                                   &link->conf);
++              break;
++      }
++      return 0;
++}
++
++static struct pcmcia_driver serial_cs_driver = {
++      .owner          = THIS_MODULE,
++      .drv            = {
++              .name   = "serial_cs",
++      },
++      .attach         = serial_attach,
++      .detach         = serial_detach,
++};
++
++static int __init init_serial_cs(void)
++{
++      return pcmcia_register_driver(&serial_cs_driver);
++}
++
++static void __exit exit_serial_cs(void)
++{
++      pcmcia_unregister_driver(&serial_cs_driver);
++
++      /* XXX: this really needs to move into generic code.. */
++      while (dev_list != NULL)
++              serial_detach(dev_list);
++}
++
++module_init(init_serial_cs);
++module_exit(exit_serial_cs);
++
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/drivers/usb/class/usblp.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/class/usblp.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/class/usblp.c        2003-09-27 11:38:32.231628432 +0800
+@@ -159,7 +159,10 @@
+       dbg("usblp=0x%p", usblp);
+       dbg("dev=0x%p", usblp->dev);
+       dbg("present=%d", usblp->present);
+-      dbg("buf=0x%p", usblp->buf);
++      dbg("readbuf=0x%p", usblp->readbuf);
++      dbg("writebuf=0x%p", usblp->writebuf);
++      dbg("readurb=0x%p", usblp->readurb);
++      dbg("writeurb=0x%p", usblp->writeurb);
+       dbg("readcount=%d", usblp->readcount);
+       dbg("ifnum=%d", usblp->ifnum);
+     for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
+Index: linux-2.6.0-test5/drivers/usb/core/config.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/core/config.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/core/config.c        2003-09-27 11:38:32.275621744 +0800
+@@ -10,364 +10,329 @@
+ /* these maximums are arbitrary */
+ #define USB_MAXCONFIG                 8
+-#define USB_ALTSETTINGALLOC           4
+ #define USB_MAXINTERFACES             32
+ static int usb_parse_endpoint(struct usb_host_endpoint *endpoint, unsigned char *buffer, int size)
+ {
++      unsigned char *buffer0 = buffer;
+       struct usb_descriptor_header *header;
+       unsigned char *begin;
+-      int parsed = 0, len, numskipped;
++      int numskipped;
+       header = (struct usb_descriptor_header *)buffer;
+-
+-      /* Everything should be fine being passed into here, but we sanity */
+-      /*  check JIC */
+-      if (header->bLength > size) {
+-              err("ran out of descriptors parsing");
+-              return -1;
+-      }
+-              
+       if (header->bDescriptorType != USB_DT_ENDPOINT) {
+               warn("unexpected descriptor 0x%X, expecting endpoint, 0x%X",
+                       header->bDescriptorType, USB_DT_ENDPOINT);
+-              return parsed;
++              return -EINVAL;
+       }
+-      if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
++      if (header->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE)
+               memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
+-      else
++      else if (header->bLength >= USB_DT_ENDPOINT_SIZE)
+               memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_SIZE);
+-      
++      else {
++              warn("invalid endpoint descriptor");
++              return -EINVAL;
++      }
++
++      if ((endpoint->desc.bEndpointAddress & ~USB_ENDPOINT_DIR_MASK) >= 16) {
++              warn("invalid endpoint address 0x%X",
++                  endpoint->desc.bEndpointAddress);
++              return -EINVAL;
++      }
++
+       le16_to_cpus(&endpoint->desc.wMaxPacketSize);
+       buffer += header->bLength;
+       size -= header->bLength;
+-      parsed += header->bLength;
+-      /* Skip over the rest of the Class Specific or Vendor Specific */
+-      /*  descriptors */
++      /* Skip over any Class Specific or Vendor Specific descriptors */
+       begin = buffer;
+       numskipped = 0;
+       while (size >= sizeof(struct usb_descriptor_header)) {
+               header = (struct usb_descriptor_header *)buffer;
+-              if (header->bLength < 2) {
+-                      err("invalid descriptor length of %d", header->bLength);
+-                      return -1;
+-              }
+-
+               /* If we find another "proper" descriptor then we're done  */
+               if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
+-                  (header->bDescriptorType == USB_DT_INTERFACE) ||
+-                  (header->bDescriptorType == USB_DT_CONFIG) ||
+-                  (header->bDescriptorType == USB_DT_DEVICE))
++                  (header->bDescriptorType == USB_DT_INTERFACE))
+                       break;
+-              dbg("skipping descriptor 0x%X",
+-                      header->bDescriptorType);
++              dbg("skipping descriptor 0x%X", header->bDescriptorType);
+               numskipped++;
+               buffer += header->bLength;
+               size -= header->bLength;
+-              parsed += header->bLength;
+       }
+-      if (numskipped)
++      if (numskipped) {
+               dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
+-
+-      /* Copy any unknown descriptors into a storage area for drivers */
+-      /*  to later parse */
+-      len = (int)(buffer - begin);
+-      if (!len) {
+-              endpoint->extra = NULL;
+-              endpoint->extralen = 0;
+-              return parsed;
+-      }
+-
+-      endpoint->extra = kmalloc(len, GFP_KERNEL);
+-
+-      if (!endpoint->extra) {
+-              err("couldn't allocate memory for endpoint extra descriptors");
+-              endpoint->extralen = 0;
+-              return parsed;
++              endpoint->extra = begin;
++              endpoint->extralen = buffer - begin;
+       }
+-      memcpy(endpoint->extra, begin, len);
+-      endpoint->extralen = len;
+-
+-      return parsed;
++      return buffer - buffer0;
+ }
+ static void usb_release_intf(struct device *dev)
+ {
+       struct usb_interface *intf;
+       int j;
+-      int k;
+       intf = to_usb_interface(dev);
+       if (intf->altsetting) {
+               for (j = 0; j < intf->num_altsetting; j++) {
+                       struct usb_host_interface *as = &intf->altsetting[j];
+-                      if (as->extra)
+-                              kfree(as->extra);
+-                      if (as->endpoint) {
+-                              for (k = 0; k < as->desc.bNumEndpoints; k++)
+-                                      if (as->endpoint[k].extra)
+-                                              kfree(as->endpoint[k].extra);
+-                              kfree(as->endpoint);
+-                      }
++                      kfree(as->endpoint);
+               }
+               kfree(intf->altsetting);
+       }
+       kfree(intf);
+ }
+-static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)
++static int usb_parse_interface(struct usb_host_config *config, unsigned char *buffer, int size)
+ {
+-      int i, len, numskipped, retval, parsed = 0;
+-      struct usb_descriptor_header *header;
++      unsigned char *buffer0 = buffer;
++      struct usb_interface_descriptor *d;
++      int inum, asnum;
++      struct usb_interface *interface;
+       struct usb_host_interface *ifp;
++      int len, numskipped;
++      struct usb_descriptor_header *header;
+       unsigned char *begin;
++      int i, retval;
+-      interface->act_altsetting = 0;
+-      interface->num_altsetting = 0;
+-      interface->max_altsetting = USB_ALTSETTINGALLOC;
+-      device_initialize(&interface->dev);
+-      interface->dev.release = usb_release_intf;
+-
+-      /* put happens in usb_destroy_configuration */
+-      get_device(&interface->dev);
+-      
+-      interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting,
+-                                      GFP_KERNEL);
+-      
+-      if (!interface->altsetting) {
+-              err("couldn't kmalloc interface->altsetting");
+-              return -1;
+-      }
+-
+-      while (size > 0) {
+-              struct usb_interface_descriptor *d;
+-      
+-              if (interface->num_altsetting >= interface->max_altsetting) {
+-                      struct usb_host_interface *ptr;
+-                      int oldmas;
+-
+-                      oldmas = interface->max_altsetting;
+-                      interface->max_altsetting += USB_ALTSETTINGALLOC;
+-                      if (interface->max_altsetting > USB_MAXALTSETTING) {
+-                              warn("too many alternate settings (incr %d max %d)\n",
+-                                      USB_ALTSETTINGALLOC, USB_MAXALTSETTING);
+-                              return -1;
+-                      }
+-
+-                      ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL);
+-                      if (ptr == NULL) {
+-                              err("couldn't kmalloc interface->altsetting");
+-                              return -1;
+-                      }
+-                      memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas);
+-                      kfree(interface->altsetting);
+-                      interface->altsetting = ptr;
+-              }
+-
+-              ifp = interface->altsetting + interface->num_altsetting;
+-              ifp->endpoint = NULL;
+-              ifp->extra = NULL;
+-              ifp->extralen = 0;
+-              interface->num_altsetting++;
+-
+-              memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
+-
+-              /* Skip over the interface */
+-              buffer += ifp->desc.bLength;
+-              parsed += ifp->desc.bLength;
+-              size -= ifp->desc.bLength;
++      d = (struct usb_interface_descriptor *) buffer;
++      if (d->bDescriptorType != USB_DT_INTERFACE) {
++              warn("unexpected descriptor 0x%X, expecting interface, 0x%X",
++                      d->bDescriptorType, USB_DT_INTERFACE);
++              return -EINVAL;
++      }
+-              begin = buffer;
+-              numskipped = 0;
++      inum = d->bInterfaceNumber;
++      if (inum >= config->desc.bNumInterfaces) {
+-              /* Skip over any interface, class or vendor descriptors */
++              /* Skip to the next interface descriptor */
++              buffer += d->bLength;
++              size -= d->bLength;
+               while (size >= sizeof(struct usb_descriptor_header)) {
+-                      header = (struct usb_descriptor_header *)buffer;
++                      header = (struct usb_descriptor_header *) buffer;
+-                      if (header->bLength < 2) {
+-                              err("invalid descriptor length of %d", header->bLength);
+-                              return -1;
+-                      }
+-
+-                      /* If we find another "proper" descriptor then we're done  */
+-                      if ((header->bDescriptorType == USB_DT_INTERFACE) ||
+-                          (header->bDescriptorType == USB_DT_ENDPOINT) ||
+-                          (header->bDescriptorType == USB_DT_CONFIG) ||
+-                          (header->bDescriptorType == USB_DT_DEVICE))
++                      if (header->bDescriptorType == USB_DT_INTERFACE)
+                               break;
+-
+-                      numskipped++;
+-
+                       buffer += header->bLength;
+-                      parsed += header->bLength;
+                       size -= header->bLength;
+               }
++              return buffer - buffer0;
++      }
+-              if (numskipped)
+-                      dbg("skipped %d class/vendor specific interface descriptors", numskipped);
++      interface = config->interface[inum];
++      asnum = d->bAlternateSetting;
++      if (asnum >= interface->num_altsetting) {
++              warn("invalid alternate setting %d for interface %d",
++                  asnum, inum);
++              return -EINVAL;
++      }
+-              /* Copy any unknown descriptors into a storage area for */
+-              /*  drivers to later parse */
+-              len = (int)(buffer - begin);
+-              if (len) {
+-                      ifp->extra = kmalloc(len, GFP_KERNEL);
+-
+-                      if (!ifp->extra) {
+-                              err("couldn't allocate memory for interface extra descriptors");
+-                              ifp->extralen = 0;
+-                              return -1;
+-                      }
+-                      memcpy(ifp->extra, begin, len);
+-                      ifp->extralen = len;
+-              }
++      ifp = &interface->altsetting[asnum];
++      if (ifp->desc.bLength) {
++              warn("duplicate descriptor for interface %d altsetting %d",
++                  inum, asnum);
++              return -EINVAL;
++      }
++      memcpy(&ifp->desc, buffer, USB_DT_INTERFACE_SIZE);
++
++      buffer += d->bLength;
++      size -= d->bLength;
+-              /* Did we hit an unexpected descriptor? */
++      /* Skip over any Class Specific or Vendor Specific descriptors */
++      begin = buffer;
++      numskipped = 0;
++      while (size >= sizeof(struct usb_descriptor_header)) {
+               header = (struct usb_descriptor_header *)buffer;
+-              if ((size >= sizeof(struct usb_descriptor_header)) &&
+-                  ((header->bDescriptorType == USB_DT_CONFIG) ||
+-                   (header->bDescriptorType == USB_DT_DEVICE)))
+-                      return parsed;
+-
+-              if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
+-                      warn("too many endpoints");
+-                      return -1;
+-              }
+-              ifp->endpoint = (struct usb_host_endpoint *)
+-                      kmalloc(ifp->desc.bNumEndpoints *
+-                      sizeof(struct usb_host_endpoint), GFP_KERNEL);
+-              if (!ifp->endpoint) {
+-                      err("out of memory");
+-                      return -1;      
+-              }
++              /* If we find another "proper" descriptor then we're done  */
++              if ((header->bDescriptorType == USB_DT_INTERFACE) ||
++                  (header->bDescriptorType == USB_DT_ENDPOINT))
++                      break;
+-              memset(ifp->endpoint, 0, ifp->desc.bNumEndpoints *
+-                      sizeof(struct usb_host_endpoint));
+-      
+-              for (i = 0; i < ifp->desc.bNumEndpoints; i++) {
+-                      header = (struct usb_descriptor_header *)buffer;
+-
+-                      if (header->bLength > size) {
+-                              err("ran out of descriptors parsing");
+-                              return -1;
+-                      }
+-              
+-                      retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
+-                      if (retval < 0)
+-                              return retval;
++              dbg("skipping descriptor 0x%X", header->bDescriptorType);
++              numskipped++;
++
++              buffer += header->bLength;
++              size -= header->bLength;
++      }
++      if (numskipped) {
++              dbg("skipped %d class/vendor specific interface descriptors", numskipped);
++              ifp->extra = begin;
++              ifp->extralen = buffer - begin;
++      }
++
++      if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
++              warn("too many endpoints for interface %d altsetting %d",
++                  inum, asnum);
++              return -EINVAL;
++      }
++
++      len = ifp->desc.bNumEndpoints * sizeof(struct usb_host_endpoint);
++      ifp->endpoint = kmalloc(len, GFP_KERNEL);
++      if (!ifp->endpoint) {
++              err("out of memory");
++              return -ENOMEM;
++      }
++      memset(ifp->endpoint, 0, len);
+-                      buffer += retval;
+-                      parsed += retval;
+-                      size -= retval;
++      for (i = 0; i < ifp->desc.bNumEndpoints; i++) {
++              if (size < USB_DT_ENDPOINT_SIZE) {
++                      warn("ran out of descriptors while parsing endpoints");
++                      return -EINVAL;
+               }
+-              /* We check to see if it's an alternate to this one */
+-              d = (struct usb_interface_descriptor *)buffer;
+-              if (size < USB_DT_INTERFACE_SIZE
+-                              || d->bDescriptorType != USB_DT_INTERFACE
+-                              || !d->bAlternateSetting)
+-                      return parsed;
++              retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
++              if (retval < 0)
++                      return retval;
++
++              buffer += retval;
++              size -= retval;
+       }
+-      return parsed;
++      return buffer - buffer0;
+ }
+-int usb_parse_configuration(struct usb_host_config *config, char *buffer)
++int usb_parse_configuration(struct usb_host_config *config, char *buffer, int size)
+ {
+-      int i, size;
+-      int retval = -EINVAL;
++      int nintf, nintf_orig;
++      int i, j;
++      struct usb_interface *interface;
++      char *buffer2;
++      int size2;
+       struct usb_descriptor_header *header;
++      int numskipped, len;
++      char *begin;
++      int retval;
+       memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+-      le16_to_cpus(&config->desc.wTotalLength);
+-      size = config->desc.wTotalLength;
++      if (config->desc.bDescriptorType != USB_DT_CONFIG ||
++          config->desc.bLength < USB_DT_CONFIG_SIZE) {
++              warn("invalid configuration descriptor");
++              return -EINVAL;
++      }
++      config->desc.wTotalLength = size;
+-      for (i = 0; i < USB_MAXINTERFACES; ++i)
+-              config->interface[i] = NULL;
++      nintf = nintf_orig = config->desc.bNumInterfaces;
++      if (nintf > USB_MAXINTERFACES) {
++              warn("too many interfaces (%d max %d)",
++                  nintf, USB_MAXINTERFACES);
++              config->desc.bNumInterfaces = nintf = USB_MAXINTERFACES;
++      }
+-      if (config->desc.bNumInterfaces > USB_MAXINTERFACES) {
+-              warn("too many interfaces");
+-              goto error;
++      for (i = 0; i < nintf; ++i) {
++              interface = config->interface[i] =
++                  kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
++              dbg("kmalloc IF %p, numif %i", interface, i);
++              if (!interface) {
++                      err("out of memory");
++                      return -ENOMEM;
++              }
++              memset(interface, 0, sizeof(struct usb_interface));
++              interface->dev.release = usb_release_intf;
++              device_initialize(&interface->dev);
++
++              /* put happens in usb_destroy_configuration */
++              get_device(&interface->dev);
++      }
++
++      /* Go through the descriptors, checking their length and counting the
++       * number of altsettings for each interface */
++      buffer2 = buffer;
++      size2 = size;
++      j = 0;
++      while (size2 >= sizeof(struct usb_descriptor_header)) {
++              header = (struct usb_descriptor_header *) buffer2;
++              if ((header->bLength > size2) || (header->bLength < 2)) {
++                      warn("invalid descriptor of length %d", header->bLength);
++                      return -EINVAL;
++              }
++
++              if (header->bDescriptorType == USB_DT_INTERFACE) {
++                      struct usb_interface_descriptor *d;
++
++                      if (header->bLength < USB_DT_INTERFACE_SIZE) {
++                              warn("invalid interface descriptor");
++                              return -EINVAL;
++                      }
++                      d = (struct usb_interface_descriptor *) header;
++                      i = d->bInterfaceNumber;
++                      if (i >= nintf_orig) {
++                              warn("invalid interface number (%d/%d)",
++                                  i, nintf_orig);
++                              return -EINVAL;
++                      }
++                      if (i < nintf)
++                              ++config->interface[i]->num_altsetting;
++
++              } else if ((header->bDescriptorType == USB_DT_DEVICE ||
++                  header->bDescriptorType == USB_DT_CONFIG) && j) {
++                      warn("unexpected descriptor type 0x%X", header->bDescriptorType);
++                      return -EINVAL;
++              }
++
++              j = 1;
++              buffer2 += header->bLength;
++              size2 -= header->bLength;
+       }
++      /* Allocate the altsetting arrays */
+       for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+-              config->interface[i] = kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
+-              dbg("kmalloc IF %p, numif %i", config->interface[i], i);
+-              if (!config->interface[i]) {
+-                      err("out of memory");
+-                      retval = -ENOMEM;
+-                      goto error;
++              interface = config->interface[i];
++              if (interface->num_altsetting > USB_MAXALTSETTING) {
++                      warn("too many alternate settings for interface %d (%d max %d)\n",
++                          i, interface->num_altsetting, USB_MAXALTSETTING);
++                      return -EINVAL;
++              }
++              if (interface->num_altsetting == 0) {
++                      warn("no alternate settings for interface %d", i);
++                      return -EINVAL;
++              }
++
++              len = sizeof(*interface->altsetting) * interface->num_altsetting;
++              interface->altsetting = kmalloc(len, GFP_KERNEL);
++              if (!interface->altsetting) {
++                      err("couldn't kmalloc interface->altsetting");
++                      return -ENOMEM;
+               }
+-              memset(config->interface[i], 0x00, sizeof(struct usb_interface));
++              memset(interface->altsetting, 0, len);
+       }
+       buffer += config->desc.bLength;
+       size -= config->desc.bLength;
+-      
+-      config->extra = NULL;
+-      config->extralen = 0;
+-
+-      for (i = 0; i < config->desc.bNumInterfaces; i++) {
+-              int numskipped, len;
+-              char *begin;
+-
+-              /* Skip over the rest of the Class Specific or Vendor */
+-              /*  Specific descriptors */
+-              begin = buffer;
+-              numskipped = 0;
+-              while (size >= sizeof(struct usb_descriptor_header)) {
+-                      header = (struct usb_descriptor_header *)buffer;
+-                      if ((header->bLength > size) || (header->bLength < 2)) {
+-                              err("invalid descriptor length of %d", header->bLength);
+-                              return -1;
+-                      }
+-
+-                      /* If we find another "proper" descriptor then we're done  */
+-                      if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
+-                          (header->bDescriptorType == USB_DT_INTERFACE) ||
+-                          (header->bDescriptorType == USB_DT_CONFIG) ||
+-                          (header->bDescriptorType == USB_DT_DEVICE))
+-                              break;
+-
+-                      dbg("skipping descriptor 0x%X", header->bDescriptorType);
+-                      numskipped++;
++      /* Skip over any Class Specific or Vendor Specific descriptors */
++      begin = buffer;
++      numskipped = 0;
++      while (size >= sizeof(struct usb_descriptor_header)) {
++              header = (struct usb_descriptor_header *)buffer;
+-                      buffer += header->bLength;
+-                      size -= header->bLength;
+-              }
+-              if (numskipped)
+-                      dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
++              /* If we find another "proper" descriptor then we're done  */
++              if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
++                  (header->bDescriptorType == USB_DT_INTERFACE))
++                      break;
+-              /* Copy any unknown descriptors into a storage area for */
+-              /*  drivers to later parse */
+-              len = (int)(buffer - begin);
+-              if (len) {
+-                      if (config->extralen) {
+-                              warn("extra config descriptor");
+-                      } else {
+-                              config->extra = kmalloc(len, GFP_KERNEL);
+-                              if (!config->extra) {
+-                                      err("couldn't allocate memory for config extra descriptors");
+-                                      config->extralen = 0;
+-                                      return -1;
+-                              }
++              dbg("skipping descriptor 0x%X", header->bDescriptorType);
++              numskipped++;
+-                              memcpy(config->extra, begin, len);
+-                              config->extralen = len;
+-                      }
+-              }
++              buffer += header->bLength;
++              size -= header->bLength;
++      }
++      if (numskipped) {
++              dbg("skipped %d class/vendor specific configuration descriptors", numskipped);
++              config->extra = begin;
++              config->extralen = buffer - begin;
++      }
+-              retval = usb_parse_interface(config->interface[i], buffer, size);
++      /* Parse all the interface/altsetting descriptors */
++      while (size >= sizeof(struct usb_descriptor_header)) {
++              retval = usb_parse_interface(config, buffer, size);
+               if (retval < 0)
+                       return retval;
+@@ -375,11 +340,18 @@
+               size -= retval;
+       }
++      /* Check for missing altsettings */
++      for (i = 0; i < nintf; ++i) {
++              interface = config->interface[i];
++              for (j = 0; j < interface->num_altsetting; ++j) {
++                      if (!interface->altsetting[j].desc.bLength) {
++                              warn("missing altsetting %d for interface %d", j, i);
++                              return -EINVAL;
++                      }
++              }
++      }
++
+       return size;
+-error:
+-      for (i = 0; i < USB_MAXINTERFACES; ++i)
+-              kfree(config->interface[i]);
+-      return retval;
+ }
+ // hub-only!! ... and only exported for reset/reinit path.
+@@ -387,7 +359,7 @@
+ void usb_destroy_configuration(struct usb_device *dev)
+ {
+       int c, i;
+-      
++
+       if (!dev->config)
+               return;
+@@ -401,12 +373,11 @@
+       for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+               struct usb_host_config *cf = &dev->config[c];
+-              if (!cf->interface)
+-                      break;
+-
+               for (i = 0; i < cf->desc.bNumInterfaces; i++) {
+                       struct usb_interface *ifp = cf->interface[i];
+-                      put_device(&ifp->dev);
++
++                      if (ifp)
++                              put_device(&ifp->dev);
+               }
+       }
+       kfree(dev->config);
+@@ -417,38 +388,39 @@
+ // (used by real hubs and virtual root hubs)
+ int usb_get_configuration(struct usb_device *dev)
+ {
++      int ncfg = dev->descriptor.bNumConfigurations;
+       int result;
+       unsigned int cfgno, length;
+       unsigned char *buffer;
+       unsigned char *bigbuffer;
+       struct usb_config_descriptor *desc;
+-      if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
+-              warn("too many configurations");
+-              return -EINVAL;
++      if (ncfg > USB_MAXCONFIG) {
++              warn("too many configurations (%d max %d)",
++                  ncfg, USB_MAXCONFIG);
++              dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
+       }
+-      if (dev->descriptor.bNumConfigurations < 1) {
+-              warn("not enough configurations");
++      if (ncfg < 1) {
++              warn("no configurations");
+               return -EINVAL;
+       }
+-      dev->config = (struct usb_host_config *)
+-              kmalloc(dev->descriptor.bNumConfigurations *
+-              sizeof(struct usb_host_config), GFP_KERNEL);
++      length = ncfg * sizeof(struct usb_host_config);
++      dev->config = kmalloc(length, GFP_KERNEL);
+       if (!dev->config) {
+               err("out of memory");
+-              return -ENOMEM; 
++              return -ENOMEM;
+       }
+-      memset(dev->config, 0, dev->descriptor.bNumConfigurations *
+-              sizeof(struct usb_host_config));
++      memset(dev->config, 0, length);
+-      dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
+-              dev->descriptor.bNumConfigurations, GFP_KERNEL);
++      length = ncfg * sizeof(char *);
++      dev->rawdescriptors = kmalloc(length, GFP_KERNEL);
+       if (!dev->rawdescriptors) {
+               err("out of memory");
+               return -ENOMEM;
+       }
++      memset(dev->rawdescriptors, 0, length);
+       buffer = kmalloc(8, GFP_KERNEL);
+       if (!buffer) {
+@@ -457,7 +429,7 @@
+       }
+       desc = (struct usb_config_descriptor *)buffer;
+-      for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
++      for (cfgno = 0; cfgno < ncfg; cfgno++) {
+               /* We grab the first 8 bytes so we know how long the whole */
+               /*  configuration is */
+               result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
+@@ -465,14 +437,14 @@
+                       if (result < 0)
+                               err("unable to get descriptor");
+                       else {
+-                              err("config descriptor too short (expected %i, got %i)", 8, result);
++                              warn("config descriptor too short (expected %i, got %i)", 8, result);
+                               result = -EINVAL;
+                       }
+                       goto err;
+               }
+               /* Get the full buffer */
+-              length = le16_to_cpu(desc->wTotalLength);
++              length = max((int) le16_to_cpu(desc->wTotalLength), USB_DT_CONFIG_SIZE);
+               bigbuffer = kmalloc(length, GFP_KERNEL);
+               if (!bigbuffer) {
+@@ -487,8 +459,8 @@
+                       err("couldn't get all of config descriptors");
+                       kfree(bigbuffer);
+                       goto err;
+-              }       
+-      
++              }
++
+               if (result < length) {
+                       err("config descriptor too short (expected %i, got %i)", length, result);
+                       result = -EINVAL;
+@@ -498,11 +470,11 @@
+               dev->rawdescriptors[cfgno] = bigbuffer;
+-              result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
++              result = usb_parse_configuration(&dev->config[cfgno], bigbuffer, length);
+               if (result > 0)
+                       dbg("descriptor data left");
+               else if (result < 0) {
+-                      result = -EINVAL;
++                      ++cfgno;
+                       goto err;
+               }
+       }
+Index: linux-2.6.0-test5/drivers/usb/core/hub.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/core/hub.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/core/hub.c   2003-09-27 11:38:32.306617032 +0800
+@@ -859,8 +859,7 @@
+               }
+       }
+-      /* XXX Replace this with dbg() when 2.6 is about to ship. */
+-      dev_info (hubdev (hub),
++      dev_dbg (hubdev (hub),
+               "debounce: port %d: delay %dms stable %d status 0x%x\n",
+               port + 1, delay_time, stable_count, portstatus);
+@@ -1183,8 +1182,7 @@
+               return -1;
+       }
+-      pid = kernel_thread(hub_thread, NULL,
+-              CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      pid = kernel_thread(hub_thread, NULL, CLONE_KERNEL);
+       if (pid >= 0) {
+               khubd_pid = pid;
+Index: linux-2.6.0-test5/drivers/usb/core/usb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/core/usb.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/core/usb.c   2003-09-27 11:38:32.335612624 +0800
+@@ -1424,14 +1424,15 @@
+       struct usb_interface *intf;
+       struct usb_driver *driver;
+-      if ((dev->driver == &usb_generic_driver) || 
++      if ((dev->driver == NULL) ||
++          (dev->driver == &usb_generic_driver) ||
+           (dev->driver_data == &usb_generic_driver_data))
+               return 0;
+       intf = to_usb_interface(dev);
+       driver = to_usb_driver(dev->driver);
+-      if (driver && driver->suspend)
++      if (driver->suspend)
+               return driver->suspend(intf, state);
+       return 0;
+ }
+@@ -1441,14 +1442,15 @@
+       struct usb_interface *intf;
+       struct usb_driver *driver;
+-      if ((dev->driver == &usb_generic_driver) || 
++      if ((dev->driver == NULL) ||
++          (dev->driver == &usb_generic_driver) ||
+           (dev->driver_data == &usb_generic_driver_data))
+               return 0;
+       intf = to_usb_interface(dev);
+       driver = to_usb_driver(dev->driver);
+-      if (driver && driver->resume)
++      if (driver->resume)
+               return driver->resume(intf);
+       return 0;
+ }
+Index: linux-2.6.0-test5/drivers/usb/gadget/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/gadget/inode.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/gadget/inode.c       2003-09-27 11:38:32.405601984 +0800
+@@ -28,7 +28,6 @@
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
+ #include <linux/uts.h>
+-#include <linux/version.h>
+ #include <linux/wait.h>
+ #include <linux/compiler.h>
+ #include <asm/uaccess.h>
+Index: linux-2.6.0-test5/drivers/usb/gadget/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/gadget/Kconfig  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/gadget/Kconfig       2003-09-27 11:38:32.450595144 +0800
+@@ -68,7 +68,7 @@
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+-      depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA250 || USB_SA1100)
++      depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100)
+       help
+         Gadget Zero is a two-configuration device.  It either sinks and
+         sources bulk data; or it loops back a configurable number of
+@@ -97,9 +97,9 @@
+       depends on USB_ZERO && (USB_NET2280 || USB_DUMMY_HCD)
+       default y
+-config USB_ZERO_PXA250
++config USB_ZERO_PXA2XX
+       bool
+-      depends on USB_ZERO && USB_PXA250
++      depends on USB_ZERO && USB_PXA2XX
+       default y
+ config USB_ZERO_SA1100
+@@ -110,22 +110,28 @@
+ config USB_ETH
+       tristate "Ethernet Gadget"
+-      depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA250 || USB_SA1100)
++      depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100)
+       help
+-        This driver implements the "Communication Device Class" (CDC)
+-        Ethernet Control Model.  That protocol is often avoided with pure
+-        Ethernet adapters, in favor of simpler vendor-specific hardware,
+-        but is widely supported by firmware for smart network devices.
++        This driver implements Ethernet style communication, in either
++        of two ways:
++        
++         - The "Communication Device Class" (CDC) Ethernet Control Model.
++           That protocol is often avoided with pure Ethernet adapters, in
++           favor of simpler vendor-specific hardware, but is widely
++           supported by firmware for smart network devices.
++
++         - On hardware can't implement that protocol, a simpler approach
++           is used, placing fewer demands on USB.
+         Within the USB device, this gadget driver exposes a network device
+         "usbX", where X depends on what other networking devices you have.
+         Treat it like a two-node Ethernet link:  host, and gadget.
+         The Linux-USB host-side "usbnet" driver interoperates with this
+-        driver, so that deep I/O queues can be supported.  (On 2.4 kernels,
+-        use "CDCEther" instead.)  Deep queues are especially important with
+-        high speed devices.  It should also interoperate with standard CDC
+-        Ethernet class drivers on other host operating systems.
++        driver, so that deep I/O queues can be supported.  On 2.4 kernels,
++        use "CDCEther" instead, if you're using the CDC option. That CDC
++        mode should also interoperate with standard CDC Ethernet class
++        drivers on other host operating systems.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_ether".
+@@ -137,9 +143,9 @@
+       depends on USB_ETH && (USB_NET2280 || USB_DUMMY_HCD)
+       default y
+-config USB_ETH_PXA250
++config USB_ETH_PXA2XX
+       bool
+-      depends on USB_ETH && USB_PXA250
++      depends on USB_ETH && USB_PXA2XX
+       default y
+ config USB_ETH_SA1100
+Index: linux-2.6.0-test5/drivers/usb/input/hiddev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/input/hiddev.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/input/hiddev.c       2003-09-27 11:38:32.505586784 +0800
+@@ -727,6 +727,7 @@
+       retval = usb_register_dev(&hiddev->intf, &hiddev_class);
+       if (retval) {
+               err("Not able to get a minor for this device.");
++              kfree(hiddev);
+               return -1;
+       }
+Index: linux-2.6.0-test5/drivers/usb/input/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/input/Kconfig   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/input/Kconfig        2003-09-27 11:38:32.535582224 +0800
+@@ -20,10 +20,8 @@
+         If unsure, say Y.
+-        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 hid. 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, say M here: the
++        module will be called hid.
+ comment "Input core support is needed for USB HID input layer or HIDBP support"
+       depends on USB && INPUT=n
+@@ -104,10 +102,8 @@
+         This is almost certainly not what you want.  This is mostly
+         useful for embedded applications or simple keyboards.
+-        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 usbkbd. 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, say M here: the
++        module will be called usbkbd.
+         If even remotely unsure, say N.
+@@ -122,10 +118,8 @@
+         This is almost certainly not what you want.  This is mostly
+         useful for embedded applications or simple mice.
+-        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 usbmouse. 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, say M here: the
++        module will be called usbmouse.
+         If even remotely unsure, say N.
+@@ -140,10 +134,8 @@
+         (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+         (CONFIG_INPUT_EVDEV) as well.
+-        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 aiptek. 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, say M here: the
++        module will be called aiptek.
+ config USB_WACOM
+       tristate "Wacom Intuos/Graphire tablet support"
+@@ -154,10 +146,8 @@
+         (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+         (CONFIG_INPUT_EVDEV) as well.
+-        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 wacom.  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, say M here: the
++        module will be called wacom.
+ config USB_KBTAB
+       tristate "KB Gear JamStudio tablet support"
+@@ -168,10 +158,8 @@
+         (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+         (CONFIG_INPUT_EVDEV) as well.
+-        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 kbtab.o.  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, say M here: the
++        module will be called kbtab.
+ config USB_POWERMATE
+       tristate "Griffin PowerMate and Contour Jog support"
+@@ -184,10 +172,8 @@
+         You can download userspace tools from http://sowerbutts.com/powermate/
+-        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 powermate. 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, say M here: the
++        module will be called powermate.
+ config USB_XPAD
+       tristate "X-Box gamepad support"
+@@ -200,8 +186,6 @@
+         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, say M here: the
++        module will be called xpad.
+Index: linux-2.6.0-test5/drivers/usb/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/Kconfig      2003-09-27 11:38:32.584574776 +0800
+@@ -33,10 +33,8 @@
+         It doesn't normally hurt to select them all if you are not certain.
+-        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 usbcore.  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, say M here: the
++        module will be called usbcore.
+ source "drivers/usb/core/Kconfig"
+@@ -82,10 +80,8 @@
+         Say Y here if you own an USS-720 USB->Parport cable and intend to
+         connect anything other than a printer to it.
+-        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 uss720. 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, say M here: the
++        module will be called uss720.
+ source "drivers/usb/serial/Kconfig"
+Index: linux-2.6.0-test5/drivers/usb/media/dabusb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/dabusb.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/dabusb.c       2003-09-27 11:38:32.628568088 +0800
+@@ -89,7 +89,6 @@
+ static void dump_urb (struct urb *urb)
+ {
+       dbg("urb                   :%p", urb);
+-      dbg("next                  :%p", urb->next);
+       dbg("dev                   :%p", urb->dev);
+       dbg("pipe                  :%08X", urb->pipe);
+       dbg("status                :%d", urb->status);
+@@ -728,7 +727,7 @@
+       pdabusb_t s;
+       dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
+-        usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
++        usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, intf->altsetting->desc.bInterfaceNumber);
+       /* We don't handle multiple configurations */
+       if (usbdev->descriptor.bNumConfigurations != 1)
+@@ -762,7 +761,7 @@
+                       goto reject;
+               }
+       }
+-      dbg("bound to interface: %d", ifnum);
++      dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
+       usb_set_intfdata (intf, s);
+       up (&s->mutex);
+Index: linux-2.6.0-test5/drivers/usb/media/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/Kconfig   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/Kconfig        2003-09-27 11:38:32.677560640 +0800
+@@ -14,10 +14,8 @@
+         isochronous transactions. URB's are explained in
+         <file:Documentation/usb/URB.txt>.
+-        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 dabusb.  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, say M here: the
++        module will be called dabusb.
+ comment "Video4Linux support is needed for USB Multimedia device support"
+       depends on USB && VIDEO_DEV=n
+@@ -33,10 +31,8 @@
+         Information on this API and pointers to "v4l" programs may be found
+         on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 vicam. 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, say M here: the
++        module will be called vicam.
+ config USB_DSBR
+       tristate "D-Link USB FM radio support (EXPERIMENTAL)"
+@@ -53,10 +49,8 @@
+         "v4l" programs may be found on the WWW at
+         <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 dsbr100. 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, say M here: the
++        module will be called dsbr100.
+ config USB_IBMCAM
+       tristate "USB IBM (Xirlink) C-it Camera support"
+@@ -72,13 +66,12 @@
+         "v4l" programs may be found on the WWW at
+         <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 ibmcam.  If you want to compile it as a
+-        module, say M here and read <file:Documentation/modules.txt>. This
+-        camera has several configuration options which can be specified when
+-        you load the module.  Read <file:Documentation/usb/ibmcam.txt> to
+-        learn more.
++        To compile this driver as a module, say M here: the
++        module will be called ibmcam.
++
++        This camera has several configuration options which
++        can be specified when you load the module. Read
++        <file:Documentation/usb/ibmcam.txt> to learn more.
+ config USB_KONICAWC
+       tristate "USB Konica Webcam support"
+@@ -93,10 +86,8 @@
+         "v4l" programs may be found on the WWW at
+         <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 konicawc. 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, say M here: the
++        module will be called konicawc.
+ config USB_OV511
+       tristate "USB OV511 Camera support"
+@@ -111,10 +102,8 @@
+         Information on this API and pointers to "v4l" programs may be found
+         on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 ov511. 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, say M here: the
++        module will be called ov511.
+ config USB_PWC
+       tristate "USB Philips Cameras"
+@@ -152,10 +141,8 @@
+         Information on this API and pointers to "v4l" programs may be found
+         on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 pwc.  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, say M here: the
++        module will be called pwc.
+ config USB_SE401
+       tristate "USB SE401 Camera support"
+@@ -170,10 +157,8 @@
+         Information on this API and pointers to "v4l" programs may be found
+         on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 se401. 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, say M here: the
++        module will be called se401.
+ config USB_STV680
+       tristate "USB STV680 (Pencam) Camera support"
+@@ -189,8 +174,6 @@
+         Information on this API and pointers to "v4l" programs may be found
+         on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+-        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 stv680. 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, say M here: the
++        module will be called stv680.
+Index: linux-2.6.0-test5/drivers/usb/media/usbvideo.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/usbvideo.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/usbvideo.c     2003-09-27 11:38:32.796542552 +0800
+@@ -24,7 +24,6 @@
+ #include <linux/vmalloc.h>
+ #include <linux/init.h>
+ #include <linux/spinlock.h>
+-#include <linux/mm.h>
+ #include <asm/io.h>
+Index: linux-2.6.0-test5/drivers/usb/media/vicam.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/media/vicam.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/media/vicam.c        2003-09-27 11:38:32.853533888 +0800
+@@ -1292,7 +1292,7 @@
+       interface = &intf->altsetting[0];
+       DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",
+-             ifnum, (unsigned) (interface->desc.bNumEndpoints));
++             interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));
+       endpoint = &interface->endpoint[0].desc;
+       if ((endpoint->bEndpointAddress & 0x80) &&
+Index: linux-2.6.0-test5/drivers/usb/misc/speedtch.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/misc/speedtch.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/misc/speedtch.c      2003-09-27 11:38:32.906525832 +0800
+@@ -21,7 +21,9 @@
+  ******************************************************************************/
+ /*
+- *  Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@wanadoo.fr)
++ *  Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@free.fr)
++ *
++ *  1.7+:     - See the check-in logs
+  *
+  *  1.6:      - No longer opens a connection if the firmware is not loaded
+  *            - Added support for the speedtouch 330
+@@ -84,6 +86,11 @@
+ #include <linux/usb.h>
++#ifdef DEBUG
++#define DEBUG_ON(x)   BUG_ON(x)
++#else
++#define DEBUG_ON(x)   do { if (x); } while (0)
++#endif
+ #ifdef VERBOSE_DEBUG
+ static int udsl_print_packet (const unsigned char *data, int len);
+@@ -94,9 +101,9 @@
+ #define vdbg(arg...)
+ #endif
+-#define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@wanadoo.fr>"
++#define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
+ #define DRIVER_DESC   "Alcatel SpeedTouch USB driver"
+-#define DRIVER_VERSION        "1.6"
++#define DRIVER_VERSION        "1.7"
+ static const char udsl_driver_name [] = "speedtch";
+@@ -109,10 +116,10 @@
+ #define UDSL_MAX_SND_BUFS             8
+ #define UDSL_MAX_RCV_BUF_SIZE         1024 /* ATM cells */
+ #define UDSL_MAX_SND_BUF_SIZE         1024 /* ATM cells */
+-#define UDSL_DEFAULT_RCV_URBS         1
+-#define UDSL_DEFAULT_SND_URBS         1
+-#define UDSL_DEFAULT_RCV_BUFS         2
+-#define UDSL_DEFAULT_SND_BUFS         2
++#define UDSL_DEFAULT_RCV_URBS         2
++#define UDSL_DEFAULT_SND_URBS         2
++#define UDSL_DEFAULT_RCV_BUFS         4
++#define UDSL_DEFAULT_SND_BUFS         4
+ #define UDSL_DEFAULT_RCV_BUF_SIZE     64 /* ATM cells */
+ #define UDSL_DEFAULT_SND_BUF_SIZE     64 /* ATM cells */
+@@ -351,7 +358,7 @@
+                       dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
+                       /* discard cells already received */
+                       skb_trim (skb, 0);
+-                      BUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
++                      DEBUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
+               }
+               memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+@@ -498,7 +505,7 @@
+               memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
+               target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+-              BUG_ON (--ctrl->num_cells);
++              DEBUG_ON (--ctrl->num_cells);
+       }
+       memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
+@@ -535,7 +542,7 @@
+       vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
+-      BUG_ON (buf->filled_cells > rcv_buf_size);
++      DEBUG_ON (buf->filled_cells > rcv_buf_size);
+       /* may not be in_interrupt() */
+       spin_lock_irqsave (&instance->receive_lock, flags);
+@@ -1216,8 +1223,7 @@
+               count = 0;
+               spin_lock_irq (&instance->receive_lock);
+               list_for_each (pos, &instance->spare_receivers)
+-                      if (++count > num_rcv_urbs)
+-                              panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
++                      DEBUG_ON (++count > num_rcv_urbs);
+               spin_unlock_irq (&instance->receive_lock);
+               dbg ("udsl_usb_disconnect: found %u spare receivers", count);
+@@ -1253,8 +1259,7 @@
+               count = 0;
+               spin_lock_irq (&instance->send_lock);
+               list_for_each (pos, &instance->spare_senders)
+-                      if (++count > num_snd_urbs)
+-                              panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
++                      DEBUG_ON (++count > num_snd_urbs);
+               spin_unlock_irq (&instance->send_lock);
+               dbg ("udsl_usb_disconnect: found %u spare senders", count);
+Index: linux-2.6.0-test5/drivers/usb/misc/usbtest.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/misc/usbtest.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/misc/usbtest.c       2003-09-27 11:38:32.968516408 +0800
+@@ -87,7 +87,7 @@
+       struct usb_host_endpoint        *in, *out;
+       struct usb_device               *udev;
+-      for (tmp = 0; tmp < intf->max_altsetting; tmp++) {
++      for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
+               unsigned        ep;
+               in = out = 0;
+Index: linux-2.6.0-test5/drivers/usb/net/usbnet.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/net/usbnet.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/net/usbnet.c 2003-09-27 11:38:33.172485400 +0800
+@@ -252,6 +252,8 @@
+       /* for new devices, use the descriptor-reading code instead */
+       int             in;             /* rx endpoint */
+       int             out;            /* tx endpoint */
++
++      unsigned long   data;           /* Misc driver specific data */
+ };
+ // we record the state for each of our queued skbs
+@@ -298,6 +300,9 @@
+ /*-------------------------------------------------------------------------*/
++static struct ethtool_ops usbnet_ethtool_ops;
++static void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
++
+ /* mostly for PDA style devices, which are always connected if present */
+ static int always_connected (struct usbnet *dev)
+ {
+@@ -312,7 +317,7 @@
+       struct usb_host_interface       *alt;
+       struct usb_host_endpoint        *in, *out;
+-      for (tmp = 0; tmp < intf->max_altsetting; tmp++) {
++      for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
+               unsigned        ep;
+               in = out = 0;
+@@ -383,10 +388,10 @@
\f
+ #ifdef CONFIG_USB_AX8817X
+-#define NEED_MII
+ /* ASIX AX8817X based USB 2.0 Ethernet Devices */
+ #define HAVE_HARDWARE
++#define NEED_MII
+ #include <linux/crc32.h>
+@@ -394,6 +399,8 @@
+ #define AX_CMD_READ_MII_REG           0x07
+ #define AX_CMD_WRITE_MII_REG          0x08
+ #define AX_CMD_SET_HW_MII             0x0a
++#define AX_CMD_READ_EEPROM            0x0b
++#define AX_CMD_WRITE_EEPROM           0x0c
+ #define AX_CMD_WRITE_RX_CTL           0x10
+ #define AX_CMD_READ_IPG012            0x11
+ #define AX_CMD_WRITE_IPG0             0x12
+@@ -403,8 +410,15 @@
+ #define AX_CMD_READ_NODE_ID           0x17
+ #define AX_CMD_READ_PHY_ID            0x19
+ #define AX_CMD_WRITE_MEDIUM_MODE      0x1b
++#define AX_CMD_READ_MONITOR_MODE      0x1c
++#define AX_CMD_WRITE_MONITOR_MODE     0x1d
+ #define AX_CMD_WRITE_GPIOS            0x1f
++#define AX_MONITOR_MODE                       0x01
++#define AX_MONITOR_LINK                       0x02
++#define AX_MONITOR_MAGIC              0x04
++#define AX_MONITOR_HSFS                       0x10
++
+ #define AX_MCAST_FILTER_SIZE          8
+ #define AX_MAX_MCAST                  64
+@@ -441,11 +455,11 @@
+ static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+ {
+       struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+-      
++
+       if (urb->status < 0)
+               printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
+                       urb->status);
+-      
++
+       kfree(req);
+       usb_free_urb(urb);
+ }
+@@ -456,12 +470,12 @@
+       struct usb_ctrlrequest *req;
+       int status;
+       struct urb *urb;
+-      
++
+       if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
+               devdbg(dev, "Error allocating URB in write_cmd_async!");
+               return;
+       }
+-      
++
+       if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
+               deverr(dev, "Failed to allocate memory for control request");
+               usb_free_urb(urb);
+@@ -496,34 +510,31 @@
+       } else if (net->mc_count == 0) {
+               /* just broadcast and directed */
+       } else {
++              /* We use the 20 byte dev->data
++               * for our 8 byte filter buffer
++               * to avoid allocating memory that
++               * is tricky to free later */
++              u8 *multi_filter = (u8 *)dev->data;
+               struct dev_mc_list *mc_list = net->mc_list;
+-              u8 *multi_filter;
+               u32 crc_bits;
+               int i;
+-              multi_filter = kmalloc(AX_MCAST_FILTER_SIZE, GFP_ATOMIC);
+-              if (multi_filter == NULL) {
+-                      /* Oops, couldn't allocate a buffer for setting the multicast
+-                         filter. Try all multi mode. */
+-                      rx_ctl |= 0x02;
+-              } else {
+-                      memset(multi_filter, 0, AX_MCAST_FILTER_SIZE);
+-
+-                      /* Build the multicast hash filter. */
+-                      for (i = 0; i < net->mc_count; i++) {
+-                              crc_bits =
+-                                  ether_crc(ETH_ALEN,
+-                                            mc_list->dmi_addr) >> 26;
+-                              multi_filter[crc_bits >> 3] |=
+-                                  1 << (crc_bits & 7);
+-                              mc_list = mc_list->next;
+-                      }
+-
+-                      ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
+-                                         AX_MCAST_FILTER_SIZE, multi_filter);
++              memset(multi_filter, 0, AX_MCAST_FILTER_SIZE);
+-                      rx_ctl |= 0x10;
++              /* Build the multicast hash filter. */
++              for (i = 0; i < net->mc_count; i++) {
++                      crc_bits =
++                          ether_crc(ETH_ALEN,
++                                    mc_list->dmi_addr) >> 26;
++                      multi_filter[crc_bits >> 3] |=
++                          1 << (crc_bits & 7);
++                      mc_list = mc_list->next;
+               }
++
++              ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
++                                 AX_MCAST_FILTER_SIZE, multi_filter);
++
++              rx_ctl |= 0x10;
+       }
+       ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
+@@ -533,7 +544,7 @@
+ {
+       struct usbnet *dev = netdev->priv;
+       u16 res;
+-      u8 buf[4];
++      u8 buf[1];
+       ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+       ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
+@@ -546,23 +557,103 @@
+ {
+       struct usbnet *dev = netdev->priv;
+       u16 res = val;
+-      u8 buf[4];
++      u8 buf[1];
+       ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+       ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
+       ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+ }
++void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
++{
++      struct usbnet *dev = (struct usbnet *)net->priv;
++      u8 opt;
++
++      if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
++              wolinfo->supported = 0;
++              wolinfo->wolopts = 0;
++              return;
++      }
++      wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
++      wolinfo->wolopts = 0;
++      if (opt & AX_MONITOR_MODE) {
++              if (opt & AX_MONITOR_LINK)
++                      wolinfo->wolopts |= WAKE_PHY;
++              if (opt & AX_MONITOR_MAGIC)
++                      wolinfo->wolopts |= WAKE_MAGIC;
++      }
++}
++
++int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
++{
++      struct usbnet *dev = (struct usbnet *)net->priv;
++      u8 opt = 0;
++      u8 buf[1];
++
++      if (wolinfo->wolopts & WAKE_PHY)
++              opt |= AX_MONITOR_LINK;
++      if (wolinfo->wolopts & WAKE_MAGIC)
++              opt |= AX_MONITOR_MAGIC;
++      if (opt != 0)
++              opt |= AX_MONITOR_MODE;
++
++      if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
++                            opt, 0, 0, &buf) < 0)
++              return -EINVAL;
++
++      return 0;
++}
++
++int ax8817x_get_eeprom(struct net_device *net, 
++                     struct ethtool_eeprom *eeprom, u8 *data)
++{
++      struct usbnet *dev = (struct usbnet *)net->priv;
++      u16 *ebuf = (u16 *)data;
++      int i;
++
++      /* Crude hack to ensure that we don't overwrite memory
++       * if an odd length is supplied
++       */
++      if (eeprom->len % 2)
++              return -EINVAL;
++
++      /* ax8817x returns 2 bytes from eeprom on read */
++      for (i=0; i < eeprom->len / 2; i++) {
++              if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM, 
++                      eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
++                      return -EINVAL;
++      }
++      return i * 2;
++}
++
++static void ax8817x_get_drvinfo (struct net_device *net,
++                               struct ethtool_drvinfo *info)
++{
++      /* Inherit standard device info */
++      usbnet_get_drvinfo(net, info);
++      info->eedump_len = 0x3e;
++}
++
+ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
+ {
+       int ret;
+       u8 buf[6];
+       u16 *buf16 = (u16 *) buf;
+       int i;
++      unsigned long gpio_bits = dev->driver_info->data;
+       dev->in = usb_rcvbulkpipe(dev->udev, 3);
+       dev->out = usb_sndbulkpipe(dev->udev, 2);
++      /* Toggle the GPIOs in a manufacturer/model specific way */
++      for (i = 2; i >= 0; i--) {
++              if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
++                                      (gpio_bits >> (i * 8)) & 0xff, 0, 0,
++                                      buf)) < 0)
++                      return ret;
++              wait_ms(5);
++      }
++
+       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
+               dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
+               return ret;
+@@ -640,6 +731,11 @@
+       dev->net->set_multicast_list = ax8817x_set_multicast;
++      usbnet_ethtool_ops.get_drvinfo = &ax8817x_get_drvinfo;
++      usbnet_ethtool_ops.get_wol = &ax8817x_get_wol;
++      usbnet_ethtool_ops.set_wol = &ax8817x_set_wol;
++      usbnet_ethtool_ops.get_eeprom = &ax8817x_get_eeprom;
++
+       return 0;
+ }
+@@ -647,7 +743,30 @@
+       .description = "ASIX AX8817x USB 2.0 Ethernet",
+       .bind = ax8817x_bind,
+       .flags =  FLAG_ETHER,
++      .data = 0x00130103,
++};
++
++static const struct driver_info dlink_dub_e100_info = {
++      .description = "DLink DUB-E100 USB Ethernet",
++      .bind = ax8817x_bind,
++      .flags =  FLAG_ETHER,
++      .data = 0x009f9d9f,
++};
++
++static const struct driver_info netgear_fa120_info = {
++      .description = "Netgear FA-120 USB Ethernet",
++      .bind = ax8817x_bind,
++      .flags =  FLAG_ETHER,
++      .data = 0x00130103,
+ };
++
++static const struct driver_info hawking_uf200_info = {
++      .description = "Hawking UF200 USB Ethernet",
++      .bind = ax8817x_bind,
++      .flags =  FLAG_ETHER,
++      .data = 0x001f1d1f,
++};
++
+ #endif /* CONFIG_USB_AX8817X */
+@@ -2415,72 +2534,45 @@
+ /*-------------------------------------------------------------------------*/
+-static inline int
+-usbnet_ethtool_ioctl (struct net_device *net, void __user *useraddr)
++static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
+ {
+-      struct usbnet   *dev = (struct usbnet *) net->priv;
+-      u32             cmd;
++      struct usbnet *dev = net->priv;
+-      if (get_user (cmd, (u32 *)useraddr))
+-              return -EFAULT;
+-      switch (cmd) {
+-
+-      case ETHTOOL_GDRVINFO: {        /* get driver info */
+-              struct ethtool_drvinfo          info;
+-
+-              memset (&info, 0, sizeof info);
+-              info.cmd = ETHTOOL_GDRVINFO;
+-              strncpy (info.driver, driver_name, sizeof info.driver);
+-              strncpy (info.version, DRIVER_VERSION, sizeof info.version);
+-              strncpy (info.fw_version, dev->driver_info->description,
+-                      sizeof info.fw_version);
+-              usb_make_path (dev->udev, info.bus_info, sizeof info.bus_info);
+-              if (copy_to_user (useraddr, &info, sizeof (info)))
+-                      return -EFAULT;
+-              return 0;
+-              }
++      strncpy (info->driver, driver_name, sizeof info->driver);
++      strncpy (info->version, DRIVER_VERSION, sizeof info->version);
++      strncpy (info->fw_version, dev->driver_info->description,
++              sizeof info->fw_version);
++      usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
++}
+-      case ETHTOOL_GLINK:             /* get link status */
+-              if (dev->driver_info->check_connect) {
+-                      struct ethtool_value    edata = { ETHTOOL_GLINK };
+-
+-                      edata.data = dev->driver_info->check_connect (dev) == 0;
+-                      if (copy_to_user (useraddr, &edata, sizeof (edata)))
+-                              return -EFAULT;
+-                      return 0;
+-              }
+-              break;
++static u32 usbnet_get_link (struct net_device *net)
++{
++      struct usbnet *dev = net->priv;
+-      case ETHTOOL_GMSGLVL: {         /* get message-level */
+-              struct ethtool_value    edata = {ETHTOOL_GMSGLVL};
++      /* If a check_connect is defined, return it's results */
++      if (dev->driver_info->check_connect)
++              return dev->driver_info->check_connect (dev) == 0;
+-              edata.data = dev->msg_level;
+-              if (copy_to_user (useraddr, &edata, sizeof (edata)))
+-                      return -EFAULT;
+-              return 0;
+-              }
++      /* Otherwise, we're up to avoid breaking scripts */
++      return 1;
++}
+-      case ETHTOOL_SMSGLVL: {         /* set message-level */
+-              struct ethtool_value    edata;
++static u32 usbnet_get_msglevel (struct net_device *net)
++{
++      struct usbnet *dev = net->priv;
+-              if (copy_from_user (&edata, useraddr, sizeof (edata)))
+-                      return -EFAULT;
+-              dev->msg_level = edata.data;
+-              return 0;
+-              }
+-      
+-      /* could also map RINGPARAM to RX/TX QLEN */
++      return dev->msg_level;
++}
+-      }
+-      /* Note that the ethtool user space code requires EOPNOTSUPP */
+-      return -EOPNOTSUPP;
++static void usbnet_set_msglevel (struct net_device *net, u32 level)
++{
++      struct usbnet *dev = net->priv;
++
++      dev->msg_level = level;
+ }
+ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+ {
+-      if (cmd == SIOCETHTOOL)
+-              return usbnet_ethtool_ioctl (net, (void __user *)rq->ifr_data);
+-
+ #ifdef NEED_MII
+       {
+       struct usbnet *dev = (struct usbnet *)net->priv;
+@@ -2889,6 +2981,7 @@
+       net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
+       net->tx_timeout = usbnet_tx_timeout;
+       net->do_ioctl = usbnet_ioctl;
++      net->ethtool_ops = &usbnet_ethtool_ops;
+       // allow device-specific bind/init procedures
+       // NOTE net->name still not usable ...
+@@ -2991,19 +3084,19 @@
+ }, {
+       // Netgear FA120
+       USB_DEVICE (0x0846, 0x1040),
+-      .driver_info =  (unsigned long) &ax8817x_info,
++      .driver_info =  (unsigned long) &netgear_fa120_info,
+ }, {
+       // DLink DUB-E100
+       USB_DEVICE (0x2001, 0x1a00),
+-      .driver_info =  (unsigned long) &ax8817x_info,
++      .driver_info =  (unsigned long) &dlink_dub_e100_info,
+ }, {
+       // Intellinet, ST Lab USB Ethernet
+       USB_DEVICE (0x0b95, 0x1720),
+-      .driver_info =  (unsigned long) &ax8817x_info,
++      .driver_info =  (unsigned long) &ax8817x_info,
+ }, {
+       // Hawking UF200, TrendNet TU2-ET100
+       USB_DEVICE (0x07b8, 0x420a),
+-      .driver_info =  (unsigned long) &ax8817x_info,
++      .driver_info =  (unsigned long) &hawking_uf200_info,
+ }, 
+ #endif
+@@ -3167,6 +3260,14 @@
+       .disconnect =   usbnet_disconnect,
+ };
++/* Default ethtool_ops assigned.  Devices can override in their bind() routine */
++static struct ethtool_ops usbnet_ethtool_ops = {
++      .get_drvinfo            = usbnet_get_drvinfo,
++      .get_link               = usbnet_get_link,
++      .get_msglevel           = usbnet_get_msglevel,
++      .set_msglevel           = usbnet_set_msglevel,
++};
++
+ /*-------------------------------------------------------------------------*/
+ static int __init usbnet_init (void)
+Index: linux-2.6.0-test5/drivers/usb/serial/ipaq.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/serial/ipaq.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/serial/ipaq.c        2003-09-27 11:38:33.183483728 +0800
+@@ -341,7 +341,7 @@
+       usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+       tty = port->tty;
+-      if (urb->actual_length) {
++      if (tty && urb->actual_length) {
+               for (i = 0; i < urb->actual_length ; ++i) {
+                       /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+Index: linux-2.6.0-test5/drivers/usb/serial/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/serial/Kconfig  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/serial/Kconfig       2003-09-27 11:38:33.216478712 +0800
+@@ -17,10 +17,8 @@
+         information on the specifics of the different devices that are
+         supported, and on how to use them.
+-        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 usbserial. 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, say M here: the
++        module will be called usbserial.
+ config USB_SERIAL_DEBUG
+       bool "USB Serial Converter verbose debug"
+@@ -70,10 +68,8 @@
+         adaptor (F5U103 is one of the model numbers) or the Peracom single
+         port USB to serial adapter.
+-        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 belkin_sa.  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, say M here: the
++        module will be called belkin_sa.
+ config USB_SERIAL_WHITEHEAT
+       tristate "USB ConnectTech WhiteHEAT Serial Driver"
+@@ -82,10 +78,8 @@
+         Say Y here if you want to use a ConnectTech WhiteHEAT 4 port
+         USB to serial converter device.
+-        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 whiteheat.  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, say M here: the
++        module will be called whiteheat.
+ config USB_SERIAL_DIGI_ACCELEPORT
+       tristate "USB Digi International AccelePort USB Serial Driver"
+@@ -99,11 +93,8 @@
+         This driver works under SMP with the usb-uhci driver.  It does not
+         work under SMP with the uhci driver.
+-        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 digi_acceleport.  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, say M here: the
++        module will be called digi_acceleport.
+ config USB_SERIAL_EMPEG
+       tristate "USB Empeg empeg-car Mark I/II Driver"
+@@ -114,10 +105,8 @@
+         device node.  See <file:Documentation/usb/usb-serial.txt> for more
+         tidbits of information.
+-        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 empeg. 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, say M here: the
++        module will be called empeg.
+ config USB_SERIAL_FTDI_SIO
+       tristate "USB FTDI Single Port Serial Driver (EXPERIMENTAL)"
+@@ -130,10 +119,8 @@
+         See <http://ftdi-usb-sio.sourceforge.net/> for more
+         information on this driver and the device.
+-        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 ftdi_sio.  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, say M here: the
++        module will be called ftdi_sio.
+ config USB_SERIAL_VISOR
+       tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver"
+@@ -144,10 +131,8 @@
+         <http://usbvisor.sourceforge.net/> for more information on using this
+         driver.
+-        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 visor. 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, say M here: the
++        module will be called visor.
+ config USB_SERIAL_IPAQ
+       tristate "USB PocketPC PDA Driver"
+@@ -158,10 +143,8 @@
+         using a USB cradle/cable. For information on using the driver,
+         read <file:Documentation/usb/usb-serial.txt>.
+-        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 ipaq. 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, say M here: the
++        module will be called ipaq.
+ config USB_SERIAL_IR
+       tristate "USB IR Dongle Serial Driver (EXPERIMENTAL)"
+@@ -171,10 +154,8 @@
+         devices.  This is useful if you do not want to use the full IrDA
+         stack.
+-        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 ir-usb. 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, say M here: the
++        module will be called ir-usb.
+ config USB_SERIAL_EDGEPORT
+       tristate "USB Inside Out Edgeport Serial Driver"
+@@ -199,10 +180,8 @@
+         Edgeport/4 DIN
+         Edgeport/16 Dual
+-        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 io_edgeport.  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, say M here: the
++        module will be called io_edgeport.
+ config USB_SERIAL_EDGEPORT_TI
+       tristate "USB Inside Out Edgeport Serial Driver (TI devices)"
+@@ -212,10 +191,8 @@
+         Networks (Digi) that are not supported by the io_edgeport driver.
+         This includes the Edgeport/1 device.
+-        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 io_ti.  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, say M here: the
++        module will be called io_ti.
+ config USB_SERIAL_KEYSPAN_PDA
+       tristate "USB Keyspan PDA Single Port Serial Driver"
+@@ -225,10 +202,8 @@
+         serial converter device.  This driver makes use of firmware
+         developed from scratch by Brian Warner.
+-        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 keyspan_pda. 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, say M here: the
++        module will be called keyspan_pda.
+ config USB_SERIAL_KEYSPAN
+       tristate "USB Keyspan USA-xxx Serial Driver"
+@@ -241,10 +216,8 @@
+         See <http://misc.nu/hugh/keyspan.html> for more information.
+-        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 keyspan. 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, say M here: the
++        module will be called keyspan.
+ config USB_SERIAL_KEYSPAN_MPR
+       bool "USB Keyspan MPR Firmware"
+@@ -337,10 +310,8 @@
+         Please read <file:Documentation/usb/usb-serial.txt> for more
+         information.
+-        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 kl5kusb105. 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, say M here: the
++        module will be called kl5kusb105.
+ config USB_SERIAL_KOBIL_SCT
+         tristate "USB KOBIL chipcard reader (EXPERIMENTAL)"
+@@ -357,10 +328,8 @@
+             - KAAN Professional
+           Note that you need a current CT-API.
+-          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 kobil_sct. 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, say M here: the
++        module will be called kobil_sct.
+ config USB_SERIAL_MCT_U232
+       tristate "USB MCT Single Port Serial Driver"
+@@ -372,10 +341,8 @@
+         This driver also works with Sitecom U232-P25 and D-Link DU-H3SP USB
+         BAY devices.
+-        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 mct_u232.  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, say M here: the
++        module will be called mct_u232.
+ config USB_SERIAL_PL2303
+       tristate "USB Prolific 2303 Single Port Serial Driver"
+@@ -384,10 +351,8 @@
+         Say Y here if you want to use the PL2303 USB Serial single port
+         adapter from Prolific.
+-        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 pl2303.  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, say M here: the
++        module will be called pl2303.
+ config USB_SERIAL_SAFE
+       tristate "USB Safe Serial (Encapsulated) Driver (EXPERIMENTAL)"
+@@ -405,10 +370,8 @@
+         reader. This is an interface to ISO 7816 compatible contactbased
+         chipcards, e.g. GSM SIMs.
+-        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 cyberjack. 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, say M here: the
++        module will be called cyberjack.
+         If unsure, say N.
+@@ -420,10 +383,8 @@
+         serial converter device.  This driver makes use of firmware
+         developed from scratch by Brian Warner.
+-        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 keyspan_pda. 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, say M here: the
++        module will be called keyspan_pda.
+ config USB_SERIAL_OMNINET
+       tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)"
+@@ -431,10 +392,8 @@
+       help
+         Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA.
+-        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 omninet. 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, say M here: the
++        module will be called omninet.
+ config USB_EZUSB
+       bool
+Index: linux-2.6.0-test5/drivers/usb/serial/usb-serial.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/serial/usb-serial.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/serial/usb-serial.c  2003-09-27 11:38:33.250473544 +0800
+@@ -871,8 +871,10 @@
+       /* the ports are cleaned up and released in port_release() */
+       for (i = 0; i < serial->num_ports; ++i)
+-              if (serial->port[i]->dev.parent != NULL)
++              if (serial->port[i]->dev.parent != NULL) {
+                       device_unregister(&serial->port[i]->dev);
++                      serial->port[i] = NULL;
++              }
+       /* If this is a "fake" port, we have to clean it up here, as it will
+        * not get cleaned up in port_release() as it was never registered with
+Index: linux-2.6.0-test5/drivers/usb/storage/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/storage/Kconfig 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/storage/Kconfig      2003-09-27 11:38:33.287467920 +0800
+@@ -15,10 +15,8 @@
+         similar devices. This driver may also be used for some cameras and
+         card readers.
+-        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 usb-storage. 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, say M here: the
++        module will be called usb-storage.
+ config USB_STORAGE_DEBUG
+       bool "USB Mass Storage verbose debug"
+Index: linux-2.6.0-test5/drivers/usb/storage/unusual_devs.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/usb/storage/unusual_devs.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/usb/storage/unusual_devs.h       2003-09-27 11:38:33.350458344 +0800
+@@ -289,7 +289,7 @@
+ UNUSUAL_DEV(  0x057b, 0x0000, 0x0000, 0x0299, 
+               "Y-E Data",
+               "Flashbuster-U",
+-              US_SC_UFI,  US_PR_CB, NULL,
++              US_SC_DEVICE,  US_PR_CB, NULL,
+               US_FL_SINGLE_LUN),
+ UNUSUAL_DEV(  0x057b, 0x0000, 0x0300, 0x9999, 
+Index: linux-2.6.0-test5/drivers/video/asiliantfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/asiliantfb.c  2003-09-27 11:38:18.464721320 +0800
++++ linux-2.6.0-test5/drivers/video/asiliantfb.c       2003-09-27 11:38:33.359456976 +0800
+@@ -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");
+Index: linux-2.6.0-test5/drivers/video/aty/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/aty/Makefile  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/aty/Makefile       2003-09-27 11:38:33.401450592 +0800
+@@ -4,4 +4,3 @@
+ 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)
+Index: linux-2.6.0-test5/drivers/video/chipsfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/chipsfb.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/chipsfb.c  2003-09-27 11:38:33.451442992 +0800
+@@ -85,7 +85,7 @@
+ /*
+  * 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 @@
+       .remove =       __devexit_p(chipsfb_remove),
+ };
+-int __init chips_init(void)
++int __init chipsfb_init(void)
+ {
+       return pci_module_init(&chipsfb_driver);
+ }
+Index: linux-2.6.0-test5/drivers/video/console/fbcon.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/console/fbcon.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/console/fbcon.c    2003-09-27 11:38:33.528431288 +0800
+@@ -195,8 +195,7 @@
+ {
+       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 @@
+       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 @@
+ }
+ /*
+- * 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 @@
+       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 @@
+       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 @@
+       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 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 @@
+               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 @@
+       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 @@
+ {
+       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 @@
+       } 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 @@
+                       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 @@
+                               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 @@
+       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 @@
+               }
+       } 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 */
+               {
+Index: linux-2.6.0-test5/drivers/video/console/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/console/Makefile      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/console/Makefile   2003-09-27 11:38:33.536430072 +0800
+@@ -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 @@
+ # 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)
++
+Index: linux-2.6.0-test5/drivers/video/controlfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/controlfb.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/controlfb.c        2003-09-27 11:38:33.589422016 +0800
+@@ -136,8 +136,8 @@
+ /*
+  * 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 @@
+ /*
+  * 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 @@
+ /*
+  * Parse user speficied options (`video=controlfb:')
+  */
+-void __init control_setup(char *options)
++void __init controlfb_setup(char *options)
+ {
+       char *this_opt;
+Index: linux-2.6.0-test5/drivers/video/epson1355fb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/epson1355fb.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/epson1355fb.c      2003-09-27 11:38:33.653412288 +0800
+@@ -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");
+Index: linux-2.6.0-test5/drivers/video/fbmem.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/fbmem.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/fbmem.c    2003-09-27 11:38:33.721401952 +0800
+@@ -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 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_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 @@
+       { "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 @@
+ #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 @@
+ #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 @@
+       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 @@
+       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 @@
+  * 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 @@
+       }
+       /* 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 @@
+            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 @@
+               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 @@
+ __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
+      */
+Index: linux-2.6.0-test5/drivers/video/g364fb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/g364fb.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/g364fb.c   2003-09-27 11:38:33.764395416 +0800
+@@ -127,20 +127,55 @@
+ 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 @@
+  */
+ 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 @@
+           (*((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 */
+Index: linux-2.6.0-test5/drivers/video/i810/i810_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/i810/i810_main.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/i810/i810_main.c   2003-09-27 11:38:33.913372768 +0800
+@@ -57,7 +57,7 @@
+ #include "i810_main.h"
+ /* PCI */
+-static const char *i810_pci_list[] __initdata = {
++static const char *i810_pci_list[] __devinitdata = {
+       "Intel(R) 810 Framebuffer Device"                                 ,
+       "Intel(R) 810-DC100 Framebuffer Device"                           ,
+       "Intel(R) 810E Framebuffer Device"                                ,
+@@ -66,7 +66,7 @@
+       "Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device"
+ };
+-static struct pci_device_id i810fb_pci_tbl[] __initdata = {
++static struct pci_device_id i810fb_pci_tbl[] = {
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3,
+@@ -1456,7 +1456,7 @@
+       return 0;
+ }
+-static struct fb_ops i810fb_ops __initdata = {
++static struct fb_ops i810fb_ops __devinitdata = {
+       .owner =             THIS_MODULE,
+       .fb_open =           i810fb_open,
+       .fb_release =        i810fb_release,
+@@ -1538,7 +1538,7 @@
+  *                  AGP resource allocation                            *
+  ***********************************************************************/
+   
+-static void __init i810_fix_pointers(struct i810fb_par *par)
++static void __devinit i810_fix_pointers(struct i810fb_par *par)
+ {
+               par->fb.physical = par->aperture.physical+(par->fb.offset << 12);
+       par->fb.virtual = par->aperture.virtual+(par->fb.offset << 12);
+@@ -1550,7 +1550,7 @@
+               (par->cursor_heap.offset << 12);
+ }
+-static void __init i810_fix_offsets(struct i810fb_par *par)
++static void __devinit i810_fix_offsets(struct i810fb_par *par)
+ {
+       if (vram + 1 > par->aperture.size >> 20)
+               vram = (par->aperture.size >> 20) - 1;
+@@ -1570,7 +1570,7 @@
+       par->cursor_heap.size = 4096;
+ }
+-static int __init i810_alloc_agp_mem(struct fb_info *info)
++static int __devinit i810_alloc_agp_mem(struct fb_info *info)
+ {
+       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       int size;
+@@ -1635,7 +1635,7 @@
+  * Sets the the user monitor's horizontal and vertical
+  * frequency limits
+  */
+-static void __init i810_init_monspecs(struct fb_info *info)
++static void __devinit i810_init_monspecs(struct fb_info *info)
+ {
+       if (!hsync1)
+               hsync1 = HFMIN;
+@@ -1663,7 +1663,7 @@
+  * @par: pointer to i810fb_par structure
+  * @info: pointer to current fb_info structure
+  */
+-static void __init i810_init_defaults(struct i810fb_par *par, 
++static void __devinit i810_init_defaults(struct i810fb_par *par, 
+                                     struct fb_info *info)
+ {
+       if (voffset) 
+@@ -1707,7 +1707,7 @@
+  * i810_init_device - initialize device
+  * @par: pointer to i810fb_par structure
+  */
+-static void __init i810_init_device(struct i810fb_par *par)
++static void __devinit i810_init_device(struct i810fb_par *par)
+ {
+       u8 reg, *mmio = par->mmio_start_virtual;
+@@ -1726,7 +1726,7 @@
+       par->mem_freq = (reg) ? 133 : 100;
+ }
+-static int __init 
++static int __devinit 
+ i810_allocate_pci_resource(struct i810fb_par *par, 
+                          const struct pci_device_id *entry)
+ {
+@@ -1831,7 +1831,7 @@
+       return 0;
+ }
+-static int __init i810fb_init_pci (struct pci_dev *dev, 
++static int __devinit i810fb_init_pci (struct pci_dev *dev, 
+                                  const struct pci_device_id *entry)
+ {
+       struct fb_info    *info;
+Index: linux-2.6.0-test5/drivers/video/i810/i810_main.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/i810/i810_main.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/i810/i810_main.h   2003-09-27 11:38:33.994360456 +0800
+@@ -14,7 +14,7 @@
+ #ifndef __I810_MAIN_H__
+ #define __I810_MAIN_H__
+-static int  __init i810fb_init_pci (struct pci_dev *dev, 
++static int  __devinit i810fb_init_pci (struct pci_dev *dev, 
+                                      const struct pci_device_id *entry);
+ static void __exit i810fb_remove_pci(struct pci_dev *dev);
+ static int i810fb_resume(struct pci_dev *dev);
+@@ -95,7 +95,7 @@
+ #ifdef CONFIG_MTRR
+ #define KERNEL_HAS_MTRR 1
+-static inline void __init set_mtrr(struct i810fb_par *par)
++static inline void __devinit set_mtrr(struct i810fb_par *par)
+ {
+       par->mtrr_reg = mtrr_add((u32) par->aperture.physical, 
+                par->aperture.size, MTRR_TYPE_WRCOMB, 1);
+Index: linux-2.6.0-test5/drivers/video/i810/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/i810/Makefile 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/i810/Makefile      2003-09-27 11:38:34.010358024 +0800
+@@ -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
+Index: linux-2.6.0-test5/drivers/video/imsttfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/imsttfb.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/imsttfb.c  2003-09-27 11:38:34.121341152 +0800
+@@ -1495,6 +1495,8 @@
+               default:
+                       printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
+                                        "contact maintainer.\n", pdev->device);
++                      release_mem_region(addr, size);
++                      kfree(info);
+                       return -ENODEV;
+       }
+Index: linux-2.6.0-test5/drivers/video/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/Kconfig       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/Kconfig    2003-09-27 11:38:34.169333856 +0800
+@@ -268,6 +268,10 @@
+         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
+@@ -423,35 +427,15 @@
+         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
+@@ -722,26 +706,40 @@
+         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"
+Index: linux-2.6.0-test5/drivers/video/logo/logo.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/logo/logo.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/logo/logo.c        2003-09-27 11:38:34.213327168 +0800
+@@ -32,8 +32,7 @@
+ 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;
+Index: linux-2.6.0-test5/drivers/video/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/Makefile      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/Makefile   2003-09-27 11:38:34.273318048 +0800
+@@ -22,7 +22,7 @@
+ 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_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
+Index: linux-2.6.0-test5/drivers/video/neofb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/neofb.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/neofb.c    2003-09-27 11:38:34.464289016 +0800
+@@ -81,9 +81,10 @@
+ #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 @@
+ };
+ #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 @@
+       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 @@
+               /*
+                * 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 @@
+ {
+       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 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 @@
+       }
+       /* 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 @@
+        * 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 @@
+               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 @@
+        * 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 @@
+        * 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 @@
+               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 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 @@
+       /*
+        * 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 @@
+       }
+       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 @@
+ 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 @@
+       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 @@
+       .fb_fillrect    = neofb_fillrect,
+       .fb_copyarea    = neofb_copyarea,
+       .fb_imageblit   = neofb_imageblit,
+-      .fb_cursor      = soft_cursor,
++      .fb_cursor      = neofb_cursor,
+ };
+ /* --------------------------------------------------------------------- */
+@@ -1650,6 +1753,7 @@
+                                  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 @@
+       /* 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 @@
+       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 @@
+       }
+       /* 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 @@
+               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);
+ }
+Index: linux-2.6.0-test5/drivers/video/platinumfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/platinumfb.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/platinumfb.c       2003-09-27 11:38:34.488285368 +0800
+@@ -104,9 +104,6 @@
+  * 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 @@
+ /* 
+  * 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 @@
+       .remove         = platinumfb_remove,
+ };
+-int __init platinum_init(void)
++int __init platinumfb_init(void)
+ {
+       of_register_driver(&platinum_driver);
+Index: linux-2.6.0-test5/drivers/video/pvr2fb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/pvr2fb.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/pvr2fb.c   2003-09-27 11:38:34.532278680 +0800
+@@ -166,6 +166,11 @@
+ 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_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 @@
+       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 @@
+                           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 @@
+                               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 @@
+ 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 @@
+       
+       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 @@
+       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 @@
+       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 @@
+                       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;
+               }
+Index: linux-2.6.0-test5/drivers/video/riva/fbdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/riva/fbdev.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/riva/fbdev.c       2003-09-27 11:38:34.667258160 +0800
+@@ -143,7 +143,17 @@
+       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 @@
+       { "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 @@
+         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 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 @@
+       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 @@
+       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 @@
+               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,11 +1602,11 @@
+       .fb_fillrect    = rivafb_fillrect,
+       .fb_copyarea    = rivafb_copyarea,
+       .fb_imageblit   = rivafb_imageblit,
+-      .fb_cursor      = rivafb_cursor,        
++      .fb_cursor      = soft_cursor,
+       .fb_sync        = rivafb_sync,
+ };
+-static int __init riva_set_fbinfo(struct fb_info *info)
++static int __devinit riva_set_fbinfo(struct fb_info *info)
+ {
+       struct riva_par *par = (struct riva_par *) info->par;
+       unsigned int cmap_len;
+@@ -1603,6 +1633,15 @@
+       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;
+ }
+@@ -1726,7 +1765,7 @@
+  *
+  * ------------------------------------------------------------------------- */
+-static int __init rivafb_probe(struct pci_dev *pd,
++static int __devinit rivafb_probe(struct pci_dev *pd,
+                               const struct pci_device_id *ent)
+ {
+       struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
+Index: linux-2.6.0-test5/drivers/video/riva/nv_type.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/riva/nv_type.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/riva/nv_type.h     2003-09-27 11:38:34.708251928 +0800
+@@ -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)
+Index: linux-2.6.0-test5/drivers/video/sis/300vtbl.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/300vtbl.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/300vtbl.h      2003-09-27 11:38:34.786240072 +0800
+@@ -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 @@
+       {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 @@
+       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 @@
+       {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 @@
+ 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 @@
+  {{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 @@
+  {{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 @@
+  {{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 @@
+    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 @@
+       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 @@
+       { 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 @@
+       { 0x37,0x61,0x80,100}
+ };
++#ifdef LINUXBIOS
+ typedef struct _SiS300_ECLKDataStruct
+ {
+       UCHAR SR2E,SR2F,SR30;
+@@ -954,6 +640,7 @@
+       { 0x54,0x43,0x80,100},
+       { 0x54,0x43,0x80,100}
+ };
++#endif
+ typedef struct _SiS300_VCLKDataStruct
+ {
+@@ -964,71 +651,77 @@
+ 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 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 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 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 @@
+ 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 @@
+       {    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 @@
+       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 @@
+       {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 @@
+       {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 @@
+ 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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {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 @@
+       {   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 @@
+         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 @@
+         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 @@
+       {{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 @@
+         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 @@
+         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 @@
+         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 @@
+         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 @@
+         0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+         0x01 }}
+ };
+-/* TW: New end */
+-/* TW: New */
+ typedef struct _SiS300_CHTVRegDataStruct
+ {
+       UCHAR Reg[16];
+@@ -3361,9 +2087,7 @@
+       {{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_CHTVVCLKOPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+ static const UCHAR SiS300_CHTVVCLKSOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
+-/* TW: New end */
+Index: linux-2.6.0-test5/drivers/video/sis/310vtbl.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/310vtbl.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/310vtbl.h      2003-09-27 11:38:34.911221072 +0800
+@@ -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 @@
+       {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 @@
+       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 @@
+       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 @@
+  {{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 @@
+    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 @@
+       { 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 @@
+       { 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 @@
+       { 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 @@
+       { 0x37,0x22,0x82,133}
+ };
++#ifdef LINUXBIOS
+ typedef struct _SiS310_ECLKDataStruct
+ {
+       UCHAR SR2E,SR2F,SR30;
+@@ -1011,6 +607,7 @@
+       { 0x5c,0x23,0x01,166},
+       { 0x5c,0x23,0x01,166}
+ };
++#endif
+ typedef struct _SiS310_VCLKDataStruct
+ {
+@@ -1020,22 +617,22 @@
+ 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 @@
+       { 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 @@
+       { 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 @@
+       { 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 @@
+       { 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 @@
+ 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 @@
+       { 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 @@
+       { 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 @@
+       { 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_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 @@
+       {    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 @@
+       {    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 @@
+       {    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 @@
+       {    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 @@
+       {{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 @@
+       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 @@
+       {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 @@
+       {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 @@
+       { 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 @@
+       { 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 @@
+       {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 @@
+       {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 @@
+       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 @@
+       { 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 @@
+       { 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 @@
+       { 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 @@
+       {   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 @@
+       { 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 @@
+       { 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 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 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 @@
+  {{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 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 @@
+  {{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  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  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  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  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  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  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  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  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  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  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  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  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 @@
+       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 @@
+    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 @@
+ #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 @@
+       {{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 @@
+       {{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 @@
+       {{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 @@
+       {{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 @@
+       {{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];
+Index: linux-2.6.0-test5/drivers/video/sis/init301.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init301.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init301.c      2003-09-27 11:38:35.072196600 +0800
+@@ -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_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 @@
+       return(TRUE);
+    }
+-   if(SiS_Pr->UseCustomMode) return(FALSE);
+-   
+    SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                    HwDeviceExtension);
+@@ -153,9 +140,9 @@
+                  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 @@
+                             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 @@
+    }
+ #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 @@
+     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 @@
+     }
+ }
+-/* 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 @@
+   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 @@
+ #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 @@
+               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 @@
+                                }
+                     }
+                  }
++#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 @@
+       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 @@
+          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 @@
+                  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_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 @@
+                     }
+                  }
+               }
+-              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 @@
+                     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 @@
+      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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+   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_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 @@
+ #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 @@
+   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 @@
+                  } 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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+                           tempcx = 0x0003;
+ #endif
+                     } else {
+-                          tempcx = 0x0002;   /* TW: A901; sometimes 0x0003; */
++                          tempcx = 0x0002;   /* A901; sometimes 0x0003; */
+                     }
+                  } else tempcx = 0x0003;
+            }
+@@ -1319,26 +1353,33 @@
+   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 @@
+   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 @@
+       }
+       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 @@
+       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 @@
+   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 @@
+      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 @@
+ #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 @@
+   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_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 @@
+   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 @@
+   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 @@
+   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 @@
+  
+   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 @@
+   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 @@
+      }
+   } 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 @@
+   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_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 @@
+   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 @@
+   } 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 @@
+   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 @@
+   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 @@
+   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 @@
+     } 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 @@
+             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 @@
+          } 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 @@
+       } 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 @@
+    }
+ }
+-/* 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 @@
+   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 @@
+                                               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 @@
+     }
+     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 @@
+     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 @@
+        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_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 @@
+        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 @@
+               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 @@
+ }
+ #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 @@
+   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 @@
+      /* 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 @@
+   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 @@
+   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 @@
+   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 @@
+     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 @@
+   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 @@
+       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 @@
+      } 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 @@
+         }
+      }
+   }
+-  return;
++
+ }
+ void
+@@ -2757,11 +2848,11 @@
+   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 @@
+         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 @@
+      }
+   }
+   
+-  /* 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 @@
+ #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 @@
+     } 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 @@
+       }
+       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 @@
+     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 @@
+       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 @@
+       } else {
+-              /* --- 310 series --- */
++              /* ---- 315 series ---- */
+                       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+@@ -2956,9 +3046,9 @@
+                       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 @@
+                     }
+          }
+       }
+-      /* 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 @@
+       } 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 @@
+   }
+-  /* 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 @@
+           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 @@
+             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 @@
+           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 @@
+                             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 @@
+    } 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 @@
+       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 @@
+   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 @@
+   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_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 @@
+       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_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 @@
+     } 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 @@
+   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 @@
+ {
+   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 @@
+                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 @@
+   } 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 @@
+   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 @@
+                       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 @@
+                       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 @@
+               
+       }
+-      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 @@
+       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 @@
+               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 @@
+               } 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 @@
+       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 @@
+ 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 @@
+   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 @@
+ 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 @@
+   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 @@
+   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 @@
+       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 @@
+   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 @@
+       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 @@
+       }
+       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 @@
+ {
+   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 @@
+   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 @@
+   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 @@
+                       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 @@
+          }
+       }
+       
+-      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 @@
+                   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_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 @@
+       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_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 @@
+ #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 @@
+   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 @@
+ #ifdef SIS315H     
+       temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+-                      RefreshRateTableIndex,&ResInfo,&DisplayType);
++                      RefreshRateTableIndex,&ResIndex,&DisplayType);
+       if(temp == 0)  return;
+@@ -4795,16 +4952,16 @@
+               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 @@
+   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 @@
+ 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_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 @@
+   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 @@
+         } 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 @@
+             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 @@
+               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 @@
+             } 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 @@
+             }
+-            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_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_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 @@
+       }
+-      } 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_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 @@
+             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 @@
+     } 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_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 @@
+       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_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_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 @@
+ }
+-/* TW: Checked against all BIOSes */
+ void
+ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+@@ -5400,7 +5585,7 @@
+   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 @@
+       } 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 @@
+                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 @@
+           }
+           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_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_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 @@
+       }
+-    } 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 @@
+        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_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_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 @@
+        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 @@
+ {
+   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 @@
+ {
+   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 @@
+   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 @@
+   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 @@
+ #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_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 @@
+   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 @@
+   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 @@
+       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 @@
+   }
+ }
+-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 @@
+      }
+   }
+-  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 @@
+   }
+   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_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 @@
+         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_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 @@
+   }
+ #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_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 @@
+   } else {
+     SiS_LongWait(SiS_Pr);
+   }
+-  return;
+ }
+ void
+@@ -6803,7 +7034,7 @@
+ #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 @@
+ /* ========================================================= */
+-/* 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 @@
+ #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 @@
+   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 @@
+   
+   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 @@
+      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 @@
+   }
+   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_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_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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+      }
+   }
+-  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_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 @@
+      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 @@
+       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_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 @@
+   
+   /* 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_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 @@
+         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_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 @@
+       }
+      }
+-     /* 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 @@
+        * 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 @@
+     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 @@
+   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 @@
+   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_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 @@
+   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 @@
+      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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+          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_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 @@
+        }
+        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 @@
+                  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 @@
+      }
+   } 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 @@
+                 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 @@
+      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 @@
+                  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 @@
+                               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 @@
+                               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 @@
+               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 @@
+                         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 @@
+ #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 @@
+   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 @@
+                 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 @@
+     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 @@
+ 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 @@
+            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 @@
+ 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 @@
+ }
+ #endif
+-/* TW: Start of Chrontel 70xx functions ---------------------- */
++/* Start of Chrontel 70xx functions ---------------------- */
+ /* Set-up the Chrontel Registers */
+ void
+@@ -8890,44 +9215,44 @@
+   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_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 @@
+          }
+        }
+      } 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 @@
+ #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 @@
+ #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 @@
+ {
+   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 @@
+   }
+ }
+-#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 @@
+         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 @@
+   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_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 @@
+        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 @@
+        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 @@
+      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 @@
+ 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 @@
+   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 @@
+   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 @@
+   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 @@
+      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 @@
+          }
+         }
+      }
++#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 @@
+       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 @@
+         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 @@
+         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 @@
+ #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 @@
+ {
+    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 @@
+ {
+    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_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 @@
+ }
+ 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 @@
+    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 @@
+    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 @@
+  */
+ 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 @@
+    /* 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 @@
+       }
+       
+       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 @@
+               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 @@
+               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 @@
+                  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 @@
+        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 @@
+    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 @@
+    /* 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 @@
+               "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 @@
+               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 @@
+ 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_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 @@
+   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 @@
+   }
+ }
+-/* 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 @@
+   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 @@
+   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 @@
+ }
+ 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 @@
+   index *= 3;
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
+-
+   return index;
+ }
+@@ -10945,8 +11332,9 @@
+ 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 @@
+         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 @@
+         }
+      }
+   } 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 @@
+   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 @@
+   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 @@
+   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 @@
+                  }
+               }
+          }
++       /* 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 @@
+   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 @@
+    */
+   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 @@
+      }
+   }
+-  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 @@
+                   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 @@
+ }
+ /* 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 @@
+   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 @@
+       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_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 @@
+       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 @@
+   }
+ }
+-#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 @@
+   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 @@
+ {
+   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 @@
+ 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 @@
+ 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);
+        }
+   }
+ }
+Index: linux-2.6.0-test5/drivers/video/sis/init301.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init301.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init301.h      2003-09-27 11:38:35.081195232 +0800
+@@ -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 @@
+                          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 @@
+ 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 @@
+                             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_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_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   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
+Index: linux-2.6.0-test5/drivers/video/sis/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init.c 2003-09-27 11:38:35.169181856 +0800
+@@ -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 @@
+ 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 @@
+    } 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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+ 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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+       (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 @@
+       (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 @@
+    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 @@
+    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 @@
+       (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 @@
+ #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 @@
+ #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 @@
+    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 @@
+    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 @@
+       (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 @@
+    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 @@
+    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 @@
+       (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 @@
+             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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+    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 @@
+ /* 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 @@
+    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 @@
+    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 @@
+    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 @@
+       }
+    }
+-   /* 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 @@
+      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 @@
+       }
+    }
+-   /* 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 @@
+       }
+    }
+-   /* 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 @@
+    
+    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 @@
+ #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 @@
+    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 @@
+    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 @@
+        }
+    }
+    
+-   /* 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 @@
+    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 @@
+      }
+    }
+-   /* 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 @@
+      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 @@
+       }
+    }
+-   /* 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 @@
+ #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 @@
+    }
+ #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 @@
+ }
+ 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_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 @@
+     }
+   }
++  /* 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 @@
+ 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 @@
+     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 @@
+    return TRUE;
+ }
+-/* For SiS 300 oem util: Search VBModeID */
+ BOOLEAN
+ SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
+ {
+@@ -2946,6 +3140,81 @@
+    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 @@
+       (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 @@
+       }
+       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 @@
+   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 @@
+      /* 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 @@
+       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 @@
+ 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 @@
+   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 @@
+   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 @@
+   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 @@
+   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 @@
+      } 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 @@
+         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 @@
+     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 @@
+     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 @@
+   } 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_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 @@
+ #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_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 @@
+ }
+ #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 @@
+    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 @@
+    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 @@
+                               | (((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 @@
+       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 @@
+       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 @@
+    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 @@
+       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 @@
+       }
+       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 @@
+               ( (((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 @@
+       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 @@
+        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 @@
+        current->VTotal >>= 1;
+       }
++#if 0
+       if((backup = xalloc(sizeof(DisplayModeRec)))) {
+          if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
+        else {
+@@ -5458,6 +5687,7 @@
+        backup->Flags = current->Flags;
+        backup->Clock = current->Clock;
+       }
++#endif
+ #ifdef TWDEBUG
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+@@ -5470,6 +5700,187 @@
+       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 @@
+     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 @@
+     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 @@
+     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 @@
+         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;       
+ }                       
+Index: linux-2.6.0-test5/drivers/video/sis/initdef.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/initdef.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/initdef.h      2003-09-27 11:38:35.183179728 +0800
+@@ -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
+Index: linux-2.6.0-test5/drivers/video/sis/init.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/init.h    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/init.h 2003-09-27 11:38:35.204176536 +0800
+@@ -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 @@
+       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_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_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_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 @@
+                             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
+Index: linux-2.6.0-test5/drivers/video/sis/oem300.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/oem300.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/oem300.h       2003-09-27 11:38:35.233172128 +0800
+@@ -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_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
++
++
++
++
++
+Index: linux-2.6.0-test5/drivers/video/sis/oem310.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/oem310.h  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/oem310.h       2003-09-27 11:38:35.261167872 +0800
+@@ -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_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 @@
+  }
+ };
++/* 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}}
++};
++
+Index: linux-2.6.0-test5/drivers/video/sis/osdef.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/osdef.h   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/osdef.h        2003-09-27 11:38:35.297162400 +0800
+@@ -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
+Index: linux-2.6.0-test5/drivers/video/sis/sis_accel.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_accel.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_accel.c    2003-09-27 11:38:35.334156776 +0800
+@@ -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 @@
+       SiS300DoCMD
+ }
+-/* 310/325 series ------------------------------------------------ */
++/* 315 series ---------------------------------------------------- */
+ static void
+ SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
+@@ -230,7 +230,7 @@
+               /* 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 @@
+     }
+ }
+-#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 @@
+    if(!rect->width || !rect->height)
+       return;
+-   if(!sisfb_accel) {
++   if(!ivideo.accel) {
+       cfb_fillrect(info, rect);
+       return;
+    }
+@@ -388,7 +390,7 @@
+    CRITFLAGS
+    TWDEBUG("Inside sis_copyarea");
+-   if(!sisfb_accel) {
++   if(!ivideo.accel) {
+       cfb_copyarea(info, area);
+       return;
+    }
+@@ -418,7 +420,7 @@
+ #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 @@
+ #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
+Index: linux-2.6.0-test5/drivers/video/sis/sis_accel.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_accel.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_accel.h    2003-09-27 11:38:35.395147504 +0800
+@@ -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 @@
+-/* ----------- SiS 310/325 series --------------- */
++/* -------------- SiS 315 series --------------- */
+ /* Q_STATUS:
+    bit 31 = 1: All engines idle and all queues empty
+@@ -342,16 +342,27 @@
+    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) \
+Index: linux-2.6.0-test5/drivers/video/sis/sis_main.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_main.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_main.c     2003-09-27 11:38:35.516129112 +0800
+@@ -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 @@
+       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 @@
+       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 @@
+               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 @@
+ /* ------------------ 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 @@
+    }
+ #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 @@
+               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 @@
+               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 @@
+               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 @@
+               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 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 @@
+    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 @@
+       }
+       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 @@
+               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 @@
+               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 @@
+               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 @@
+       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 @@
+                       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 @@
+ 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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+               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 @@
+       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 @@
+       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 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 @@
+       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 @@
+       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 @@
+       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 @@
+ {
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 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 @@
+               rc = 256;       
+               break;
+       case 16:
+-              rc = 16;        
+-              break;          
+       case 32:
+               rc = 16;
+-              break;  
++              break;
+       }
+       return rc;
+ }
+@@ -1596,7 +1953,7 @@
+               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 @@
+ {
+       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 @@
+       }
+       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 @@
+       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 @@
+           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 @@
+       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 @@
+       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 @@
+                               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 @@
+       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 @@
+ #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 @@
+       .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 @@
+       } 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 @@
+       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 @@
+       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 @@
+                              "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 @@
+                                       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 @@
+ #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 @@
+               reg >>= 2;
+               
+               if(ivideo.chip == SIS_330) {
+-              
++
+                  if(reg) ivideo.video_size <<= 1;
+               
+               } else {
+@@ -2470,7 +2738,7 @@
+                     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 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 @@
+     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 @@
+          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 @@
+             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 @@
+ 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 @@
+       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 @@
+       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 @@
+  *     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 @@
+ #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 @@
+ #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 @@
+               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 @@
+               *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 @@
+               req->offset = poh->offset;
+               req->size = poh->size;
+       }
+-
+ }
+ void sis_free(unsigned long base)
+@@ -3352,35 +3806,70 @@
+ 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 @@
+       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_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 @@
+               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 @@
+                               }
+                       }
+-              } 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 @@
+               }
+               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 @@
+                       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 @@
+ #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 @@
+               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 @@
+         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 @@
+                     }
+                 }
+               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 pdev_valid = 0;
+       u32 reg32;
+       u16 reg16;
+-      u8  reg, reg1;
++      u8  reg;
+       /* outb(0x77, 0x80); */  /* What is this? */
+@@ -3751,18 +4271,24 @@
+       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 @@
+               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 @@
+                       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 @@
+               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 @@
+         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 @@
+ #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 @@
+       }
+ #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 @@
+                  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 @@
+       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 @@
+       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 @@
+ #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 @@
+ #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 @@
+               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 @@
+               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 @@
+                        &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 @@
+                  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 @@
+               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 @@
+               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 @@
+ #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 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          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 @@
+        "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 @@
+       "\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(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(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 @@
+       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 @@
+       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 @@
+          }
+       }
++      sisfb_nocrt2rate = nocrt2rate;
++
++      if(specialtiming)
++              sisfb_search_specialtiming(specialtiming);
++
+       if((err = sisfb_init()) < 0) return err;
+       return 0;
+@@ -4788,7 +5332,7 @@
+       /* 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 @@
+       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");
+ }
+Index: linux-2.6.0-test5/drivers/video/sis/sis_main.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/sis_main.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/sis_main.h     2003-09-27 11:38:35.546124552 +0800
+@@ -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 @@
+ } 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 @@
+ 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 @@
+       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 @@
+       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 @@
+       {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 @@
+       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 @@
+       {"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 @@
+ /* 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 @@
+       {"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 @@
+       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 @@
+       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 @@
+     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_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 int           filter = -1;
+ static unsigned char filter_tb;
+-//~Eden Chen
+-/* ---------------------- Routine prototypes ------------------------- */
++/* ---------------------- Prototypes ------------------------- */
+ /* Interface used by the world */
+ #ifndef MODULE
+@@ -894,10 +1053,6 @@
+                                    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 @@
+                        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 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  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 @@
+ /* 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_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);                    
+Index: linux-2.6.0-test5/drivers/video/sis/vgatypes.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/vgatypes.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/vgatypes.h     2003-09-27 11:38:35.552123640 +0800
+@@ -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 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 @@
+     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 @@
+     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 @@
+     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 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 @@
+                                  /* 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 @@
+                                  /* 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 @@
+                                  /*             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 @@
+ #endif
+ };
+ #endif
+-#endif 
+ /* TW: Addtional IOCTL for communication sisfb <> X driver        */
+@@ -284,12 +312,16 @@
+       
+       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 @@
+     MaximumBusDataType
+ } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
+ #endif
+-#endif /* WINCE_HEADER */
+ #ifndef PCI_TYPE0_ADDRESSES
+ #define PCI_TYPE0_ADDRESSES             6
+@@ -317,7 +348,6 @@
+ #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 @@
+ } 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 @@
+ #ifndef PCI_COMMON_HDR_LENGTH
+ #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
+ #endif
+-#endif
+ #endif
++
+Index: linux-2.6.0-test5/drivers/video/sis/vstruct.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/sis/vstruct.h 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/sis/vstruct.h      2003-09-27 11:38:35.602116040 +0800
+@@ -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 @@
+       UCHAR  CR[15];
+ } SiS_LVDSCRT1DataStruct;
+-/*add for LCDA*/
+ typedef struct _SiS_LCDACRT1DataStruct
+ {
+       UCHAR  CR[17];
+@@ -111,9 +144,7 @@
+       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 @@
+       UCHAR  ModeID;
+       USHORT XRes;
+       USHORT YRes;
+-      USHORT ROM_OFFSET;
+ } SiS_Ext2Struct;
+ typedef struct _SiS_Part2PortTblStruct
+@@ -183,6 +213,15 @@
+ 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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       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 @@
+       const UCHAR *SiS_CHTVVCLKUPALN;
+       const UCHAR *SiS_CHTVVCLKOPALN;
+       const UCHAR *SiS_CHTVVCLKSOPAL;
++
++      USHORT  PanelXRes;
++      USHORT  PanelYRes;
+       
+       BOOLEAN UseCustomMode;
+       BOOLEAN CRT1UsesCustomMode;
+@@ -560,8 +629,11 @@
+       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 @@
+       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
+Index: linux-2.6.0-test5/drivers/video/skeletonfb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/skeletonfb.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/skeletonfb.c       2003-09-27 11:38:35.705100384 +0800
+@@ -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 @@
+ 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;
+ }
+ /**
+Index: linux-2.6.0-test5/drivers/video/softcursor.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/softcursor.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/softcursor.c       2003-09-27 11:38:35.726097192 +0800
+@@ -21,8 +21,13 @@
+ {
+       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 @@
+               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;
+ }
+Index: linux-2.6.0-test5/drivers/video/valkyriefb.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/video/valkyriefb.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/drivers/video/valkyriefb.c       2003-09-27 11:38:35.756092632 +0800
+@@ -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>
+Index: linux-2.6.0-test5/fs/adfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/adfs/super.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/adfs/super.c  2003-09-27 11:38:35.810084424 +0800
+@@ -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 @@
+       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;
+               }
+       }
+Index: linux-2.6.0-test5/fs/affs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/affs/super.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/affs/super.c  2003-09-27 11:38:35.856077432 +0800
+@@ -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 @@
+       .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 @@
+       *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
+Index: linux-2.6.0-test5/fs/afs/cache.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cache.h      2003-09-27 11:38:18.465721168 +0800
++++ linux-2.6.0-test5/fs/afs/cache.h   2003-09-27 11:38:35.857077280 +0800
+@@ -0,0 +1,27 @@
++/* cache.h: AFS local cache management interface
++ *
++ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.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.
++ */
++
++#ifndef _LINUX_AFS_CACHE_H
++#define _LINUX_AFS_CACHE_H
++
++#undef AFS_CACHING_SUPPORT
++
++#include <linux/mm.h>
++#ifdef AFS_CACHING_SUPPORT
++#include <linux/cachefs.h>
++#endif
++#include "types.h"
++
++#ifdef __KERNEL__
++
++#endif /* __KERNEL__ */
++
++#endif /* _LINUX_AFS_CACHE_H */
+Index: linux-2.6.0-test5/fs/afs/callback.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/callback.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/callback.c        2003-09-27 11:38:35.918068008 +0800
+@@ -68,7 +68,7 @@
+                       spin_unlock(&vnode->lock);
+                       iput(inode);
+-                      if (release) afs_put_server(server);
++                      afs_put_server(server);
+                       spin_lock(&server->cb_lock);
+               }
+Index: linux-2.6.0-test5/fs/afs/cell.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cell.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/cell.c    2003-09-27 11:38:35.975059344 +0800
+@@ -36,6 +36,19 @@
+ MODULE_PARM(rootcell,"s");
+ MODULE_PARM_DESC(rootcell,"root AFS cell name and VL server IP addr list");
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry);
++static void afs_cell_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_cache_cell_index_def = {
++      .name                   = "cell_ix",
++      .data_size              = sizeof(afs_cell_t),
++      .keys[0]                = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
++      .match                  = afs_cell_cache_match,
++      .update                 = afs_cell_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+  * create a cell record
+@@ -65,7 +78,6 @@
+       atomic_set(&cell->usage,0);
+       INIT_LIST_HEAD(&cell->link);
+-      INIT_LIST_HEAD(&cell->caches);
+       rwlock_init(&cell->sv_lock);
+       INIT_LIST_HEAD(&cell->sv_list);
+@@ -96,7 +108,7 @@
+               cell->vl_addrs[cell->vl_naddrs++].s_addr =
+                       htonl((a<<24)|(b<<16)|(c<<8)|d);
+-              if (cell->vl_naddrs>=16)
++              if (cell->vl_naddrs >= AFS_CELL_MAX_ADDRS)
+                       break;
+       } while(vllist=next, vllist);
+@@ -106,6 +118,14 @@
+       if (ret<0)
+               goto error;
++#ifdef AFS_CACHING_SUPPORT
++      /* put it up for caching */
++      cachefs_acquire_cookie(afs_cache_netfs.primary_index,
++                             &afs_vlocation_cache_index_def,
++                             cell,
++                             &cell->cache);
++#endif
++
+       /* add to the cell lists */
+       write_lock(&afs_cells_lock);
+       list_add_tail(&cell->link,&afs_cells);
+@@ -166,36 +186,45 @@
+ /*
+  * lookup a cell record
+  */
+-int afs_cell_lookup(const char *name, afs_cell_t **_cell)
++int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
+ {
+       struct list_head *_p;
+       afs_cell_t *cell;
++      int ret;
+-      _enter("\"%s\",",name?name:"*thiscell*");
++      _enter("\"%*.*s\",", namesz, namesz, name ? name : "");
+-      cell = afs_cell_root;
++      *_cell = NULL;
+       if (name) {
+               /* if the cell was named, look for it in the cell record list */
++              ret = -ENOENT;
+               cell = NULL;
+               read_lock(&afs_cells_lock);
+               list_for_each(_p,&afs_cells) {
+-                      cell = list_entry(_p,afs_cell_t,link);
+-                      if (strcmp(cell->name,name)==0)
++                      cell = list_entry(_p, struct afs_cell, link);
++                      if (strncmp(cell->name, name, namesz) == 0) {
++                              afs_get_cell(cell);
+                               break;
++                      }
+                       cell = NULL;
+               }
+               read_unlock(&afs_cells_lock);
+-      }
+-      if (cell)
++              if (cell)
++                      ret = 0;
++      }
++      else {
++              cell = afs_cell_root;
+               afs_get_cell(cell);
++              ret = 0;
++      }
+       *_cell = cell;
+-      _leave(" = %d (%p)",cell?0:-ENOENT,cell);
+-      return cell ? 0 : -ENOENT;
++      _leave(" = %d (%p)", ret, cell);
++      return ret;
+ } /* end afs_cell_lookup() */
+@@ -211,8 +240,8 @@
+       cell = *_cell;
+       if (cell && !list_empty(&cell->link))
+-              atomic_inc(&cell->usage);
+-      else 
++              afs_get_cell(cell);
++      else
+               cell = NULL;
+       write_unlock(&afs_cells_lock);
+@@ -226,6 +255,9 @@
+  */
+ void afs_put_cell(afs_cell_t *cell)
+ {
++      if (!cell)
++              return;
++
+       _enter("%p{%d,%s}",cell,atomic_read(&cell->usage),cell->name);
+       /* sanity check */
+@@ -278,6 +310,10 @@
+       list_del_init(&cell->proc_link);
+       up_write(&afs_proc_cells_sem);
++#ifdef AFS_CACHING_SUPPORT
++      cachefs_relinquish_cookie(cell->cache,0);
++#endif
++
+       up_write(&afs_cells_sem);
+       if (!list_empty(&cell->sv_list))        BUG();
+@@ -377,8 +413,7 @@
+       _enter("");
+-      if (afs_cell_root)
+-              afs_put_cell(afs_cell_root);
++      afs_put_cell(afs_cell_root);
+       while (!list_empty(&afs_cells)) {
+               cell = NULL;
+@@ -450,3 +485,46 @@
+       _leave("");
+ } /* end afs_cell_purge() */
++
++/*****************************************************************************/
++/*
++ * match a cell record obtained from the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry)
++{
++      const struct afs_cache_cell *ccell = entry;
++      struct afs_cell *cell = target;
++
++      _enter("{%s},{%s}", ccell->name, cell->name);
++
++      if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) {
++              _leave(" = SUCCESS");
++              return CACHEFS_MATCH_SUCCESS;
++      }
++
++      _leave(" = FAILED");
++      return CACHEFS_MATCH_FAILED;
++} /* end afs_cell_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a cell record in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_cell_cache_update(void *source, void *entry)
++{
++      struct afs_cache_cell *ccell = entry;
++      struct afs_cell *cell = source;
++
++      _enter("%p,%p", source, entry);
++
++      strncpy(ccell->name, cell->name, sizeof(ccell->name));
++
++      memcpy(ccell->vl_servers,
++             cell->vl_addrs,
++             min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
++
++} /* end afs_cell_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/cell.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cell.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/cell.h    2003-09-27 11:38:35.978058888 +0800
+@@ -13,11 +13,24 @@
+ #define _LINUX_AFS_CELL_H
+ #include "types.h"
++#include "cache.h"
++
++#define AFS_CELL_MAX_ADDRS 15
+ extern volatile int afs_cells_being_purged; /* T when cells are being purged by rmmod */
+ /*****************************************************************************/
+ /*
++ * entry in the cached cell catalogue
++ */
++struct afs_cache_cell
++{
++      char                    name[64];       /* cell name (padded with NULs) */
++      struct in_addr          vl_servers[15]; /* cached cell VL servers */
++};
++
++/*****************************************************************************/
++/*
+  * AFS cell record
+  */
+ struct afs_cell
+@@ -26,7 +39,9 @@
+       struct list_head        link;           /* main cell list link */
+       struct list_head        proc_link;      /* /proc cell list link */
+       struct proc_dir_entry   *proc_dir;      /* /proc dir for this cell */
+-      struct list_head        caches;         /* list of caches currently backing this cell */
++#ifdef AFS_CACHING_SUPPORT
++      struct cachefs_cookie   *cache;         /* caching cookie */
++#endif
+       /* server record management */
+       rwlock_t                sv_lock;        /* active server list lock */
+@@ -41,22 +56,22 @@
+       spinlock_t              vl_gylock;      /* graveyard lock */
+       unsigned short          vl_naddrs;      /* number of VL servers in addr list */
+       unsigned short          vl_curr_svix;   /* current server index */
+-      struct in_addr          vl_addrs[16];   /* cell VL server addresses */
++      struct in_addr          vl_addrs[AFS_CELL_MAX_ADDRS];   /* cell VL server addresses */
+       char                    name[0];        /* cell name - must go last */
+ };
+ extern int afs_cell_init(void);
+-extern int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell);
++extern int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell);
+-extern int afs_cell_lookup(const char *name, afs_cell_t **_cell);
++extern int afs_cell_lookup(const char *name, unsigned nmsize, struct afs_cell **_cell);
+ #define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
+-extern afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell);
++extern struct afs_cell *afs_get_cell_maybe(struct afs_cell **_cell);
+-extern void afs_put_cell(afs_cell_t *cell);
++extern void afs_put_cell(struct afs_cell *cell);
+ extern void afs_cell_purge(void);
+Index: linux-2.6.0-test5/fs/afs/cmservice.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/cmservice.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/cmservice.c       2003-09-27 11:38:35.982058280 +0800
+@@ -119,6 +119,7 @@
+       int die;
+       printk("kAFS: Started kafscmd %d\n",current->pid);
++
+       daemonize("kafscmd");
+       complete(&kafscmd_alive);
+@@ -293,15 +294,20 @@
+       down_write(&afscm_sem);
+       if (!afscm_usage) {
+-              ret = kernel_thread(kafscmd,NULL,0);
+-              if (ret<0)
++              ret = kernel_thread(kafscmd, NULL, 0);
++              if (ret < 0)
+                       goto out;
+               wait_for_completion(&kafscmd_alive);
+-              ret = rxrpc_add_service(afs_transport,&AFSCM_service);
++              ret = rxrpc_add_service(afs_transport, &AFSCM_service);
+               if (ret<0)
+                       goto kill;
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++              afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
++                                      afs_mntpt_expiry_timeout * HZ);
++#endif
+       }
+       afscm_usage++;
+@@ -330,17 +336,20 @@
+       down_write(&afscm_sem);
+-      if (afscm_usage==0) BUG();
++      if (afscm_usage == 0) BUG();
+       afscm_usage--;
+-      if (afscm_usage==0) {
++      if (afscm_usage == 0) {
+               /* don't want more incoming calls */
+-              rxrpc_del_service(afs_transport,&AFSCM_service);
++              rxrpc_del_service(afs_transport, &AFSCM_service);
+               /* abort any calls I've still got open (the afscm_error() will dequeue them) */
+               spin_lock(&afscm_calls_lock);
+               while (!list_empty(&afscm_calls)) {
+-                      call = list_entry(afscm_calls.next,struct rxrpc_call,app_link);
++                      call = list_entry(afscm_calls.next,
++                                        struct rxrpc_call,
++                                        app_link);
++
+                       list_del_init(&call->app_link);
+                       rxrpc_get_call(call);
+                       spin_unlock(&afscm_calls_lock);
+@@ -348,7 +357,8 @@
+                       rxrpc_call_abort(call,-ESRCH); /* abort, dequeue and put */
+                       _debug("nuking active call %08x.%d",
+-                             ntohl(call->conn->conn_id),ntohl(call->call_id));
++                             ntohl(call->conn->conn_id),
++                             ntohl(call->call_id));
+                       rxrpc_put_call(call);
+                       rxrpc_put_call(call);
+@@ -376,6 +386,10 @@
+                       spin_lock(&kafscmd_attention_lock);
+               }
+               spin_unlock(&kafscmd_attention_lock);
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++              afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
++#endif
+       }
+       up_write(&afscm_sem);
+@@ -490,7 +504,7 @@
+       if (ret<0)
+               rxrpc_call_abort(call,ret);
+-      if (server) afs_put_server(server);
++      afs_put_server(server);
+       _leave(" = %d",ret);
+@@ -556,7 +570,7 @@
+       if (ret<0)
+               rxrpc_call_abort(call,ret);
+-      if (server) afs_put_server(server);
++      afs_put_server(server);
+       _leave(" = %d",ret);
+@@ -622,7 +636,7 @@
+       if (ret<0)
+               rxrpc_call_abort(call,ret);
+-      if (server) afs_put_server(server);
++      afs_put_server(server);
+       _leave(" = %d",ret);
+Index: linux-2.6.0-test5/fs/afs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/dir.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/dir.c     2003-09-27 11:38:35.993056608 +0800
+@@ -23,10 +23,11 @@
+ #include "super.h"
+ #include "internal.h"
+-static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
++static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
++                                   struct nameidata *nd);
+ static int afs_dir_open(struct inode *inode, struct file *file);
+ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
+-static int afs_d_revalidate(struct dentry *dentry, struct nameidata *);
++static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
+ static int afs_d_delete(struct dentry *dentry);
+ static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, loff_t fpos,
+                                    ino_t ino, unsigned dtype);
+@@ -70,7 +71,7 @@
+               u8      name[16];
+               u8      overflow[4];    /* if any char of the name (inc NUL) reaches here, consume
+                                        * the next dirent too */
+-      } parts;
++      } u;
+       u8      extended_name[32];
+ } afs_dirent_t;
+@@ -256,7 +257,7 @@
+               /* got a valid entry */
+               dire = &block->dirents[offset];
+-              nlen = strnlen(dire->parts.name,sizeof(*block) - offset*sizeof(afs_dirent_t));
++              nlen = strnlen(dire->u.name,sizeof(*block) - offset*sizeof(afs_dirent_t));
+               _debug("ENT[%Zu.%u]: %s %Zu \"%s\"\n",
+                      blkoff/sizeof(afs_dir_block_t),offset,
+@@ -288,11 +289,11 @@
+               /* found the next entry */
+               ret = filldir(cookie,
+-                            dire->parts.name,
++                            dire->u.name,
+                             nlen,
+                             blkoff + offset * sizeof(afs_dirent_t),
+-                            ntohl(dire->parts.vnode),
+-                            filldir==afs_dir_lookup_filldir ? dire->parts.unique : DT_UNKNOWN);
++                            ntohl(dire->u.vnode),
++                            filldir==afs_dir_lookup_filldir ? dire->u.unique : DT_UNKNOWN);
+               if (ret<0) {
+                       _leave(" = 0 [full]");
+                       return 0;
+@@ -414,7 +415,8 @@
+ /*
+  * look up an entry in a directory
+  */
+-static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
++static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
++                                   struct nameidata *nd)
+ {
+       struct afs_dir_lookup_cookie cookie;
+       struct afs_super_info *as;
+@@ -423,11 +425,11 @@
+       unsigned fpos;
+       int ret;
+-      _enter("{%lu},{%s}",dir->i_ino,dentry->d_name.name);
++      _enter("{%lu},%p{%s}",dir->i_ino,dentry,dentry->d_name.name);
+       /* insanity checks first */
+-      if (sizeof(afs_dir_block_t) != 2048) BUG();
+-      if (sizeof(afs_dirent_t) != 32) BUG();
++      BUG_ON(sizeof(afs_dir_block_t) != 2048);
++      BUG_ON(sizeof(afs_dirent_t) != 32);
+       if (dentry->d_name.len > 255) {
+               _leave(" = -ENAMETOOLONG");
+@@ -495,9 +497,11 @@
+       unsigned fpos;
+       int ret;
+-      _enter("%s,%p",dentry->d_name.name,nd);
++      _enter("{sb=%p n=%s},",dentry->d_sb,dentry->d_name.name);
++
++      /* lock down the parent dentry so we can peer at it */
++      parent = dget_parent(dentry->d_parent);
+-      parent = dget_parent(dentry);
+       dir = parent->d_inode;
+       inode = dentry->d_inode;
+Index: linux-2.6.0-test5/fs/afs/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/file.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/file.c    2003-09-27 11:38:35.995056304 +0800
+@@ -16,6 +16,7 @@
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
++#include <linux/buffer_head.h>
+ #include "volume.h"
+ #include "vnode.h"
+ #include <rxrpc/call.h>
+@@ -27,6 +28,8 @@
+ #endif
+ static int afs_file_readpage(struct file *file, struct page *page);
++static int afs_file_invalidatepage(struct page *page, unsigned long offset);
++static int afs_file_releasepage(struct page *page, int gfp_flags);
+ static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, loff_t *off);
+@@ -37,7 +40,7 @@
+ struct file_operations afs_file_file_operations = {
+       .read           = generic_file_read,
+       .write          = afs_file_write,
+-      .mmap           = generic_file_readonly_mmap,
++      .mmap           = generic_file_mmap,
+ #if 0
+       .open           = afs_file_open,
+       .release        = afs_file_release,
+@@ -47,6 +50,10 @@
+ struct address_space_operations afs_fs_aops = {
+       .readpage       = afs_file_readpage,
++      .sync_page      = block_sync_page,
++      .set_page_dirty = __set_page_dirty_nobuffers,
++      .releasepage    = afs_file_releasepage,
++      .invalidatepage = afs_file_invalidatepage,
+ };
+ /*****************************************************************************/
+@@ -66,11 +73,48 @@
+ /*****************************************************************************/
+ /*
++ * deal with notification that a page was read from the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_file_readpage_read_complete(void *cookie_data, struct page *page, void *data,
++                                          int error)
++{
++      _enter("%p,%p,%p,%d",cookie_data,page,data,error);
++
++      if (error)
++              SetPageError(page);
++      else
++              SetPageUptodate(page);
++      unlock_page(page);
++
++} /* end afs_file_readpage_read_complete() */
++#endif
++
++/*****************************************************************************/
++/*
++ * deal with notification that a page was written to the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_file_readpage_write_complete(void *cookie_data, struct page *page, void *data,
++                                           int error)
++{
++      _enter("%p,%p,%p,%d",cookie_data,page,data,error);
++
++      unlock_page(page);
++
++} /* end afs_file_readpage_write_complete() */
++#endif
++
++/*****************************************************************************/
++/*
+  * AFS read page from file (or symlink)
+  */
+ static int afs_file_readpage(struct file *file, struct page *page)
+ {
+       struct afs_rxfs_fetch_descriptor desc;
++#ifdef AFS_CACHING_SUPPORT
++      struct cachefs_page *pageio;
++#endif
+       struct inode *inode;
+       afs_vnode_t *vnode;
+       int ret;
+@@ -88,28 +132,73 @@
+       if (vnode->flags & AFS_VNODE_DELETED)
+               goto error;
+-      /* work out how much to get and from where */
+-      desc.fid        = vnode->fid;
+-      desc.offset     = page->index << PAGE_CACHE_SHIFT;
+-      desc.size       = min((size_t)(inode->i_size - desc.offset),(size_t)PAGE_SIZE);
+-      desc.buffer     = kmap(page);
+-
+-      clear_page(desc.buffer);
+-
+-      /* read the contents of the file from the server into the page */
+-      ret = afs_vnode_fetch_data(vnode,&desc);
+-      kunmap(page);
+-      if (ret<0) {
+-              if (ret==-ENOENT) {
+-                      _debug("got NOENT from server - marking file deleted and stale");
+-                      vnode->flags |= AFS_VNODE_DELETED;
+-                      ret = -ESTALE;
+-              }
++#ifdef AFS_CACHING_SUPPORT
++      ret = cachefs_page_get_private(page,&pageio,GFP_NOIO);
++      if (ret<0)
+               goto error;
+-      }
+-      SetPageUptodate(page);
+-      unlock_page(page);
++      /* is it cached? */
++      ret = cachefs_read_or_alloc_page(vnode->cache,
++                                       page,
++                                       afs_file_readpage_read_complete,
++                                       NULL,
++                                       GFP_KERNEL);
++#else
++      ret = -ENOBUFS;
++#endif
++
++      switch (ret) {
++              /* read BIO submitted and wb-journal entry found */
++      case 1:
++              BUG(); // TODO - handle wb-journal match
++
++              /* read BIO submitted (page in cache) */
++      case 0:
++              break;
++
++              /* no page available in cache */
++      case -ENOBUFS:
++      case -ENODATA:
++      default:
++              desc.fid        = vnode->fid;
++              desc.offset     = page->index << PAGE_CACHE_SHIFT;
++              desc.size       = min((size_t)(inode->i_size - desc.offset),(size_t)PAGE_SIZE);
++              desc.buffer     = kmap(page);
++
++              clear_page(desc.buffer);
++
++              /* read the contents of the file from the server into the page */
++              ret = afs_vnode_fetch_data(vnode,&desc);
++              kunmap(page);
++              if (ret<0) {
++                      if (ret==-ENOENT) {
++                              _debug("got NOENT from server - marking file deleted and stale");
++                              vnode->flags |= AFS_VNODE_DELETED;
++                              ret = -ESTALE;
++                      }
++
++#ifdef AFS_CACHING_SUPPORT
++                      cachefs_uncache_page(vnode->cache,page);
++#endif
++                      goto error;
++              }
++
++              SetPageUptodate(page);
++
++#ifdef AFS_CACHING_SUPPORT
++              if (cachefs_write_page(vnode->cache,
++                                     page,
++                                     afs_file_readpage_write_complete,
++                                     NULL,
++                                     GFP_KERNEL) != 0
++                  ) {
++                      cachefs_uncache_page(vnode->cache,page);
++                      unlock_page(page);
++              }
++#else
++              unlock_page(page);
++#endif
++      }
+       _leave(" = 0");
+       return 0;
+@@ -122,3 +211,83 @@
+       return ret;
+ } /* end afs_file_readpage() */
++
++/*****************************************************************************/
++/*
++ * get a page cookie for the specified page
++ */
++#ifdef AFS_CACHING_SUPPORT
++int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie)
++{
++      int ret;
++
++      _enter("");
++      ret = cachefs_page_get_private(page,_page_cookie,GFP_NOIO);
++
++      _leave(" = %d",ret);
++      return ret;
++} /* end afs_cache_get_page_cookie() */
++#endif
++
++/*****************************************************************************/
++/*
++ * invalidate part or all of a page
++ */
++static int afs_file_invalidatepage(struct page *page, unsigned long offset)
++{
++      int ret = 1;
++
++      _enter("{%lu},%lu",page->index,offset);
++
++      BUG_ON(!PageLocked(page));
++      if (PagePrivate(page)) {
++#ifdef AFS_CACHING_SUPPORT
++              struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
++              cachefs_uncache_page(vnode->cache,page);
++#endif
++
++              /*
++               * We release buffers only if the entire page is being invalidated.
++               * The get_block cached value has been unconditionally invalidated,
++               * so real IO is not possible anymore.
++               */
++              if (offset == 0) {
++                      BUG_ON(!PageLocked(page));
++
++                      ret = 0;
++                      if (!PageWriteback(page))
++                              ret = page->mapping->a_ops->releasepage(page, 0);
++              }
++      }
++
++      _leave(" = %d",ret);
++      return ret;
++} /* end afs_file_invalidatepage() */
++
++/*****************************************************************************/
++/*
++ * release a page and cleanup its private data
++ */
++static int afs_file_releasepage(struct page *page, int gfp_flags)
++{
++      struct cachefs_page *pageio;
++
++      _enter("{%lu},%x",page->index,gfp_flags);
++
++      if (PagePrivate(page)) {
++#ifdef AFS_CACHING_SUPPORT
++              struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
++              cachefs_uncache_page(vnode->cache,page);
++#endif
++
++              pageio = (struct cachefs_page *) page->private;
++              page->private = 0;
++              ClearPagePrivate(page);
++
++              if (pageio)
++                      kfree(pageio);
++      }
++
++      _leave(" = 0");
++      return 0;
++} /* end afs_file_releasepage() */
+Index: linux-2.6.0-test5/fs/afs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/inode.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/inode.c   2003-09-27 11:38:35.997056000 +0800
+@@ -69,17 +69,16 @@
+       inode->i_uid            = vnode->status.owner;
+       inode->i_gid            = 0;
+       inode->i_size           = vnode->status.size;
+-      inode->i_atime.tv_sec           = inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = vnode->status.mtime_server;
+-      inode->i_atime.tv_nsec = 
+-      inode->i_mtime.tv_nsec = 
+-              inode->i_ctime.tv_nsec = 0;
++      inode->i_ctime.tv_sec   = vnode->status.mtime_server;
++      inode->i_ctime.tv_nsec  = 0;
++      inode->i_atime          = inode->i_mtime = inode->i_ctime;
+       inode->i_blksize        = PAGE_CACHE_SIZE;
+       inode->i_blocks         = 0;
+       inode->i_version        = vnode->fid.unique;
+       inode->i_mapping->a_ops = &afs_fs_aops;
+       /* check to see whether a symbolic link is really a mountpoint */
+-      if (vnode->status.type==AFS_FTYPE_SYMLINK) {
++      if (vnode->status.type == AFS_FTYPE_SYMLINK) {
+               afs_mntpt_check_symlink(vnode);
+               if (vnode->flags & AFS_VNODE_MOUNTPOINT) {
+@@ -105,7 +104,7 @@
+       ret = afs_vnode_fetch_status(vnode);
+-      if (ret==0)
++      if (ret == 0)
+               ret = afs_inode_map_status(vnode);
+       return ret;
+@@ -120,8 +119,8 @@
+ {
+       struct afs_iget_data *data = opaque;
+-      /* only match inodes with the same version number */
+-      return inode->i_ino==data->fid.vnode && inode->i_version==data->fid.unique;
++      return inode->i_ino == data->fid.vnode &&
++              inode->i_version == data->fid.unique;
+ } /* end afs_iget5_test() */
+ /*****************************************************************************/
+@@ -145,20 +144,22 @@
+ /*
+  * inode retrieval
+  */
+-inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inode)
++inline int afs_iget(struct super_block *sb, afs_fid_t *fid,
++                  struct inode **_inode)
+ {
+-      struct afs_iget_data data = { .fid = *fid };
++      struct afs_iget_data data = { fid: *fid };
+       struct afs_super_info *as;
++      struct afs_vnode *vnode;
+       struct inode *inode;
+-      afs_vnode_t *vnode;
+       int ret;
+-      _enter(",{%u,%u,%u},,",fid->vid,fid->vnode,fid->unique);
++      _enter(",{%u,%u,%u},,", fid->vid, fid->vnode, fid->unique);
+       as = sb->s_fs_info;
+       data.volume = as->volume;
+-      inode = iget5_locked(sb,fid->vnode,afs_iget5_test,afs_iget5_set,&data);
++      inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
++                           &data);
+       if (!inode) {
+               _leave(" = -ENOMEM");
+               return -ENOMEM;
+@@ -173,10 +174,19 @@
+                       *_inode = inode;
+               else
+                       iput(inode);
+-              _leave(" = %d",ret);
++              _leave(" = %d", ret);
+               return ret;
+       }
++#ifdef AFS_CACHING_SUPPORT
++      /* set up caching before reading the status, as fetch-status reads the
++       * first page of symlinks to see if they're really mntpts */
++      cachefs_acquire_cookie(vnode->volume->cache,
++                             NULL,
++                             vnode,
++                             &vnode->cache);
++#endif
++
+       /* okay... it's a new inode */
+       vnode->flags |= AFS_VNODE_CHANGED;
+       ret = afs_inode_fetch_status(inode);
+@@ -187,11 +197,11 @@
+       unlock_new_inode(inode);
+       *_inode = inode;
+-      _leave(" = 0 [CB { v=%u x=%lu t=%u nix=%u }]",
++      _leave(" = 0 [CB { v=%u x=%lu t=%u } c=%p]",
+              vnode->cb_version,
+              vnode->cb_timeout.timo_jif,
+              vnode->cb_type,
+-             vnode->nix
++             vnode->cache
+              );
+       return 0;
+@@ -201,7 +211,7 @@
+       unlock_new_inode(inode);
+       iput(inode);
+-      _leave(" = %d [bad]",ret);
++      _leave(" = %d [bad]", ret);
+       return ret;
+ } /* end afs_iget() */
+@@ -209,7 +219,8 @@
+ /*
+  * read the attributes of an inode
+  */
+-int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
++int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
++                    struct kstat *stat)
+ {
+       struct inode *inode;
+       afs_vnode_t *vnode;
+@@ -217,23 +228,25 @@
+       inode = dentry->d_inode;
+-      _enter("{ ino=%lu v=%lu }",inode->i_ino,inode->i_version);
++      _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version);
+       vnode = AFS_FS_I(inode);
+       ret = afs_inode_fetch_status(inode);
+-      if (ret==-ENOENT) {
+-              _leave(" = %d [%d %p]",ret,atomic_read(&dentry->d_count),dentry->d_inode);
++      if (ret == -ENOENT) {
++              _leave(" = %d [%d %p]",
++                     ret, atomic_read(&dentry->d_count), dentry->d_inode);
+               return ret;
+       }
+-      else if (ret<0) {
++      else if (ret < 0) {
+               make_bad_inode(inode);
+-              _leave(" = %d",ret);
++              _leave(" = %d", ret);
+               return ret;
+       }
+-      /* transfer attributes from the inode structure to the stat structure */
+-      generic_fillattr(inode,stat);
++      /* transfer attributes from the inode structure to the stat
++       * structure */
++      generic_fillattr(inode, stat);
+       _leave(" = 0 CB { v=%u x=%u t=%u }",
+              vnode->cb_version,
+@@ -261,9 +274,14 @@
+              vnode->cb_type
+              );
+-      if (inode->i_ino!=vnode->fid.vnode) BUG();
++      BUG_ON(inode->i_ino != vnode->fid.vnode);
+       afs_vnode_give_up_callback(vnode);
++#ifdef AFS_CACHING_SUPPORT
++      cachefs_relinquish_cookie(vnode->cache, 0);
++      vnode->cache = NULL;
++#endif
++
+       _leave("");
+ } /* end afs_clear_inode() */
+Index: linux-2.6.0-test5/fs/afs/internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/internal.h   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/internal.h        2003-09-27 11:38:35.999055696 +0800
+@@ -26,7 +26,7 @@
+ #define kproto(FMT, a...)     printk("### "FMT"\n" , ## a)
+ #define knet(FMT, a...)               printk(FMT"\n" , ## a)
+-#if 0
++#ifdef __KDEBUG
+ #define _enter(FMT, a...)     kenter(FMT , ## a)
+ #define _leave(FMT, a...)     kleave(FMT , ## a)
+ #define _debug(FMT, a...)     kdebug(FMT , ## a)
+@@ -56,6 +56,9 @@
+  */
+ extern struct rw_semaphore afs_proc_cells_sem;
+ extern struct list_head afs_proc_cells;
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_cache_cell_index_def;
++#endif
+ /*
+  * dir.c
+@@ -70,6 +73,10 @@
+ extern struct inode_operations afs_file_inode_operations;
+ extern struct file_operations afs_file_file_operations;
++#ifdef AFS_CACHING_SUPPORT
++extern int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie);
++#endif
++
+ /*
+  * inode.c
+  */
+@@ -78,10 +85,22 @@
+ extern void afs_clear_inode(struct inode *inode);
+ /*
++ * main.c
++ */
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_netfs afs_cache_netfs;
++#endif
++
++/*
+  * mntpt.c
+  */
+ extern struct inode_operations afs_mntpt_inode_operations;
+ extern struct file_operations afs_mntpt_file_operations;
++#ifdef AFS_AUTOMOUNT_SUPPORT
++extern struct afs_timer afs_mntpt_expiry_timer;
++extern struct afs_timer_ops afs_mntpt_expiry_timer_ops;
++extern unsigned long afs_mntpt_expiry_timeout;
++#endif
+ extern int afs_mntpt_check_symlink(afs_vnode_t *vnode);
+Index: linux-2.6.0-test5/fs/afs/kafsasyncd.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/kafsasyncd.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/kafsasyncd.c      2003-09-27 11:38:36.001055392 +0800
+@@ -153,8 +153,7 @@
+       spin_lock(&kafsasyncd_async_lock);
+       /* fold the busy and attention queues together */
+-      list_splice(&kafsasyncd_async_busyq,&kafsasyncd_async_attnq);
+-      list_del_init(&kafsasyncd_async_busyq);
++      list_splice_init(&kafsasyncd_async_busyq,&kafsasyncd_async_attnq);
+       /* dequeue kafsasyncd from all their wait queues */
+       list_for_each(_p,&kafsasyncd_async_attnq) {
+@@ -197,6 +196,7 @@
+       spin_lock(&kafsasyncd_async_lock);
+       init_waitqueue_entry(&op->waiter,kafsasyncd_task);
++      add_wait_queue(&op->call->waitq,&op->waiter);
+       list_del(&op->link);
+       list_add_tail(&op->link,&kafsasyncd_async_busyq);
+@@ -238,7 +238,10 @@
+       spin_lock(&kafsasyncd_async_lock);
+-      list_del_init(&op->link);
++      if (!list_empty(&op->link)) {
++              list_del_init(&op->link);
++              remove_wait_queue(&op->call->waitq,&op->waiter);
++      }
+       spin_unlock(&kafsasyncd_async_lock);
+Index: linux-2.6.0-test5/fs/afs/kafstimod.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/kafstimod.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/kafstimod.c       2003-09-27 11:38:36.004054936 +0800
+@@ -82,7 +82,7 @@
+       for (;;) {
+               unsigned long jif;
+-              unsigned long timeout;
++              signed long timeout;
+               /* deal with the server being asked to die */
+               if (kafstimod_die) {
+@@ -98,18 +98,18 @@
+               spin_lock(&kafstimod_lock);
+               if (list_empty(&kafstimod_list)) {
+                       timeout = MAX_SCHEDULE_TIMEOUT;
+-              } else {
+-                      unsigned long tmo;
+-
+-                      timer = list_entry(kafstimod_list.next,
+-                                         afs_timer_t, link);
+-                      tmo = timer->timo_jif;
++              }
++              else {
++                      timer = list_entry(kafstimod_list.next,afs_timer_t,link);
++                      timeout = timer->timo_jif;
+                       jif = jiffies;
+-                      if (time_before_eq(tmo,jif))
++                      if (time_before_eq((unsigned long)timeout,jif))
+                               goto immediate;
+-                      timeout = (long)tmo - (long)jiffies;
++                      else {
++                              timeout = (long)timeout - (long)jiffies;
++                      }
+               }
+               spin_unlock(&kafstimod_lock);
+@@ -170,7 +170,7 @@
+       wake_up(&kafstimod_sleepq);
+       _leave("");
+-} /* end afs_kafstimod_queue_vlocation() */
++} /* end afs_kafstimod_add_timer() */
+ /*****************************************************************************/
+ /*
+Index: linux-2.6.0-test5/fs/afs/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/main.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/main.c    2003-09-27 11:38:36.006054632 +0800
+@@ -17,6 +17,7 @@
+ #include <rxrpc/transport.h>
+ #include <rxrpc/call.h>
+ #include <rxrpc/peer.h>
++#include "cache.h"
+ #include "cell.h"
+ #include "server.h"
+ #include "fsclient.h"
+@@ -47,6 +48,18 @@
+ struct list_head afs_cb_hash_tbl[AFS_CB_HASH_COUNT];
+ spinlock_t afs_cb_hash_lock = SPIN_LOCK_UNLOCKED;
++#ifdef AFS_CACHING_SUPPORT
++static struct cachefs_netfs_operations afs_cache_ops = {
++      .get_page_cookie        = afs_cache_get_page_cookie,
++};
++
++struct cachefs_netfs afs_cache_netfs = {
++      .name                   = "afs",
++      .version                = 0,
++      .ops                    = &afs_cache_ops,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+  * initialise the AFS client FS module
+@@ -64,34 +77,41 @@
+       /* register the /proc stuff */
+       ret = afs_proc_init();
+-      if (ret<0)
++      if (ret < 0)
+               return ret;
++#ifdef AFS_CACHING_SUPPORT
++      /* we want to be able to cache */
++      ret = cachefs_register_netfs(&afs_cache_netfs,&afs_cache_cell_index_def);
++      if (ret < 0)
++              goto error;
++#endif
++
+       /* initialise the cell DB */
+       ret = afs_cell_init();
+-      if (ret<0)
+-              goto error;
++      if (ret < 0)
++              goto error_cache;
+       /* start the timeout daemon */
+       ret = afs_kafstimod_start();
+-      if (ret<0)
+-              goto error;
++      if (ret < 0)
++              goto error_cache;
+       /* start the async operation daemon */
+       ret = afs_kafsasyncd_start();
+-      if (ret<0)
++      if (ret < 0)
+               goto error_kafstimod;
+       /* create the RxRPC transport */
+       ret = rxrpc_create_transport(7001,&afs_transport);
+-      if (ret<0)
++      if (ret < 0)
+               goto error_kafsasyncd;
+       afs_transport->peer_ops = &afs_peer_ops;
+       /* register the filesystems */
+       ret = afs_fs_init();
+-      if (ret<0)
++      if (ret < 0)
+               goto error_transport;
+       return ret;
+@@ -102,7 +122,11 @@
+       afs_kafsasyncd_stop();
+  error_kafstimod:
+       afs_kafstimod_stop();
++ error_cache:
++#ifdef AFS_CACHING_SUPPORT
++      cachefs_unregister_netfs(&afs_cache_netfs);
+  error:
++#endif
+       afs_cell_purge();
+       afs_proc_cleanup();
+       printk(KERN_ERR "kAFS: failed to register: %d\n",ret);
+@@ -122,6 +146,9 @@
+       afs_kafstimod_stop();
+       afs_kafsasyncd_stop();
+       afs_cell_purge();
++#ifdef AFS_CACHING_SUPPORT
++      cachefs_unregister_netfs(&afs_cache_netfs);
++#endif
+       afs_proc_cleanup();
+ } /* end afs_exit() */
+@@ -142,7 +169,7 @@
+       /* determine which server the peer resides in (if any) */
+       ret = afs_server_find_by_peer(peer,&server);
+-      if (ret<0)
++      if (ret < 0)
+               return ret; /* none that we recognise, so abort */
+       _debug("Server %p{u=%d}\n",server,atomic_read(&server->usage));
+@@ -191,3 +218,48 @@
+       _leave("");
+ } /* end afs_discarding_peer() */
++
++/*****************************************************************************/
++/*
++ * clear the dead space between task_struct and kernel stack
++ * - called by supplying -finstrument-functions to gcc
++ */
++#if 0
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++{
++       asm volatile("  movl    %%esp,%%edi     \n"
++                    "  andl    %0,%%edi        \n"
++                    "  addl    %1,%%edi        \n"
++                    "  movl    %%esp,%%ecx     \n"
++                    "  subl    %%edi,%%ecx     \n"
++                    "  shrl    $2,%%ecx        \n"
++                    "  movl    $0xedededed,%%eax     \n"
++                    "  rep stosl               \n"
++                    :
++                    : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++                    : "eax", "ecx", "edi", "memory", "cc"
++                    );
++}
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++{
++       asm volatile("  movl    %%esp,%%edi     \n"
++                    "  andl    %0,%%edi        \n"
++                    "  addl    %1,%%edi        \n"
++                    "  movl    %%esp,%%ecx     \n"
++                    "  subl    %%edi,%%ecx     \n"
++                    "  shrl    $2,%%ecx        \n"
++                    "  movl    $0xdadadada,%%eax     \n"
++                    "  rep stosl               \n"
++                    :
++                    : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++                    : "eax", "ecx", "edi", "memory", "cc"
++                    );
++}
++#endif
+Index: linux-2.6.0-test5/fs/afs/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/Makefile     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/Makefile  2003-09-27 11:38:36.008054328 +0800
+@@ -2,6 +2,8 @@
+ # Makefile for Red Hat Linux AFS client.
+ #
++#CFLAGS += -finstrument-functions
++
+ kafs-objs := \
+       callback.o \
+       cell.o \
+Index: linux-2.6.0-test5/fs/afs/mntpt.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/mntpt.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/mntpt.c   2003-09-27 11:38:36.010054024 +0800
+@@ -16,24 +16,52 @@
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
++#include <linux/mount.h>
++#include <linux/namei.h>
++#include <linux/namespace.h>
++#include "super.h"
++#include "cell.h"
+ #include "volume.h"
+ #include "vnode.h"
+ #include "internal.h"
+-static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
++static struct dentry *afs_mntpt_lookup(struct inode *dir,
++                                     struct dentry *dentry,
++                                     struct nameidata *nd);
+ static int afs_mntpt_open(struct inode *inode, struct file *file);
++#ifdef AFS_AUTOMOUNT_SUPPORT
++static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
++#endif
++
+ struct file_operations afs_mntpt_file_operations = {
+       .open           = afs_mntpt_open,
+ };
+ struct inode_operations afs_mntpt_inode_operations = {
+       .lookup         = afs_mntpt_lookup,
++#ifdef AFS_AUTOMOUNT_SUPPORT
++      .follow_link    = afs_mntpt_follow_link,
++#endif
+       .readlink       = page_readlink,
+       .getattr        = afs_inode_getattr,
+ };
++#ifdef AFS_AUTOMOUNT_SUPPORT
++static LIST_HEAD(afs_vfsmounts);
++
++static void afs_mntpt_expiry_timed_out(struct afs_timer *timer);
++
++struct afs_timer_ops afs_mntpt_expiry_timer_ops = {
++      .timed_out      = afs_mntpt_expiry_timed_out,
++};
++
++struct afs_timer afs_mntpt_expiry_timer;
++
++unsigned long afs_mntpt_expiry_timeout = 20;
++#endif
++
+ /*****************************************************************************/
+ /*
+  * check a symbolic link to see whether it actually encodes a mountpoint
+@@ -93,8 +121,17 @@
+ /*
+  * no valid lookup procedure on this sort of dir
+  */
+-static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
++static struct dentry *afs_mntpt_lookup(struct inode *dir,
++                                     struct dentry *dentry,
++                                     struct nameidata *nd)
+ {
++      kenter("%p,%p{%p{%s},%s}",
++             dir,
++             dentry,
++             dentry->d_parent,
++             dentry->d_parent ? dentry->d_parent->d_name.name : (const unsigned char*)"",
++             dentry->d_name.name);
++
+       return ERR_PTR(-EREMOTE);
+ } /* end afs_mntpt_lookup() */
+@@ -104,5 +141,146 @@
+  */
+ static int afs_mntpt_open(struct inode *inode, struct file *file)
+ {
++      kenter("%p,%p{%p{%s},%s}",
++             inode, file,
++             file->f_dentry->d_parent,
++             file->f_dentry->d_parent ? file->f_dentry->d_parent->d_name.name : (const unsigned char*)"",
++             file->f_dentry->d_name.name);
++
+       return -EREMOTE;
+ } /* end afs_mntpt_open() */
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++/*****************************************************************************/
++/*
++ * create a vfsmount to be automounted
++ */
++static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
++{
++      struct afs_super_info *super;
++      struct vfsmount *mnt;
++      struct page *page = NULL;
++      size_t size;
++      char *buf, *devname = NULL, *options = NULL;
++      int ret;
++
++      kenter("{%s}", mntpt->d_name.name);
++
++      BUG_ON(!mntpt->d_inode);
++
++      ret = -EINVAL;
++      size = mntpt->d_inode->i_size;
++      if (size > PAGE_SIZE - 1)
++              goto error;
++
++      ret = -ENOMEM;
++      devname = (char *) get_zeroed_page(GFP_KERNEL);
++      if (!devname)
++              goto error;
++
++      options = (char *) get_zeroed_page(GFP_KERNEL);
++      if (!options)
++              goto error;
++
++      /* read the contents of the AFS special symlink */
++      page = read_cache_page(mntpt->d_inode->i_mapping,
++                             0,
++                             (filler_t*)mntpt->d_inode->i_mapping->a_ops->readpage,
++                             NULL);
++      if (IS_ERR(page)) {
++              ret = PTR_ERR(page);
++              goto error;
++      }
++
++      ret = -EIO;
++      wait_on_page_locked(page);
++      if (!PageUptodate(page) || PageError(page))
++              goto error;
++
++      buf = kmap(page);
++      memcpy(devname, buf, size);
++      kunmap(page);
++      page_cache_release(page);
++      page = NULL;
++
++      /* work out what options we want */
++      super = AFS_FS_S(mntpt->d_sb);
++      memcpy(options, "cell=", 5);
++      strcpy(options + 5, super->volume->cell->name);
++      if (super->volume->type == AFSVL_RWVOL)
++              strcat(options,",rwpath");
++
++      /* try and do the mount */
++      kdebug("--- attempting mount %s -o %s ---", devname, options);
++      mnt = do_kern_mount("afs", 0, devname, options);
++      kdebug("--- mount result %p ---", mnt);
++
++      free_page((unsigned long)devname);
++      free_page((unsigned long)options);
++      kleave(" = %p",mnt);
++      return mnt;
++
++ error:
++      if (page)
++              page_cache_release(page);
++      if (devname)
++              free_page((unsigned long)devname);
++      if (options)
++              free_page((unsigned long)options);
++      kleave(" = %d",ret);
++      return ERR_PTR(ret);
++} /* end afs_mntpt_do_automount() */
++
++/*****************************************************************************/
++/*
++ * follow a link from a mountpoint directory, thus causing it to be mounted
++ */
++static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
++{
++      struct nameidata newnd;
++      struct vfsmount *newmnt;
++      int err;
++
++      kenter("%p{%s},{%s:%p{%s}}",
++             dentry,
++             dentry->d_name.name,
++             nd->mnt->mnt_devname,
++             dentry,
++             nd->dentry->d_name.name);
++
++      newmnt = afs_mntpt_do_automount(dentry);
++      if (IS_ERR(newmnt))
++              return PTR_ERR(newmnt);
++
++      struct_cpy(&newnd,nd);
++      newnd.dentry = dentry;
++      err = do_add_mount(newmnt, &newnd, 0, &afs_vfsmounts);
++
++      if (!err) {
++              path_release(nd);
++              mntget(newmnt);
++              nd->mnt = newmnt;
++              dget(newmnt->mnt_root);
++              nd->dentry = newmnt->mnt_root;
++      }
++
++      kleave(" = %d", err);
++      return err;
++} /* end afs_mntpt_follow_link() */
++
++/*****************************************************************************/
++/*
++ * handle mountpoint expiry timer going off
++ */
++static void afs_mntpt_expiry_timed_out(struct afs_timer *timer)
++{
++      kenter("");
++
++      mark_mounts_for_expiry(&afs_vfsmounts);
++
++      afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
++                              afs_mntpt_expiry_timeout * HZ);
++
++      kleave("");
++} /* end afs_mntpt_expiry_timed_out() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/mount.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/mount.h   2003-09-27 11:38:36.011053872 +0800
+@@ -17,7 +17,7 @@
+       const char              *cell;          /* name of cell containing volume */
+       const char              *cache;         /* name of cache block device */
+       size_t                  nservers;       /* number of server addresses listed */
+-      u_int32_t               servers[10];    /* IP addresses of servers in this cell */
++      uint32_t                servers[10];    /* IP addresses of servers in this cell */
+ };
+ #endif /* _LINUX_AFS_MOUNT_H */
+Index: linux-2.6.0-test5/fs/afs/server.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/server.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/server.c  2003-09-27 11:38:36.014053416 +0800
+@@ -148,6 +148,9 @@
+ {
+       afs_cell_t *cell;
++      if (!server)
++              return;
++
+       _enter("%p",server);
+       cell = server->cell;
+Index: linux-2.6.0-test5/fs/afs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/super.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/super.c   2003-09-27 11:38:36.019052656 +0800
+@@ -29,15 +29,22 @@
+ #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
++struct afs_mount_params {
++      int                     rwpath;
++      struct afs_cell         *default_cell;
++      struct afs_volume       *volume;
++};
++
+ static inline char *strdup(const char *s)
+ {
+-      char *ns = kmalloc(strlen(s)+1,GFP_KERNEL);
++      char *ns = kmalloc(strlen(s) + 1, GFP_KERNEL);
+       if (ns)
+-              strcpy(ns,s);
++              strcpy(ns, s);
+       return ns;
+ }
+-static void afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags);
++static void afs_i_init_once(void *foo, kmem_cache_t *cachep,
++                          unsigned long flags);
+ static struct super_block *afs_get_sb(struct file_system_type *fs_type,
+                                     int flags, const char *dev_name,
+@@ -66,6 +73,7 @@
+ };
+ static kmem_cache_t *afs_inode_cachep;
++static atomic_t afs_count_active_inodes;
+ /*****************************************************************************/
+ /*
+@@ -75,16 +83,22 @@
+ {
+       int ret;
+-      kenter("");
++      _enter("");
++
++#ifdef AFS_AUTOMOUNT_SUPPORT
++      afs_timer_init(&afs_mntpt_expiry_timer, &afs_mntpt_expiry_timer_ops);
++#endif
+       /* create ourselves an inode cache */
++      atomic_set(&afs_count_active_inodes, 0);
++
+       ret = -ENOMEM;
+       afs_inode_cachep = kmem_cache_create("afs_inode_cache",
+-                                              sizeof(afs_vnode_t),
+-                                              0,
+-                                              SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+-                                              afs_i_init_once,
+-                                              NULL);
++                                           sizeof(afs_vnode_t),
++                                           0,
++                                           SLAB_HWCACHE_ALIGN,
++                                           afs_i_init_once,
++                                           NULL);
+       if (!afs_inode_cachep) {
+               printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n");
+               return ret;
+@@ -92,9 +106,9 @@
+       /* now export our filesystem to lesser mortals */
+       ret = register_filesystem(&afs_fs_type);
+-      if (ret<0) {
++      if (ret < 0) {
+               kmem_cache_destroy(afs_inode_cachep);
+-              kleave(" = %d",ret);
++              kleave(" = %d", ret);
+               return ret;
+       }
+@@ -108,11 +122,16 @@
+  */
+ void __exit afs_fs_exit(void)
+ {
+-      /* destroy our private inode cache */
+-      kmem_cache_destroy(afs_inode_cachep);
+-
+       unregister_filesystem(&afs_fs_type);
++      if (atomic_read(&afs_count_active_inodes) != 0) {
++              printk("kAFS: %d active inode objects still present\n",
++                     atomic_read(&afs_count_active_inodes));
++              BUG();
++      }
++
++      kmem_cache_destroy(afs_inode_cachep);
++
+ } /* end afs_fs_exit() */
+ /*****************************************************************************/
+@@ -122,7 +141,7 @@
+ static int want_arg(char **_value, const char *option)
+ {
+       if (!_value || !*_value || !**_value) {
+-              printk(KERN_NOTICE "kAFS: %s: argument missing\n",option);
++              printk(KERN_NOTICE "kAFS: %s: argument missing\n", option);
+               return 0;
+       }
+       return 1;
+@@ -130,27 +149,13 @@
+ /*****************************************************************************/
+ /*
+- * check that there is a value
+- */
+-#if 0
+-static int want_value(char **_value, const char *option)
+-{
+-      if (!_value || !*_value || !**_value) {
+-              printk(KERN_NOTICE "kAFS: %s: argument incomplete\n",option);
+-              return 0;
+-      }
+-      return 1;
+-} /* end want_value() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+  * check that there's no subsequent value
+  */
+ static int want_no_value(char *const *_value, const char *option)
+ {
+       if (*_value && **_value) {
+-              printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",option,*_value);
++              printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",
++                     option, *_value);
+               return 0;
+       }
+       return 1;
+@@ -158,150 +163,55 @@
+ /*****************************************************************************/
+ /*
+- * extract a number from an option string value
+- */
+-#if 0
+-static int want_number(char **_value, const char *option, unsigned long *number,
+-                     unsigned long limit)
+-{
+-      char *value = *_value;
+-
+-      if (!want_value(_value,option))
+-              return 0;
+-
+-      *number = simple_strtoul(value,_value,0);
+-
+-      if (value==*_value) {
+-              printk(KERN_NOTICE "kAFS: %s: Invalid number: %s\n",option,value);
+-              return 0;
+-      }
+-
+-      if (*number>limit) {
+-              printk(KERN_NOTICE "kAFS: %s: numeric value %lu > %lu\n",option,*number,limit);
+-              return 0;
+-      }
+-
+-      return 1;
+-} /* end want_number() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+- * extract a separator from an option string value
+- */
+-#if 0
+-static int want_sep(char **_value, const char *option, char sep)
+-{
+-      if (!want_value(_value,option))
+-              return 0;
+-
+-      if (*(*_value)++ != sep) {
+-              printk(KERN_NOTICE "kAFS: %s: '%c' expected: %s\n",option,sep,*_value-1);
+-              return 0;
+-      }
+-
+-      return 1;
+-} /* end want_number() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+- * extract an IP address from an option string value
+- */
+-#if 0
+-static int want_ipaddr(char **_value, const char *option, struct in_addr *addr)
+-{
+-      unsigned long number[4];
+-
+-      if (!want_value(_value,option))
+-              return 0;
+-
+-      if (!want_number(_value,option,&number[0],255) ||
+-          !want_sep(_value,option,'.') ||
+-          !want_number(_value,option,&number[1],255) ||
+-          !want_sep(_value,option,'.') ||
+-          !want_number(_value,option,&number[2],255) ||
+-          !want_sep(_value,option,'.') ||
+-          !want_number(_value,option,&number[3],255))
+-              return 0;
+-
+-      ((u8*)addr)[0] = number[0];
+-      ((u8*)addr)[1] = number[1];
+-      ((u8*)addr)[2] = number[2];
+-      ((u8*)addr)[3] = number[3];
+-
+-      return 1;
+-} /* end want_numeric() */
+-#endif
+-
+-/*****************************************************************************/
+-/*
+  * parse the mount options
+  * - this function has been shamelessly adapted from the ext3 fs which shamelessly adapted it from
+  *   the msdos fs
+  */
+-static int afs_super_parse_options(struct afs_super_info *as, char *options, const char ** devname)
++static int afs_super_parse_options(struct afs_mount_params *params,
++                                 char *options,
++                                 const char **devname)
+ {
+       char *key, *value;
+       int ret;
+-      _enter("%s",options);
++      _enter("%s", options);
++
++      options[PAGE_SIZE - 1] = 0;
+       ret = 0;
+-      while ((key = strsep(&options,",")))
++      while ((key = strsep(&options, ",")))
+       {
+-              value = strchr(key,'=');
++              value = strchr(key, '=');
+               if (value)
+                       *value++ = 0;
+-              printk("kAFS: KEY: %s, VAL:%s\n",key,value?:"-");
++              printk("kAFS: KEY: %s, VAL:%s\n", key, value ?: "-");
+-              if (strcmp(key,"rwpath")==0) {
+-                      if (!want_no_value(&value,"rwpath")) return -EINVAL;
+-                      as->rwparent = 1;
++              if (strcmp(key, "rwpath") == 0) {
++                      if (!want_no_value(&value, "rwpath"))
++                              return -EINVAL;
++                      params->rwpath = 1;
+                       continue;
+               }
+-              else if (strcmp(key,"vol")==0) {
+-                      if (!want_arg(&value,"vol")) return -EINVAL;
++              else if (strcmp(key, "vol") == 0) {
++                      if (!want_arg(&value, "vol"))
++                              return -EINVAL;
+                       *devname = value;
+                       continue;
+               }
+-
+-#if 0
+-              if (strcmp(key,"servers")==0) {
+-                      if (!want_arg(&value,"servers")) return -EINVAL;
+-
+-                      _debug("servers=%s",value);
+-
+-                      for (;;) {
+-                              struct in_addr addr;
+-
+-                              if (!want_ipaddr(&value,"servers",&addr))
+-                                      return -EINVAL;
+-
+-                              ret = afs_create_server(as->cell,&addr,&as->server);
+-                              if (ret<0) {
+-                                      printk("kAFS: unable to create server: %d\n",ret);
+-                                      return ret;
+-                              }
+-
+-                              if (!*value)
+-                                      break;
+-
+-                              if (as->server) {
+-                                      printk(KERN_NOTICE
+-                                             "kAFS: only one server can be specified\n");
+-                                      return -EINVAL;
+-                              }
+-
+-                              if (!want_sep(&value,"servers",':'))
+-                                      return -EINVAL;
+-                      }
++              else if (strcmp(key, "cell") == 0) {
++                      if (!want_arg(&value, "cell"))
++                              return -EINVAL;
++                      afs_put_cell(params->default_cell);
++                      ret = afs_cell_lookup(value,
++                                            strlen(value),
++                                            &params->default_cell);
++                      if (ret < 0)
++                              return -EINVAL;
+                       continue;
+               }
+-#endif
+-              printk("kAFS: Unknown mount option: '%s'\n",key);
++              printk("kAFS: Unknown mount option: '%s'\n",  key);
+               ret = -EINVAL;
+               goto error;
+       }
+@@ -309,67 +219,48 @@
+       ret = 0;
+  error:
+-      _leave(" = %d",ret);
+-
++      _leave(" = %d", ret);
+       return ret;
+ } /* end afs_super_parse_options() */
+-struct fill_super_options {
+-      const char *dev_name;
+-      void *options;
+-};
++/*****************************************************************************/
++/*
++ * check a superblock to see if it's the one we're looking for
++ */
++static int afs_test_super(struct super_block *sb, void *data)
++{
++      struct afs_mount_params *params = data;
++      struct afs_super_info *as = sb->s_fs_info;
++
++      return as->volume == params->volume;
++} /* end afs_test_super() */
+ /*****************************************************************************/
+ /*
+  * fill in the superblock
+  */
+-static int afs_fill_super(struct super_block *sb, void *_data, int silent)
++static int afs_fill_super(struct super_block *sb, void *data, int silent)
+ {
++      struct afs_mount_params *params = data;
+       struct afs_super_info *as = NULL;
+       struct dentry *root = NULL;
+       struct inode *inode = NULL;
+       afs_fid_t fid;
+-      struct fill_super_options *data = _data;
+-      const char *devname;
+-      char *options;
+       int ret;
+-      _enter("");
+-
+-      if (!data) {
+-              _leave(" = -EINVAL");
+-              return -EINVAL;
+-      }
+-      devname = data->dev_name;
+-      options = data->options;
+-      if (options)
+-              options[PAGE_SIZE-1] = 0;
++      kenter("");
+       /* allocate a superblock info record */
+-      as = kmalloc(sizeof(struct afs_super_info),GFP_KERNEL);
++      as = kmalloc(sizeof(struct afs_super_info), GFP_KERNEL);
+       if (!as) {
+               _leave(" = -ENOMEM");
+               return -ENOMEM;
+       }
+-      memset(as,0,sizeof(struct afs_super_info));
++      memset(as, 0, sizeof(struct afs_super_info));
+-      /* parse the options */
+-      if (options) {
+-              ret = afs_super_parse_options(as,options,&devname);
+-              if (ret<0)
+-                      goto error;
+-              if (!devname) {
+-                      printk("kAFS: no volume name specified\n");
+-                      ret = -EINVAL;
+-                      goto error;
+-              }
+-      }
+-
+-      /* parse the device name */
+-      ret = afs_volume_lookup(devname,as->rwparent,&as->volume);
+-      if (ret<0)
+-              goto error;
++      afs_get_volume(params->volume);
++      as->volume = params->volume;
+       /* fill in the superblock */
+       sb->s_blocksize         = PAGE_CACHE_SIZE;
+@@ -382,8 +273,8 @@
+       fid.vid         = as->volume->vid;
+       fid.vnode       = 1;
+       fid.unique      = 1;
+-      ret = afs_iget(sb,&fid,&inode);
+-      if (ret<0)
++      ret = afs_iget(sb, &fid, &inode);
++      if (ret < 0)
+               goto error;
+       ret = -ENOMEM;
+@@ -393,19 +284,18 @@
+       sb->s_root = root;
+-      _leave(" = 0");
++      kleave(" = 0");
+       return 0;
+  error:
+-      if (root) dput(root);
+-      if (inode) iput(inode);
+-      if (as) {
+-              if (as->volume)         afs_put_volume(as->volume);
+-              kfree(as);
+-      }
++      dput(root);
++      iput(inode);
++      afs_put_volume(as->volume);
++      kfree(as);
++
+       sb->s_fs_info = NULL;
+-      _leave(" = %d",ret);
++      kleave(" = %d", ret);
+       return ret;
+ } /* end afs_fill_super() */
+@@ -414,32 +304,72 @@
+  * get an AFS superblock
+  * - TODO: don't use get_sb_nodev(), but rather call sget() directly
+  */
+-static struct super_block *
+-afs_get_sb(struct file_system_type *fs_type, int flags,
+-         const char *dev_name, void *options)
++static struct super_block *afs_get_sb(struct file_system_type *fs_type,
++                                    int flags,
++                                    const char *dev_name,
++                                    void *options)
+ {
++      struct afs_mount_params params;
+       struct super_block *sb;
+-      struct fill_super_options data = { dev_name, options };
+       int ret;
+-      _enter(",,%s,%p",dev_name,options);
++      _enter(",,%s,%p", dev_name, options);
++
++      memset(&params, 0, sizeof(params));
+       /* start the cache manager */
+       ret = afscm_start();
+-      if (ret<0) {
+-              _leave(" = %d",ret);
++      if (ret < 0) {
++              _leave(" = %d", ret);
+               return ERR_PTR(ret);
+       }
++      /* parse the options */
++      if (options) {
++              ret = afs_super_parse_options(&params, options, &dev_name);
++              if (ret < 0)
++                      goto error;
++              if (!dev_name) {
++                      printk("kAFS: no volume name specified\n");
++                      ret = -EINVAL;
++                      goto error;
++              }
++      }
++
++      /* parse the device name */
++      ret = afs_volume_lookup(dev_name,
++                              params.default_cell,
++                              params.rwpath,
++                              &params.volume);
++      if (ret < 0)
++              goto error;
++
+       /* allocate a deviceless superblock */
+-      sb = get_sb_nodev(fs_type, flags, &data, afs_fill_super);
+-      if (IS_ERR(sb)) {
+-              afscm_stop();
+-              return sb;
++      sb = sget(fs_type, afs_test_super, set_anon_super, &params);
++      if (IS_ERR(sb))
++              goto error;
++
++      sb->s_flags = flags;
++
++      ret = afs_fill_super(sb, &params, flags & MS_VERBOSE ? 1 : 0);
++      if (ret < 0) {
++              up_write(&sb->s_umount);
++              deactivate_super(sb);
++              goto error;
+       }
++      sb->s_flags |= MS_ACTIVE;
+-      _leave("");
++      afs_put_volume(params.volume);
++      afs_put_cell(params.default_cell);
++      _leave(" = %p", sb);
+       return sb;
++
++ error:
++      afs_put_volume(params.volume);
++      afs_put_cell(params.default_cell);
++      afscm_stop();
++      _leave(" = %d", ret);
++      return ERR_PTR(ret);
+ } /* end afs_get_sb() */
+ /*****************************************************************************/
+@@ -452,11 +382,7 @@
+       _enter("");
+-      if (as) {
+-              if (as->volume)         afs_put_volume(as->volume);
+-      }
+-
+-      /* stop the cache manager */
++      afs_put_volume(as->volume);
+       afscm_stop();
+       _leave("");
+@@ -466,18 +392,21 @@
+ /*
+  * initialise an inode cache slab element prior to any use
+  */
+-static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags)
++static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep,
++                          unsigned long flags)
+ {
+       afs_vnode_t *vnode = (afs_vnode_t *) _vnode;
+-      if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) {
+-              memset(vnode,0,sizeof(*vnode));
++      if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
++          SLAB_CTOR_CONSTRUCTOR) {
++              memset(vnode, 0, sizeof(*vnode));
+               inode_init_once(&vnode->vfs_inode);
+               init_waitqueue_head(&vnode->update_waitq);
+               spin_lock_init(&vnode->lock);
+               INIT_LIST_HEAD(&vnode->cb_link);
+               INIT_LIST_HEAD(&vnode->cb_hash_link);
+-              afs_timer_init(&vnode->cb_timeout,&afs_vnode_cb_timed_out_ops);
++              afs_timer_init(&vnode->cb_timeout,
++                             &afs_vnode_cb_timed_out_ops);
+       }
+ } /* end afs_i_init_once() */
+@@ -490,16 +419,19 @@
+ {
+       afs_vnode_t *vnode;
+-      vnode = (afs_vnode_t *) kmem_cache_alloc(afs_inode_cachep,SLAB_KERNEL);
++      vnode = (afs_vnode_t *)
++              kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL);
+       if (!vnode)
+               return NULL;
+-      memset(&vnode->fid,0,sizeof(vnode->fid));
+-      memset(&vnode->status,0,sizeof(vnode->status));
++      atomic_inc(&afs_count_active_inodes);
++
++      memset(&vnode->fid, 0, sizeof(vnode->fid));
++      memset(&vnode->status, 0, sizeof(vnode->status));
+-      vnode->volume = NULL;
+-      vnode->update_cnt = 0;
+-      vnode->flags = 0;
++      vnode->volume           = NULL;
++      vnode->update_cnt       = 0;
++      vnode->flags            = 0;
+       return &vnode->vfs_inode;
+ } /* end afs_alloc_inode() */
+@@ -510,6 +442,10 @@
+  */
+ static void afs_destroy_inode(struct inode *inode)
+ {
+-      _enter("{%lu}",inode->i_ino);
++      _enter("{%lu}", inode->i_ino);
++
+       kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode));
++
++      atomic_dec(&afs_count_active_inodes);
++
+ } /* end afs_destroy_inode() */
+Index: linux-2.6.0-test5/fs/afs/super.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/super.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/super.h   2003-09-27 11:38:36.020052504 +0800
+@@ -29,7 +29,7 @@
+  */
+ struct afs_super_info
+ {
+-      afs_volume_t            *volume;        /* volume record */
++      struct afs_volume       *volume;        /* volume record */
+       char                    rwparent;       /* T if parent is R/W AFS volume */
+ };
+Index: linux-2.6.0-test5/fs/afs/types.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/types.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/types.h   2003-09-27 11:38:36.022052200 +0800
+@@ -33,26 +33,13 @@
+ typedef struct afs_volume             afs_volume_t;
+ typedef struct afs_volume_info                afs_volume_info_t;
+-typedef struct afsc_cache             afsc_cache_t;
+-typedef struct afsc_cache_cell                afsc_cache_cell_t;
+-typedef struct afsc_cache_vldb                afsc_cache_vldb_t;
+-typedef struct afsc_cell_record               afsc_cell_record_t;
+-typedef struct afsc_inode             afsc_inode_t;
+-typedef struct afsc_io                        afsc_io_t;
+-typedef struct afsc_io_subop          afsc_io_subop_t;
+-typedef struct afsc_io_queue          afsc_io_queue_t;
+-typedef struct afsc_super_block               afsc_super_block_t;
+-typedef struct afsc_vldb_record               afsc_vldb_record_t;
+-typedef struct afsc_vnode_catalogue   afsc_vnode_catalogue_t;
+-typedef struct afsc_vnode_meta                afsc_vnode_meta_t;
+-
+ typedef struct afsvl_dbentry          afsvl_dbentry_t;
+ typedef enum {
+       AFSVL_RWVOL,                    /* read/write volume */
+       AFSVL_ROVOL,                    /* read-only volume */
+       AFSVL_BACKVOL,                  /* backup volume */
+-} afs_voltype_t;
++} __attribute__((packed)) afs_voltype_t;
+ extern const char *afs_voltypes[];
+Index: linux-2.6.0-test5/fs/afs/vlclient.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vlclient.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vlclient.c        2003-09-27 11:38:36.028051288 +0800
+@@ -176,8 +176,8 @@
+ /*
+  * look up a volume location database entry by name
+  */
+-int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
+-                             afsc_vldb_record_t *entry)
++int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsigned volnamesz,
++                             struct afs_cache_vlocation *entry)
+ {
+       DECLARE_WAITQUEUE(myself,current);
+@@ -189,29 +189,29 @@
+       int ret, loop;
+       u32 *bp, param[2], zero;
+-      _enter(",%s,",volname);
++      _enter(",%*.*s,%u,", volnamesz, volnamesz, volname, volnamesz);
+-      memset(entry,0,sizeof(*entry));
++      memset(entry, 0, sizeof(*entry));
+       /* get hold of the vlserver connection */
+-      ret = afs_server_get_vlconn(server,&conn);
++      ret = afs_server_get_vlconn(server, &conn);
+       if (ret<0)
+               goto out;
+       /* create a call through that connection */
+-      ret = rxrpc_create_call(conn,NULL,NULL,afs_rxvl_aemap,&call);
+-      if (ret<0) {
+-              printk("kAFS: Unable to create call: %d\n",ret);
++      ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
++      if (ret < 0) {
++              printk("kAFS: Unable to create call: %d\n", ret);
+               goto out_put_conn;
+       }
+       call->app_opcode = VLGETENTRYBYNAME;
+       /* we want to get event notifications from the call */
+-      add_wait_queue(&call->waitq,&myself);
++      add_wait_queue(&call->waitq, &myself);
+       /* marshall the parameters */
+-      piov[1].iov_len = strlen(volname);
+-      piov[1].iov_base = (char*)volname;
++      piov[1].iov_len = volnamesz;
++      piov[1].iov_base = (char*) volname;
+       zero = 0;
+       piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
+@@ -224,16 +224,16 @@
+       piov[0].iov_base = param;
+       /* send the parameters to the server */
+-      ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
++      ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, 0, &sent);
+       if (ret<0)
+               goto abort;
+       /* wait for the reply to completely arrive */
+-      bp = rxrpc_call_alloc_scratch(call,384);
++      bp = rxrpc_call_alloc_scratch(call, 384);
+-      ret = rxrpc_call_read_data(call,bp,384,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
+-      if (ret<0) {
+-              if (ret==-ECONNABORTED) {
++      ret = rxrpc_call_read_data(call, bp, 384, RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
++      if (ret < 0) {
++              if (ret == -ECONNABORTED) {
+                       ret = call->app_errno;
+                       goto out_unwait;
+               }
+@@ -255,9 +255,9 @@
+       for (loop=0; loop<8; loop++) {
+               tmp = ntohl(*bp++);
+-              if (tmp & AFS_VLSF_RWVOL  ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
+-              if (tmp & AFS_VLSF_ROVOL  ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
+-              if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
++              if (tmp & AFS_VLSF_RWVOL  ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
++              if (tmp & AFS_VLSF_ROVOL  ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
++              if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
+       }
+       entry->vid[0] = ntohl(*bp++);
+@@ -267,26 +267,26 @@
+       bp++; /* clone ID */
+       tmp = ntohl(*bp++); /* flags */
+-      if (tmp & AFS_VLF_RWEXISTS  ) entry->vidmask |= AFSC_VOL_STM_RW;
+-      if (tmp & AFS_VLF_ROEXISTS  ) entry->vidmask |= AFSC_VOL_STM_RO;
+-      if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
++      if (tmp & AFS_VLF_RWEXISTS  ) entry->vidmask |= AFS_VOL_VTM_RW;
++      if (tmp & AFS_VLF_ROEXISTS  ) entry->vidmask |= AFS_VOL_VTM_RO;
++      if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
+       ret = -ENOMEDIUM;
+       if (!entry->vidmask)
+               goto abort;
+       /* success */
+-      entry->ctime = get_seconds();
++      entry->rtime = get_seconds();
+       ret = 0;
+  out_unwait:
+       set_current_state(TASK_RUNNING);
+-      remove_wait_queue(&call->waitq,&myself);
++      remove_wait_queue(&call->waitq, &myself);
+       rxrpc_put_call(call);
+  out_put_conn:
+       rxrpc_put_connection(conn);
+  out:
+-      _leave(" = %d",ret);
++      _leave(" = %d", ret);
+       return ret;
+  abort:
+@@ -303,7 +303,7 @@
+ int afs_rxvl_get_entry_by_id(afs_server_t *server,
+                            afs_volid_t volid,
+                            afs_voltype_t voltype,
+-                           afsc_vldb_record_t *entry)
++                           struct afs_cache_vlocation *entry)
+ {
+       DECLARE_WAITQUEUE(myself,current);
+@@ -375,9 +375,9 @@
+       for (loop=0; loop<8; loop++) {
+               tmp = ntohl(*bp++);
+-              if (tmp & AFS_VLSF_RWVOL  ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
+-              if (tmp & AFS_VLSF_ROVOL  ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
+-              if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
++              if (tmp & AFS_VLSF_RWVOL  ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
++              if (tmp & AFS_VLSF_ROVOL  ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
++              if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
+       }
+       entry->vid[0] = ntohl(*bp++);
+@@ -387,9 +387,9 @@
+       bp++; /* clone ID */
+       tmp = ntohl(*bp++); /* flags */
+-      if (tmp & AFS_VLF_RWEXISTS  ) entry->vidmask |= AFSC_VOL_STM_RW;
+-      if (tmp & AFS_VLF_ROEXISTS  ) entry->vidmask |= AFSC_VOL_STM_RO;
+-      if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
++      if (tmp & AFS_VLF_RWEXISTS  ) entry->vidmask |= AFS_VOL_VTM_RW;
++      if (tmp & AFS_VLF_ROEXISTS  ) entry->vidmask |= AFS_VOL_VTM_RO;
++      if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
+       ret = -ENOMEDIUM;
+       if (!entry->vidmask)
+@@ -401,13 +401,13 @@
+       entry->servers[1].s_addr = htonl(0xac101243);
+       entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
+-      entry->srvtmask[0] = AFSC_VOL_STM_RO;
+-      entry->srvtmask[1] = AFSC_VOL_STM_RO;
+-      entry->srvtmask[2] = AFSC_VOL_STM_RO | AFSC_VOL_STM_RW;
++      entry->srvtmask[0] = AFS_VOL_VTM_RO;
++      entry->srvtmask[1] = AFS_VOL_VTM_RO;
++      entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
+ #endif
+       /* success */
+-      entry->ctime = get_seconds();
++      entry->rtime = get_seconds();
+       ret = 0;
+  out_unwait:
+@@ -520,7 +520,7 @@
+  * attend to the asynchronous get VLDB entry by ID
+  */
+ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
+-                                  afsc_vldb_record_t *entry)
++                                  struct afs_cache_vlocation *entry)
+ {
+       unsigned *bp, tmp;
+       int loop, ret;
+@@ -550,9 +550,9 @@
+               for (loop=0; loop<8; loop++) {
+                       tmp = ntohl(*bp++);
+-                      if (tmp & AFS_VLSF_RWVOL  ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
+-                      if (tmp & AFS_VLSF_ROVOL  ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
+-                      if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
++                      if (tmp & AFS_VLSF_RWVOL  ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
++                      if (tmp & AFS_VLSF_ROVOL  ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
++                      if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
+               }
+               entry->vid[0] = ntohl(*bp++);
+@@ -562,9 +562,9 @@
+               bp++; /* clone ID */
+               tmp = ntohl(*bp++); /* flags */
+-              if (tmp & AFS_VLF_RWEXISTS  ) entry->vidmask |= AFSC_VOL_STM_RW;
+-              if (tmp & AFS_VLF_ROEXISTS  ) entry->vidmask |= AFSC_VOL_STM_RO;
+-              if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
++              if (tmp & AFS_VLF_RWEXISTS  ) entry->vidmask |= AFS_VOL_VTM_RW;
++              if (tmp & AFS_VLF_ROEXISTS  ) entry->vidmask |= AFS_VOL_VTM_RO;
++              if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
+               ret = -ENOMEDIUM;
+               if (!entry->vidmask) {
+@@ -578,13 +578,13 @@
+               entry->servers[1].s_addr = htonl(0xac101243);
+               entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
+-              entry->srvtmask[0] = AFSC_VOL_STM_RO;
+-              entry->srvtmask[1] = AFSC_VOL_STM_RO;
+-              entry->srvtmask[2] = AFSC_VOL_STM_RO | AFSC_VOL_STM_RW;
++              entry->srvtmask[0] = AFS_VOL_VTM_RO;
++              entry->srvtmask[1] = AFS_VOL_VTM_RO;
++              entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
+ #endif
+               /* success */
+-              entry->ctime = get_seconds();
++              entry->rtime = get_seconds();
+               ret = 0;
+               goto done;
+       }
+@@ -626,7 +626,8 @@
+       case RXRPC_CSTATE_CLNT_GOT_REPLY:
+               if (call->app_read_count==0)
+                       break;
+-              printk("kAFS: Reply bigger than expected {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
++              printk("kAFS: Reply bigger than expected"
++                     " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
+                      call->app_call_state,
+                      call->app_async_read,
+                      call->app_mark,
+Index: linux-2.6.0-test5/fs/afs/vlclient.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vlclient.h   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vlclient.h        2003-09-27 11:38:36.030050984 +0800
+@@ -46,7 +46,7 @@
+ };
+ /* maps to "struct vldbentry" in vvl-spec.pdf */
+-struct  afsvl_dbentry {
++struct afs_vldbentry {
+       char            name[65];               /* name of volume (including NUL char) */
+       afs_voltype_t   type;                   /* volume type */
+       unsigned        num_servers;            /* num servers that hold instances of this vol */
+@@ -77,19 +77,20 @@
+ /* look up a volume location database entry by name */
+ extern int afs_rxvl_get_entry_by_name(afs_server_t *server,
+                                     const char *volname,
+-                                    afsc_vldb_record_t *entry);
++                                    unsigned volnamesz,
++                                    struct afs_cache_vlocation *entry);
+ /* look up a volume location database entry by ID */
+ extern int afs_rxvl_get_entry_by_id(afs_server_t *server,
+                                   afs_volid_t volid,
+                                   afs_voltype_t voltype,
+-                                  afsc_vldb_record_t *entry);
++                                  struct afs_cache_vlocation *entry);
+ extern int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
+                                         afs_volid_t volid,
+                                         afs_voltype_t voltype);
+ extern int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
+-                                         afsc_vldb_record_t *entry);
++                                         struct afs_cache_vlocation *entry);
+ #endif /* _LINUX_AFS_VLCLIENT_H */
+Index: linux-2.6.0-test5/fs/afs/vlocation.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vlocation.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vlocation.c       2003-09-27 11:38:36.037049920 +0800
+@@ -56,6 +56,19 @@
+ static afs_vlocation_t *afs_vlocation_update; /* VL currently being updated */
+ static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guarding update queue */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vlocation_cache_match(void *target, const void *entry);
++static void afs_vlocation_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_vlocation_cache_index_def = {
++      .name           = "vldb",
++      .data_size      = sizeof(struct afs_cache_vlocation),
++      .keys[0]        = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
++      .match          = afs_vlocation_cache_match,
++      .update         = afs_vlocation_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+  * iterate through the VL servers in a cell until one of them admits knowing about the volume in
+@@ -64,21 +77,23 @@
+  */
+ static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
+                                          const char *name,
+-                                         afsc_vldb_record_t *vldb)
++                                         unsigned namesz,
++                                         struct afs_cache_vlocation *vldb)
+ {
+       afs_server_t *server = NULL;
+       afs_cell_t *cell = vlocation->cell;
+       int count, ret;
+-      _enter("%s,%s,",cell->name,name);
++      _enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz);
+       ret = -ENOMEDIUM;
+       for (count=cell->vl_naddrs; count>0; count--) {
+               _debug("CellServ[%hu]: %08x",
+-                     cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
++                     cell->vl_curr_svix,
++                     cell->vl_addrs[cell->vl_curr_svix].s_addr);
+               /* try and create a server */
+-              ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
++              ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
+               switch (ret) {
+               case 0:
+                       break;
+@@ -90,7 +105,7 @@
+               }
+               /* attempt to access the VL server */
+-              ret = afs_rxvl_get_entry_by_name(server,name,vldb);
++              ret = afs_rxvl_get_entry_by_name(server, name, namesz, vldb);
+               switch (ret) {
+               case 0:
+                       afs_put_server(server);
+@@ -107,7 +122,7 @@
+                       }
+                       up_write(&server->sem);
+                       afs_put_server(server);
+-                      if (ret==-ENOMEM || ret==-ENONET)
++                      if (ret == -ENOMEM || ret == -ENONET)
+                               goto out;
+                       goto rotate;
+               case -ENOMEDIUM:
+@@ -140,21 +155,22 @@
+ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
+                                        afs_volid_t volid,
+                                        afs_voltype_t voltype,
+-                                       afsc_vldb_record_t *vldb)
++                                       struct afs_cache_vlocation *vldb)
+ {
+       afs_server_t *server = NULL;
+       afs_cell_t *cell = vlocation->cell;
+       int count, ret;
+-      _enter("%s,%x,%d,",cell->name,volid,voltype);
++      _enter("%s,%x,%d,", cell->name, volid, voltype);
+       ret = -ENOMEDIUM;
+       for (count=cell->vl_naddrs; count>0; count--) {
+               _debug("CellServ[%hu]: %08x",
+-                     cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
++                     cell->vl_curr_svix,
++                     cell->vl_addrs[cell->vl_curr_svix].s_addr);
+               /* try and create a server */
+-              ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
++              ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
+               switch (ret) {
+               case 0:
+                       break;
+@@ -166,7 +182,7 @@
+               }
+               /* attempt to access the VL server */
+-              ret = afs_rxvl_get_entry_by_id(server,volid,voltype,vldb);
++              ret = afs_rxvl_get_entry_by_id(server, volid, voltype, vldb);
+               switch (ret) {
+               case 0:
+                       afs_put_server(server);
+@@ -183,7 +199,7 @@
+                       }
+                       up_write(&server->sem);
+                       afs_put_server(server);
+-                      if (ret==-ENOMEM || ret==-ENONET)
++                      if (ret == -ENOMEM || ret == -ENONET)
+                               goto out;
+                       goto rotate;
+               case -ENOMEDIUM:
+@@ -216,74 +232,83 @@
+  * - lookup in the local cache if not able to find on the VL server
+  * - insert/update in the local cache if did get a VL response
+  */
+-int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation)
++int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
++                       afs_vlocation_t **_vlocation)
+ {
+-      afsc_vldb_record_t vldb;
++      struct afs_cache_vlocation vldb;
+       struct list_head *_p;
+       afs_vlocation_t *vlocation;
+       afs_voltype_t voltype;
+       afs_volid_t vid;
+       int active = 0, ret;
+-      _enter(",%s,%s,",cell->name,name);
++      _enter("{%s},%*.*s,%u,", cell->name, namesz, namesz, name, namesz);
+-      if (strlen(name)>sizeof(vlocation->vldb.name)) {
++      if (namesz > sizeof(vlocation->vldb.name)) {
+               _leave(" = -ENAMETOOLONG");
+               return -ENAMETOOLONG;
+       }
+       /* search the cell's active list first */
+-      list_for_each(_p,&cell->vl_list) {
+-              vlocation = list_entry(_p,afs_vlocation_t,link);
+-              if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
++      list_for_each(_p, &cell->vl_list) {
++              vlocation = list_entry(_p, afs_vlocation_t, link);
++              if (namesz < sizeof(vlocation->vldb.name) &&
++                  vlocation->vldb.name[namesz] != '\0')
++                      continue;
++
++              if (memcmp(vlocation->vldb.name, name, namesz) == 0)
+                       goto found_in_memory;
+       }
+       /* search the cell's graveyard list second */
+       spin_lock(&cell->vl_gylock);
+-      list_for_each(_p,&cell->vl_graveyard) {
+-              vlocation = list_entry(_p,afs_vlocation_t,link);
+-              if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
++      list_for_each(_p, &cell->vl_graveyard) {
++              vlocation = list_entry(_p, afs_vlocation_t, link);
++              if (namesz < sizeof(vlocation->vldb.name) &&
++                  vlocation->vldb.name[namesz] != '\0')
++                      continue;
++
++              if (memcmp(vlocation->vldb.name, name, namesz) == 0)
+                       goto found_in_graveyard;
+       }
+       spin_unlock(&cell->vl_gylock);
+       /* not in the cell's in-memory lists - create a new record */
+-      vlocation = kmalloc(sizeof(afs_vlocation_t),GFP_KERNEL);
++      vlocation = kmalloc(sizeof(afs_vlocation_t), GFP_KERNEL);
+       if (!vlocation)
+               return -ENOMEM;
+-      memset(vlocation,0,sizeof(afs_vlocation_t));
+-      atomic_set(&vlocation->usage,1);
++      memset(vlocation, 0, sizeof(afs_vlocation_t));
++      atomic_set(&vlocation->usage, 1);
+       INIT_LIST_HEAD(&vlocation->link);
+       rwlock_init(&vlocation->lock);
+-      strncpy(vlocation->vldb.name,name,sizeof(vlocation->vldb.name));
++      memcpy(vlocation->vldb.name, name, namesz);
+-      afs_timer_init(&vlocation->timeout,&afs_vlocation_timer_ops);
+-      afs_timer_init(&vlocation->upd_timer,&afs_vlocation_update_timer_ops);
+-      afs_async_op_init(&vlocation->upd_op,&afs_vlocation_update_op_ops);
+-
+-      INIT_LIST_HEAD(&vlocation->caches);
++      afs_timer_init(&vlocation->timeout, &afs_vlocation_timer_ops);
++      afs_timer_init(&vlocation->upd_timer, &afs_vlocation_update_timer_ops);
++      afs_async_op_init(&vlocation->upd_op, &afs_vlocation_update_op_ops);
+       afs_get_cell(cell);
+       vlocation->cell = cell;
+-      list_add_tail(&vlocation->link,&cell->vl_list);
++      list_add_tail(&vlocation->link, &cell->vl_list);
+-#if 0
+-      /* search local cache if wasn't in memory */
+-      ret = afsc_lookup_vlocation(vlocation);
+-      switch (ret) {
+-      default:        goto error;             /* disk error */
+-      case 0:         goto found_in_cache;    /* pulled from local cache into memory */
+-      case -ENOENT:   break;                  /* not in local cache */
+-      }
++#ifdef AFS_CACHING_SUPPORT
++      /* we want to store it in the cache, plus it might already be encached */
++      cachefs_acquire_cookie(cell->cache,
++                             &afs_volume_cache_index_def,
++                             vlocation,
++                             &vlocation->cache);
++
++      if (vlocation->valid)
++              goto found_in_cache;
+ #endif
+       /* try to look up an unknown volume in the cell VL databases by name */
+-      ret = afs_vlocation_access_vl_by_name(vlocation,name,&vldb);
++      ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb);
+       if (ret<0) {
+-              printk("kAFS: failed to locate '%s' in cell '%s'\n",name,cell->name);
++              printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
++                     namesz, namesz, name, cell->name);
+               goto error;
+       }
+@@ -294,7 +319,7 @@
+       _debug("found in graveyard");
+       atomic_inc(&vlocation->usage);
+       list_del(&vlocation->link);
+-      list_add_tail(&vlocation->link,&cell->vl_list);
++      list_add_tail(&vlocation->link, &cell->vl_list);
+       spin_unlock(&cell->vl_gylock);
+       afs_kafstimod_del_timer(&vlocation->timeout);
+@@ -308,30 +333,32 @@
+  active:
+       active = 1;
+-/* found_in_cache: */
++#ifdef AFS_CACHING_SUPPORT
++ found_in_cache:
++#endif
+       /* try to look up a cached volume in the cell VL databases by ID */
+       _debug("found in cache");
+       _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
+              vlocation->vldb.name,
+              vlocation->vldb.vidmask,
+-             ntohl(vlocation->vldb.servers[0].s_addr),vlocation->vldb.srvtmask[0],
+-             ntohl(vlocation->vldb.servers[1].s_addr),vlocation->vldb.srvtmask[1],
+-             ntohl(vlocation->vldb.servers[2].s_addr),vlocation->vldb.srvtmask[2]
++             ntohl(vlocation->vldb.servers[0].s_addr), vlocation->vldb.srvtmask[0],
++             ntohl(vlocation->vldb.servers[1].s_addr), vlocation->vldb.srvtmask[1],
++             ntohl(vlocation->vldb.servers[2].s_addr), vlocation->vldb.srvtmask[2]
+              );
+       _debug("Vids: %08x %08x %08x",
+-             vlocation->vldb.vid[0],vlocation->vldb.vid[1],vlocation->vldb.vid[2]);
++             vlocation->vldb.vid[0], vlocation->vldb.vid[1], vlocation->vldb.vid[2]);
+-      if (vlocation->vldb.vidmask & AFSC_VOL_STM_RW) {
++      if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
+               vid = vlocation->vldb.vid[0];
+               voltype = AFSVL_RWVOL;
+       }
+-      else if (vlocation->vldb.vidmask & AFSC_VOL_STM_RO) {
++      else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
+               vid = vlocation->vldb.vid[1];
+               voltype = AFSVL_ROVOL;
+       }
+-      else if (vlocation->vldb.vidmask & AFSC_VOL_STM_BAK) {
++      else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
+               vid = vlocation->vldb.vid[2];
+               voltype = AFSVL_BACKVOL;
+       }
+@@ -341,41 +368,44 @@
+               voltype = 0;
+       }
+-      ret = afs_vlocation_access_vl_by_id(vlocation,vid,voltype,&vldb);
++      ret = afs_vlocation_access_vl_by_id(vlocation, vid, voltype, &vldb);
+       switch (ret) {
+               /* net error */
+       default:
+-              printk("kAFS: failed to volume '%s' (%x) up in '%s': %d\n",
+-                     name,vid,cell->name,ret);
++              printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
++                     namesz, namesz, name, vid, cell->name, ret);
+               goto error;
+               /* pulled from local cache into memory */
+-      case 0: 
++      case 0:
+               goto found_on_vlserver;
+               /* uh oh... looks like the volume got deleted */
+       case -ENOMEDIUM:
+-              printk("kAFS: volume '%s' (%x) does not exist '%s'\n",name,vid,cell->name);
++              printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
++                     namesz, namesz, name, vid, cell->name);
+               /* TODO: make existing record unavailable */
+               goto error;
+       }
+  found_on_vlserver:
+-      _debug("Done VL Lookup: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
+-             name,
++      _debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
++             namesz, namesz, name,
+              vldb.vidmask,
+-             ntohl(vldb.servers[0].s_addr),vldb.srvtmask[0],
+-             ntohl(vldb.servers[1].s_addr),vldb.srvtmask[1],
+-             ntohl(vldb.servers[2].s_addr),vldb.srvtmask[2]
++             ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
++             ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
++             ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
+              );
+-      _debug("Vids: %08x %08x %08x",vldb.vid[0],vldb.vid[1],vldb.vid[2]);
++      _debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]);
+-      if (strncmp(vldb.name,name,sizeof(vlocation->vldb.name))!=0)
+-              printk("kAFS: name of volume '%s' changed to '%s' on server\n",name,vldb.name);
++      if ((namesz < sizeof(vlocation->vldb.name) && vlocation->vldb.name[namesz] != '\0') ||
++          memcmp(vldb.name, name, namesz) != 0)
++              printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
++                     namesz, namesz, name, vldb.name);
+-      memcpy(&vlocation->vldb,&vldb,sizeof(vlocation->vldb));
++      memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
+ #if 0
+       /* add volume entry to local cache */
+@@ -384,7 +414,7 @@
+               goto error;
+ #endif
+-      afs_kafstimod_add_timer(&vlocation->upd_timer,10*HZ);
++      afs_kafstimod_add_timer(&vlocation->upd_timer, 10*HZ);
+       *_vlocation = vlocation;
+       _leave(" = 0 (%p)",vlocation);
+@@ -397,10 +427,10 @@
+               }
+               else {
+                       list_del(&vlocation->link);
+-                      afs_put_cell(vlocation->cell);
+-#if 0
+-                      afs_put_cache(vlocation->cache);
++#ifdef AFS_CACHING_SUPPORT
++                      cachefs_relinquish_cookie(vlocation->cache, 0);
+ #endif
++                      afs_put_cell(vlocation->cell);
+                       kfree(vlocation);
+               }
+       }
+@@ -414,12 +444,17 @@
+  * finish using a volume location record
+  * - caller must have cell->vol_sem write-locked
+  */
+-void __afs_put_vlocation(afs_vlocation_t *vlocation)
++void __afs_put_vlocation(struct afs_vlocation *vlocation)
+ {
+-      afs_cell_t *cell = vlocation->cell;
++      struct afs_cell *cell;
++
++      if (!vlocation)
++              return;
+       _enter("%s",vlocation->vldb.name);
++      cell = vlocation->cell;
++
+       /* sanity check */
+       if (atomic_read(&vlocation->usage)<=0)
+               BUG();
+@@ -453,11 +488,13 @@
+  */
+ void afs_put_vlocation(afs_vlocation_t *vlocation)
+ {
+-      afs_cell_t *cell = vlocation->cell;
++      if (vlocation) {
++              struct afs_cell *cell = vlocation->cell;
+-      down_write(&cell->vl_sem);
+-      __afs_put_vlocation(vlocation);
+-      up_write(&cell->vl_sem);
++              down_write(&cell->vl_sem);
++              __afs_put_vlocation(vlocation);
++              up_write(&cell->vl_sem);
++      }
+ } /* end afs_put_vlocation() */
+ /*****************************************************************************/
+@@ -489,10 +526,10 @@
+       }
+       /* we can now destroy it properly */
+-      afs_put_cell(cell);
+-#if 0
+-      afs_put_cache(vlocation->cache);
++#ifdef AFS_CACHING_SUPPORT
++      cachefs_relinquish_cookie(vlocation->cache,0);
+ #endif
++      afs_put_cell(cell);
+       kfree(vlocation);
+@@ -513,15 +550,15 @@
+              vlocation->vldb.name,vlocation->upd_first_svix,vlocation->upd_curr_svix);
+       /* try to look up a cached volume in the cell VL databases by ID */
+-      if (vlocation->vldb.vidmask & AFSC_VOL_STM_RW) {
++      if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
+               vid = vlocation->vldb.vid[0];
+               voltype = AFSVL_RWVOL;
+       }
+-      else if (vlocation->vldb.vidmask & AFSC_VOL_STM_RO) {
++      else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
+               vid = vlocation->vldb.vid[1];
+               voltype = AFSVL_ROVOL;
+       }
+-      else if (vlocation->vldb.vidmask & AFSC_VOL_STM_BAK) {
++      else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
+               vid = vlocation->vldb.vid[2];
+               voltype = AFSVL_BACKVOL;
+       }
+@@ -571,10 +608,8 @@
+               printk("kAFS: Abandoning VL update '%s': %d\n",vlocation->vldb.name,ret);
+       /* discard the server record */
+-      if (vlocation->upd_op.server) {
+-              afs_put_server(vlocation->upd_op.server);
+-              vlocation->upd_op.server = NULL;
+-      }
++      afs_put_server(vlocation->upd_op.server);
++      vlocation->upd_op.server = NULL;
+       spin_lock(&afs_vlocation_update_lock);
+       afs_vlocation_update = NULL;
+@@ -669,7 +704,7 @@
+  */
+ static void afs_vlocation_update_attend(afs_async_op_t *op)
+ {
+-      afsc_vldb_record_t vldb;
++      struct afs_cache_vlocation vldb;
+       afs_vlocation_t *vlocation = list_entry(op,afs_vlocation_t,upd_op);
+       unsigned tmp;
+       int ret;
+@@ -762,11 +797,9 @@
+  try_next:
+       vlocation->upd_busy_cnt = 0;
+-      if (vlocation->upd_op.server) {
+-              /* discard the server record */
+-              afs_put_server(vlocation->upd_op.server);
+-              vlocation->upd_op.server = NULL;
+-      }
++      /* discard the server record */
++      afs_put_server(vlocation->upd_op.server);
++      vlocation->upd_op.server = NULL;
+       tmp = vlocation->cell->vl_naddrs;
+       if (tmp==0)
+@@ -822,3 +855,68 @@
+       _leave("");
+ } /* end afs_vlocation_update_discard() */
++
++/*****************************************************************************/
++/*
++ * match a VLDB record stored in the cache
++ * - may also load target from entry
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vlocation_cache_match(void *target,
++                                                   const void *entry)
++{
++      const struct afs_cache_vlocation *vldb = entry;
++      struct afs_vlocation *vlocation = target;
++
++      _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
++
++      if (strncmp(vlocation->vldb.name,
++                  vldb->name,
++                  sizeof(vldb->name)) == 0) {
++              if (!vlocation->valid ||
++                  vlocation->vldb.rtime == vldb->rtime) {
++                      struct_cpy(&vlocation->vldb, vldb);
++                      vlocation->valid = 1;
++                      _leave(" = SUCCESS [c->m]");
++                      return CACHEFS_MATCH_SUCCESS;
++              }
++              /* need to update cache if cached info differs */
++              else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
++                      /* delete if VIDs for this name differ */
++                      if (memcmp(&vlocation->vldb.vid,
++                                 &vldb->vid,
++                                 sizeof(vldb->vid)) != 0) {
++                              _leave(" = DELETE");
++                              return CACHEFS_MATCH_SUCCESS_DELETE;
++                      }
++
++                      _leave(" = UPDATE");
++                      return CACHEFS_MATCH_SUCCESS_UPDATE;
++              }
++              else {
++                      _leave(" = SUCCESS");
++                      return CACHEFS_MATCH_SUCCESS;
++              }
++      }
++
++      _leave(" = FAILED");
++      return CACHEFS_MATCH_FAILED;
++} /* end afs_vlocation_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a VLDB record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_vlocation_cache_update(void *source, void *entry)
++{
++      struct afs_cache_vlocation *vldb = entry;
++      struct afs_vlocation *vlocation = source;
++
++      _enter("");
++
++      struct_cpy(vldb,&vlocation->vldb);
++
++} /* end afs_vlocation_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/vnode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vnode.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vnode.c   2003-09-27 11:38:36.040049464 +0800
+@@ -29,6 +29,19 @@
+       .timed_out      = afs_vnode_cb_timed_out,
+ };
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry);
++static void afs_vnode_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_vnode_cache_index_def = {
++      .name           = "vnode",
++      .data_size      = sizeof(struct afs_cache_vnode),
++      .keys[0]        = { CACHEFS_INDEX_KEYS_BIN, 4 },
++      .match          = afs_vnode_cache_match,
++      .update         = afs_vnode_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+  * handle a callback timing out
+@@ -61,8 +74,7 @@
+       spin_unlock(&vnode->lock);
+-      if (oldserver)
+-              afs_put_server(oldserver);
++      afs_put_server(oldserver);
+       _leave("");
+ } /* end afs_vnode_cb_timed_out() */
+@@ -126,8 +138,7 @@
+       wake_up_all(&vnode->update_waitq);
+-      if (oldserver)
+-              afs_put_server(oldserver);
++      afs_put_server(oldserver);
+       _leave("");
+@@ -272,7 +283,7 @@
+ /*****************************************************************************/
+ /*
+  * break any outstanding callback on a vnode
+- * - only relevant to server that issued it
++ * - only relevent to server that issued it
+  */
+ int afs_vnode_give_up_callback(afs_vnode_t *vnode)
+ {
+@@ -314,3 +325,56 @@
+       _leave(" = %d",ret);
+       return ret;
+ } /* end afs_vnode_give_up_callback() */
++
++/*****************************************************************************/
++/*
++ * match a vnode record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry)
++{
++      const struct afs_cache_vnode *cvnode = entry;
++      struct afs_vnode *vnode = target;
++
++      _enter("{%x,%x,%Lx},{%x,%x,%Lx}",
++             vnode->fid.vnode,
++             vnode->fid.unique,
++             vnode->status.version,
++             cvnode->vnode_id,
++             cvnode->vnode_unique,
++             cvnode->data_version);
++
++      if (vnode->fid.vnode != cvnode->vnode_id) {
++              _leave(" = FAILED");
++              return CACHEFS_MATCH_FAILED;
++      }
++
++      if (vnode->fid.unique != cvnode->vnode_unique ||
++          vnode->status.version != cvnode->data_version) {
++              _leave(" = DELETE");
++              return CACHEFS_MATCH_SUCCESS_DELETE;
++      }
++
++      _leave(" = SUCCESS");
++      return CACHEFS_MATCH_SUCCESS;
++} /* end afs_vnode_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a vnode record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_vnode_cache_update(void *source, void *entry)
++{
++      struct afs_cache_vnode *cvnode = entry;
++      struct afs_vnode *vnode = source;
++
++      _enter("");
++
++      cvnode->vnode_id        = vnode->fid.vnode;
++      cvnode->vnode_unique    = vnode->fid.unique;
++      cvnode->data_version    = vnode->status.version;
++
++} /* end afs_vnode_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/vnode.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/vnode.h      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/vnode.h   2003-09-27 11:38:36.042049160 +0800
+@@ -15,6 +15,7 @@
+ #include <linux/fs.h>
+ #include "server.h"
+ #include "kafstimod.h"
++#include "cache.h"
+ #ifdef __KERNEL__
+@@ -22,16 +23,33 @@
+ /*****************************************************************************/
+ /*
++ * vnode catalogue entry
++ */
++struct afs_cache_vnode
++{
++      afs_vnodeid_t           vnode_id;       /* vnode ID */
++      unsigned                vnode_unique;   /* vnode ID uniquifier */
++      afs_dataversion_t       data_version;   /* data version */
++};
++
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_vnode_cache_index_def;
++#endif
++
++/*****************************************************************************/
++/*
+  * AFS inode private data
+  */
+ struct afs_vnode
+ {
+       struct inode            vfs_inode;      /* the VFS's inode record */
+-      afs_volume_t            *volume;        /* volume on which vnode resides */
+-      afs_fid_t               fid;            /* the file identifier for this inode */
+-      afs_file_status_t       status;         /* AFS status info for this file */
+-      unsigned                nix;            /* vnode index in cache */
++      struct afs_volume       *volume;        /* volume on which vnode resides */
++      struct afs_fid          fid;            /* the file identifier for this inode */
++      struct afs_file_status  status;         /* AFS status info for this file */
++#ifdef AFS_CACHING_SUPPORT
++      struct cachefs_cookie   *cache;         /* caching cookie */
++#endif
+       wait_queue_head_t       update_waitq;   /* status fetch waitqueue */
+       unsigned                update_cnt;     /* number of outstanding ops that will update the
+@@ -43,10 +61,10 @@
+ #define AFS_VNODE_MOUNTPOINT  0x00000004      /* set if vnode is a mountpoint symlink */
+       /* outstanding callback notification on this file */
+-      afs_server_t            *cb_server;     /* server that made the current promise */
++      struct afs_server       *cb_server;     /* server that made the current promise */
+       struct list_head        cb_link;        /* link in server's promises list */
+       struct list_head        cb_hash_link;   /* link in master callback hash */
+-      afs_timer_t             cb_timeout;     /* timeout on promise */
++      struct afs_timer        cb_timeout;     /* timeout on promise */
+       unsigned                cb_version;     /* callback version */
+       unsigned                cb_expiry;      /* callback expiry time */
+       afs_callback_type_t     cb_type;        /* type of callback */
+Index: linux-2.6.0-test5/fs/afs/volume.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/volume.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/volume.c  2003-09-27 11:38:36.046048552 +0800
+@@ -16,7 +16,9 @@
+ #include <linux/fs.h>
+ #include <linux/pagemap.h>
+ #include "volume.h"
++#include "vnode.h"
+ #include "cell.h"
++#include "cache.h"
+ #include "cmservice.h"
+ #include "fsclient.h"
+ #include "vlclient.h"
+@@ -24,6 +26,20 @@
+ const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry);
++static void afs_volume_cache_update(void *source, void *entry);
++
++struct cachefs_index_def afs_volume_cache_index_def = {
++      .name           = "volume",
++      .data_size      = sizeof(struct afs_cache_vhash),
++      .keys[0]        = { CACHEFS_INDEX_KEYS_BIN, 1 },
++      .keys[1]        = { CACHEFS_INDEX_KEYS_BIN, 1 },
++      .match          = afs_volume_cache_match,
++      .update         = afs_volume_cache_update,
++};
++#endif
++
+ /*****************************************************************************/
+ /*
+  * lookup a volume by name
+@@ -43,19 +59,19 @@
+  * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W if not available
+  * - Rule 3: If parent volume is R/W, then only mount R/W volume unless explicitly told otherwise
+  */
+-int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
++int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
++                    afs_volume_t **_volume)
+ {
+-      afs_vlocation_t *vlocation = NULL;
++      struct afs_vlocation *vlocation = NULL;
++      struct afs_volume *volume = NULL;
+       afs_voltype_t type;
+-      afs_volume_t *volume = NULL;
+-      afs_cell_t *cell = NULL;
+-      char *cellname, *volname, *suffix;
++      const char *cellname, *volname, *suffix;
+       char srvtmask;
+-      int force, ret, loop;
++      int force, ret, loop, cellnamesz, volnamesz;
+-      _enter(",%s,",name);
++      _enter("%s,,%d,", name, rwpath);
+-      if (!name || (name[0]!='%' && name[0]!='#') || !name[1]) {
++      if (!name || (name[0] != '%' && name[0] != '#') || !name[1]) {
+               printk("kAFS: unparsable volume name\n");
+               return -EINVAL;
+       }
+@@ -64,24 +80,22 @@
+       force = 0;
+       type = AFSVL_ROVOL;
+-      if (rwparent || name[0]=='%') {
++      if (rwpath || name[0] == '%') {
+               type = AFSVL_RWVOL;
+               force = 1;
+       }
+-      suffix = strrchr(name,'.');
++      suffix = strrchr(name, '.');
+       if (suffix) {
+-              if (strcmp(suffix,".readonly")==0) {
++              if (strcmp(suffix, ".readonly") == 0) {
+                       type = AFSVL_ROVOL;
+                       force = 1;
+               }
+-              else if (strcmp(suffix,".backup")==0) {
++              else if (strcmp(suffix, ".backup") == 0) {
+                       type = AFSVL_BACKVOL;
+                       force = 1;
+               }
+-              else if (suffix[1]==0) {
+-                      *suffix = 0;
+-                      suffix = NULL;
++              else if (suffix[1] == 0) {
+               }
+               else {
+                       suffix = NULL;
+@@ -90,38 +104,45 @@
+       /* split the cell and volume names */
+       name++;
+-      volname = strchr(name,':');
++      volname = strchr(name, ':');
+       if (volname) {
+-              *volname++ = 0;
+               cellname = name;
++              cellnamesz = volname - name;
+       }
+       else {
+               volname = name;
+               cellname = NULL;
++              cellnamesz = 0;
+       }
+-      _debug("CELL:%s VOLUME:%s SUFFIX:%s TYPE:%d%s",
+-             cellname,volname,suffix?:"-",type,force?" FORCE":"");
++      volnamesz = suffix ? suffix - volname : strlen(volname);
+-      /* lookup the cell record */
+-      ret = afs_cell_lookup(cellname,&cell);
+-      if (ret<0)
+-              printk("kAFS: unable to lookup cell '%s'\n",cellname?:"");
++      _debug("CELL:%*.*s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s",
++             cellnamesz, cellnamesz, cellname ?: "", cell,
++             volnamesz, volnamesz, volname, suffix ?: "-",
++             type,
++             force ? " FORCE" : "");
+-      if (cellname) volname[-1] = ':';
+-      if (ret<0)
+-              goto error;
++      /* lookup the cell record */
++      if (cellname || !cell) {
++              ret = afs_cell_lookup(cellname, cellnamesz, &cell);
++              if (ret<0) {
++                      printk("kAFS: unable to lookup cell '%s'\n", cellname ?: "");
++                      goto error;
++              }
++      }
++      else {
++              afs_get_cell(cell);
++      }
+       /* lookup the volume location record */
+-      if (suffix) *suffix = 0;
+-      ret = afs_vlocation_lookup(cell,volname,&vlocation);
+-      if (suffix) *suffix = '.';
+-      if (ret<0)
++      ret = afs_vlocation_lookup(cell, volname, volnamesz, &vlocation);
++      if (ret < 0)
+               goto error;
+       /* make the final decision on the type we want */
+       ret = -ENOMEDIUM;
+-      if (force && !(vlocation->vldb.vidmask & (1<<type)))
++      if (force && !(vlocation->vldb.vidmask & (1 << type)))
+               goto error;
+       srvtmask = 0;
+@@ -129,13 +150,13 @@
+               srvtmask |= vlocation->vldb.srvtmask[loop];
+       if (force) {
+-              if (!(srvtmask & (1 <<type)))
++              if (!(srvtmask & (1 << type)))
+                       goto error;
+       }
+-      else if (srvtmask & AFSC_VOL_STM_RO) {
++      else if (srvtmask & AFS_VOL_VTM_RO) {
+               type = AFSVL_ROVOL;
+       }
+-      else if (srvtmask & AFSC_VOL_STM_RW) {
++      else if (srvtmask & AFS_VOL_VTM_RW) {
+               type = AFSVL_RWVOL;
+       }
+       else {
+@@ -156,16 +177,16 @@
+       _debug("creating new volume record");
+       ret = -ENOMEM;
+-      volume = kmalloc(sizeof(afs_volume_t),GFP_KERNEL);
++      volume = kmalloc(sizeof(afs_volume_t), GFP_KERNEL);
+       if (!volume)
+               goto error_up;
+-      memset(volume,0,sizeof(afs_volume_t));
+-      atomic_set(&volume->usage,1);
+-      volume->type = type;
+-      volume->type_force = force;
+-      volume->cell = cell;
+-      volume->vid = vlocation->vldb.vid[type];
++      memset(volume, 0, sizeof(afs_volume_t));
++      atomic_set(&volume->usage, 1);
++      volume->type            = type;
++      volume->type_force      = force;
++      volume->cell            = cell;
++      volume->vid             = vlocation->vldb.vid[type];
+       init_rwsem(&volume->server_sem);
+@@ -183,15 +204,20 @@
+       }
+       /* attach the cache and volume location */
+-#if 0
+-      afs_get_cache(cache);           volume->cache = cache;
++#ifdef AFS_CACHING_SUPPORT
++      cachefs_acquire_cookie(vlocation->cache,
++                             &afs_vnode_cache_index_def,
++                             volume,
++                             &volume->cache);
+ #endif
+-      afs_get_vlocation(vlocation);   volume->vlocation = vlocation;
++
++      afs_get_vlocation(vlocation);
++      volume->vlocation = vlocation;
+       vlocation->vols[type] = volume;
+  success:
+-      _debug("kAFS selected %s volume %08x",afs_voltypes[volume->type],volume->vid);
++      _debug("kAFS selected %s volume %08x", afs_voltypes[volume->type], volume->vid);
+       *_volume = volume;
+       ret = 0;
+@@ -199,18 +225,17 @@
+  error_up:
+       up_write(&cell->vl_sem);
+  error:
+-      if (vlocation)  afs_put_vlocation(vlocation);
+-      if (cell)       afs_put_cell(cell);
++      afs_put_vlocation(vlocation);
++      afs_put_cell(cell);
+-      _leave(" = %d (%p)",ret,volume);
++      _leave(" = %d (%p)", ret, volume);
+       return ret;
+  error_discard:
+       up_write(&cell->vl_sem);
+       for (loop=volume->nservers-1; loop>=0; loop--)
+-              if (volume->servers[loop])
+-                      afs_put_server(volume->servers[loop]);
++              afs_put_server(volume->servers[loop]);
+       kfree(volume);
+       goto error;
+@@ -225,6 +250,9 @@
+       afs_vlocation_t *vlocation;
+       int loop;
++      if (!volume)
++              return;
++
+       _enter("%p",volume);
+       vlocation = volume->vlocation;
+@@ -246,16 +274,14 @@
+       up_write(&vlocation->cell->vl_sem);
+-      afs_put_vlocation(vlocation);
+-
+       /* finish cleaning up the volume */
+-#if 0
+-      if (volume->cache)      afs_put_cache(volume->cache);
++#ifdef AFS_CACHING_SUPPORT
++      cachefs_relinquish_cookie(volume->cache,0);
+ #endif
++      afs_put_vlocation(vlocation);
+       for (loop=volume->nservers-1; loop>=0; loop--)
+-              if (volume->servers[loop])
+-                      afs_put_server(volume->servers[loop]);
++              afs_put_server(volume->servers[loop]);
+       kfree(volume);
+@@ -428,3 +454,42 @@
+       return 0;
+ } /* end afs_volume_release_fileserver() */
++
++/*****************************************************************************/
++/*
++ * match a volume hash record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry)
++{
++      const struct afs_cache_vhash *vhash = entry;
++      struct afs_volume *volume = target;
++
++      _enter("{%u},{%u}", volume->type, vhash->vtype);
++
++      if (volume->type == vhash->vtype) {
++              _leave(" = SUCCESS");
++              return CACHEFS_MATCH_SUCCESS;
++      }
++
++      _leave(" = FAILED");
++      return CACHEFS_MATCH_FAILED;
++} /* end afs_volume_cache_match() */
++#endif
++
++/*****************************************************************************/
++/*
++ * update a volume hash record stored in the cache
++ */
++#ifdef AFS_CACHING_SUPPORT
++static void afs_volume_cache_update(void *source, void *entry)
++{
++      struct afs_cache_vhash *vhash = entry;
++      struct afs_volume *volume = source;
++
++      _enter("");
++
++      vhash->vtype = volume->type;
++
++} /* end afs_volume_cache_update() */
++#endif
+Index: linux-2.6.0-test5/fs/afs/volume.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/afs/volume.h     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/afs/volume.h  2003-09-27 11:38:36.048048248 +0800
+@@ -16,7 +16,7 @@
+ #include "fsclient.h"
+ #include "kafstimod.h"
+ #include "kafsasyncd.h"
+-#include "cache-layout.h"
++#include "cache.h"
+ #define __packed __attribute__((packed))
+@@ -30,21 +30,60 @@
+ /*****************************************************************************/
+ /*
++ * entry in the cached volume location catalogue
++ */
++struct afs_cache_vlocation
++{
++      uint8_t                 name[64];       /* volume name (lowercase, padded with NULs) */
++      uint8_t                 nservers;       /* number of entries used in servers[] */
++      uint8_t                 vidmask;        /* voltype mask for vid[] */
++      uint8_t                 srvtmask[8];    /* voltype masks for servers[] */
++#define AFS_VOL_VTM_RW        0x01 /* R/W version of the volume is available (on this server) */
++#define AFS_VOL_VTM_RO        0x02 /* R/O version of the volume is available (on this server) */
++#define AFS_VOL_VTM_BAK       0x04 /* backup version of the volume is available (on this server) */
++
++      afs_volid_t             vid[3];         /* volume IDs for R/W, R/O and Bak volumes */
++      struct in_addr          servers[8];     /* fileserver addresses */
++      time_t                  rtime;          /* last retrieval time */
++};
++
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_vlocation_cache_index_def;
++#endif
++
++/*****************************************************************************/
++/*
++ * volume -> vnode hash table entry
++ */
++struct afs_cache_vhash
++{
++      afs_voltype_t           vtype;          /* which volume variation */
++      uint8_t                 hash_bucket;    /* which hash bucket this represents */
++} __attribute__((packed));
++
++#ifdef AFS_CACHING_SUPPORT
++extern struct cachefs_index_def afs_volume_cache_index_def;
++#endif
++
++/*****************************************************************************/
++/*
+  * AFS volume location record
+  */
+ struct afs_vlocation
+ {
+       atomic_t                usage;
+       struct list_head        link;           /* link in cell volume location list */
+-      afs_timer_t             timeout;        /* decaching timer */
+-      afs_cell_t              *cell;          /* cell to which volume belongs */
+-      struct list_head        caches;         /* backing caches */
+-      afsc_vldb_record_t      vldb;           /* volume information DB record */
++      struct afs_timer        timeout;        /* decaching timer */
++      struct afs_cell         *cell;          /* cell to which volume belongs */
++#ifdef AFS_CACHING_SUPPORT
++      struct cachefs_cookie   *cache;         /* caching cookie */
++#endif
++      struct afs_cache_vlocation vldb;        /* volume information DB record */
+       struct afs_volume       *vols[3];       /* volume access record pointer (index by type) */
+       rwlock_t                lock;           /* access lock */
+       unsigned long           read_jif;       /* time at which last read from vlserver */
+-      afs_timer_t             upd_timer;      /* update timer */
+-      afs_async_op_t          upd_op;         /* update operation */
++      struct afs_timer        upd_timer;      /* update timer */
++      struct afs_async_op     upd_op;         /* update operation */
+       afs_vlocation_upd_t     upd_state;      /* update state */
+       unsigned short          upd_first_svix; /* first server index during update */
+       unsigned short          upd_curr_svix;  /* current server index during update */
+@@ -53,13 +92,16 @@
+       unsigned short          valid;          /* T if valid */
+ };
+-extern int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation);
++extern int afs_vlocation_lookup(struct afs_cell *cell,
++                              const char *name,
++                              unsigned namesz,
++                              struct afs_vlocation **_vlocation);
+ #define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)
+-extern void __afs_put_vlocation(afs_vlocation_t *vlocation);
+-extern void afs_put_vlocation(afs_vlocation_t *vlocation);
+-extern void afs_vlocation_do_timeout(afs_vlocation_t *vlocation);
++extern void __afs_put_vlocation(struct afs_vlocation *vlocation);
++extern void afs_put_vlocation(struct afs_vlocation *vlocation);
++extern void afs_vlocation_do_timeout(struct afs_vlocation *vlocation);
+ /*****************************************************************************/
+ /*
+@@ -68,25 +110,34 @@
+ struct afs_volume
+ {
+       atomic_t                usage;
+-      afs_cell_t              *cell;          /* cell to which belongs (unrefd ptr) */
+-      afs_vlocation_t         *vlocation;     /* volume location */
++      struct afs_cell         *cell;          /* cell to which belongs (unrefd ptr) */
++      struct afs_vlocation    *vlocation;     /* volume location */
++#ifdef AFS_CACHING_SUPPORT
++      struct cachefs_cookie   *cache;         /* caching cookie */
++#endif
+       afs_volid_t             vid;            /* volume ID */
+       afs_voltype_t __packed  type;           /* type of volume */
+       char                    type_force;     /* force volume type (suppress R/O -> R/W) */
+       unsigned short          nservers;       /* number of server slots filled */
+       unsigned short          rjservers;      /* number of servers discarded due to -ENOMEDIUM */
+-      afs_server_t            *servers[8];    /* servers on which volume resides (ordered) */
++      struct afs_server       *servers[8];    /* servers on which volume resides (ordered) */
+       struct rw_semaphore     server_sem;     /* lock for accessing current server */
+ };
+-extern int afs_volume_lookup(const char *name, int ro, afs_volume_t **_volume);
++extern int afs_volume_lookup(const char *name,
++                           struct afs_cell *cell,
++                           int rwpath,
++                           struct afs_volume **_volume);
+ #define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
+-extern void afs_put_volume(afs_volume_t *volume);
++extern void afs_put_volume(struct afs_volume *volume);
+-extern int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server);
++extern int afs_volume_pick_fileserver(struct afs_volume *volume,
++                                    struct afs_server **_server);
+-extern int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, int result);
++extern int afs_volume_release_fileserver(struct afs_volume *volume,
++                                       struct afs_server *server,
++                                       int result);
+ #endif /* _LINUX_AFS_VOLUME_H */
+Index: linux-2.6.0-test5/fs/aio.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/aio.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/aio.c 2003-09-27 11:38:36.057046880 +0800
+@@ -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   *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 @@
+               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));
+@@ -282,6 +289,7 @@
+               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);
+@@ -342,6 +350,11 @@
+               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
+@@ -396,6 +409,7 @@
+       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.
+@@ -495,7 +509,7 @@
+               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;
+@@ -537,65 +551,302 @@
+       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)) {
+@@ -604,12 +855,10 @@
+               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);
+       }
+ }
+@@ -662,6 +911,9 @@
+        */
+       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;
+@@ -690,6 +942,11 @@
+       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);
+@@ -804,6 +1061,7 @@
+       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!
+@@ -853,7 +1111,6 @@
+               add_wait_queue_exclusive(&ctx->wait, &wait);
+               do {
+                       set_task_state(tsk, TASK_INTERRUPTIBLE);
+-
+                       ret = aio_read_evt(ctx, &ent);
+                       if (ret)
+                               break;
+@@ -863,6 +1120,7 @@
+                       if (to.timed_out)       /* Only check after read evt */
+                               break;
+                       schedule();
++                      event_loop++;
+                       if (signal_pending(tsk)) {
+                               ret = -EINTR;
+                               break;
+@@ -890,6 +1148,9 @@
+       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;
+ }
+@@ -919,6 +1180,11 @@
+       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 */
+ }
+@@ -981,13 +1247,191 @@
+       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 ||
+@@ -1028,51 +1472,31 @@
+       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:
+Index: linux-2.6.0-test5/fs/autofs4/autofs_i.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs4/autofs_i.h       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs4/autofs_i.h    2003-09-27 11:38:36.060046424 +0800
+@@ -113,7 +113,7 @@
+    filesystem without "magic".) */
+ static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
+-      return sbi->catatonic || current->pgrp == sbi->oz_pgrp;
++      return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+ }
+ /* Does a dentry have some pending activity? */
+Index: linux-2.6.0-test5/fs/autofs4/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs4/inode.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs4/inode.c       2003-09-27 11:38:36.062046120 +0800
+@@ -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,69 +95,76 @@
+       .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 = current->pgrp;
++      *pgrp = process_group(current);
+       *minproto = AUTOFS_MIN_PROTO_VERSION;
+       *maxproto = AUTOFS_MAX_PROTO_VERSION;
+       *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);
+ }
+@@ -192,7 +200,7 @@
+       sbi->magic = AUTOFS_SBI_MAGIC;
+       sbi->catatonic = 0;
+       sbi->exp_timeout = 0;
+-      sbi->oz_pgrp = current->pgrp;
++      sbi->oz_pgrp = process_group(current);
+       sbi->sb = s;
+       sbi->version = 0;
+       sbi->queues = NULL;
+Index: linux-2.6.0-test5/fs/autofs4/root.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs4/root.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs4/root.c        2003-09-27 11:38:36.067045360 +0800
+@@ -255,7 +255,7 @@
+       lock_kernel();
+       oz_mode = autofs4_oz_mode(sbi);
+       DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
+-               current->pid, current->pgrp, sbi->catatonic, oz_mode));
++               current->pid, process_group(current), sbi->catatonic, oz_mode));
+       /*
+        * Mark the dentry incomplete, but add it. This is needed so
+@@ -518,7 +518,7 @@
+       struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb);
+       DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",
+-               cmd,arg,sbi,current->pgrp));
++               cmd,arg,sbi,process_group(current)));
+       if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
+            _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
+Index: linux-2.6.0-test5/fs/autofs/autofs_i.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs/autofs_i.h        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs/autofs_i.h     2003-09-27 11:38:36.069045056 +0800
+@@ -123,7 +123,7 @@
+    filesystem without "magic".) */
+ static inline int autofs_oz_mode(struct autofs_sb_info *sbi) {
+-      return sbi->catatonic || current->pgrp == sbi->oz_pgrp;
++      return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+ }
+ /* Hash operations */
+Index: linux-2.6.0-test5/fs/autofs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs/inode.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs/inode.c        2003-09-27 11:38:36.071044752 +0800
+@@ -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,67 +46,75 @@
+       .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 = current->pgrp;
++      *pgrp = process_group(current);
+       *minproto = *maxproto = AUTOFS_PROTO_VERSION;
+       *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);
+ }
+@@ -129,7 +138,7 @@
+       sbi->magic = AUTOFS_SBI_MAGIC;
+       sbi->catatonic = 0;
+       sbi->exp_timeout = 0;
+-      sbi->oz_pgrp = current->pgrp;
++      sbi->oz_pgrp = process_group(current);
+       autofs_initialize_hash(&sbi->dirhash);
+       sbi->queues = NULL;
+       memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
+Index: linux-2.6.0-test5/fs/autofs/root.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/autofs/root.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/autofs/root.c 2003-09-27 11:38:36.076043992 +0800
+@@ -213,7 +213,7 @@
+       oz_mode = autofs_oz_mode(sbi);
+       DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
+-               current->pid, current->pgrp, sbi->catatonic, oz_mode));
++               current->pid, process_group(current), sbi->catatonic, oz_mode));
+       /*
+        * Mark the dentry incomplete, but add it. This is needed so
+@@ -527,7 +527,7 @@
+ {
+       struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
+-      DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,current->pgrp));
++      DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
+       if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
+            _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
+Index: linux-2.6.0-test5/fs/befs/linuxvfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/befs/linuxvfs.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/befs/linuxvfs.c       2003-09-27 11:38:36.082043080 +0800
+@@ -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"
+@@ -667,12 +668,26 @@
+       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];
+       /* Initialize options */
+       opts->uid = 0;
+@@ -683,64 +698,60 @@
+       opts->debug = 0;
+       if (!options)
+-              return ret;
++              return 1;
+-      while ((this_char = strsep(&options, ",")) != NULL) {
+-
+-              if ((value = strchr(this_char, '=')) != NULL)
+-                      *value++ = 0;
+-
+-              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:
++                      {
++                              int uid = match_int(&args[0]);
++                              if (uid < 0) {
++                                      printk(KERN_ERR "BeFS: Invalid uid %d, "
++                                                      "using default\n", uid);
++                                      break;
+                               }
++                              opts->uid = uid;
++                              opts->use_uid = 1;
++                              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;
++                      case Opt_gid:
++                      {
++                              int gid = match_int(&args[0]);
++                              if (gid < 0) {
++                                      printk(KERN_ERR "BeFS: Invalid gid %d, "
++                                                      "using default\n", gid);
++                                      break;
+                               }
++                              opts->gid = gid;
++                              opts->use_gid = 1;
++                              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;
++                      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;
+                               }
++                              break;
+                       }
+-              } else if (!strcmp(this_char, "debug")) {
+-                      opts->debug = 1;
++                      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
+Index: linux-2.6.0-test5/fs/bfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/bfs/inode.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/bfs/inode.c   2003-09-27 11:38:36.086042472 +0800
+@@ -194,13 +194,15 @@
+ static int bfs_statfs(struct super_block *s, struct kstatfs *buf)
+ {
+       struct bfs_sb_info *info = BFS_SB(s);
++      u64 id = huge_encode_dev(s->s_bdev->bd_dev);
+       buf->f_type = BFS_MAGIC;
+       buf->f_bsize = s->s_blocksize;
+       buf->f_blocks = info->si_blocks;
+       buf->f_bfree = buf->f_bavail = info->si_freeb;
+       buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO;
+       buf->f_ffree = info->si_freei;
+-      buf->f_fsid.val[0] = s->s_dev;
++      buf->f_fsid.val[0] = (u32)id;
++      buf->f_fsid.val[1] = (u32)(id >> 32);
+       buf->f_namelen = BFS_NAMELEN;
+       return 0;
+ }
+Index: linux-2.6.0-test5/fs/binfmt_elf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/binfmt_elf.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/binfmt_elf.c  2003-09-27 11:38:36.096040952 +0800
+@@ -1023,6 +1023,7 @@
+       elf->e_ident[EI_CLASS] = ELF_CLASS;
+       elf->e_ident[EI_DATA] = ELF_DATA;
+       elf->e_ident[EI_VERSION] = EV_CURRENT;
++      elf->e_ident[EI_OSABI] = ELF_OSABI;
+       memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+       elf->e_type = ET_CORE;
+@@ -1076,7 +1077,7 @@
+       prstatus->pr_sighold = p->blocked.sig[0];
+       prstatus->pr_pid = p->pid;
+       prstatus->pr_ppid = p->parent->pid;
+-      prstatus->pr_pgrp = p->pgrp;
++      prstatus->pr_pgrp = process_group(p);
+       prstatus->pr_sid = p->session;
+       jiffies_to_timeval(p->utime, &prstatus->pr_utime);
+       jiffies_to_timeval(p->stime, &prstatus->pr_stime);
+@@ -1104,7 +1105,7 @@
+       psinfo->pr_pid = p->pid;
+       psinfo->pr_ppid = p->parent->pid;
+-      psinfo->pr_pgrp = p->pgrp;
++      psinfo->pr_pgrp = process_group(p);
+       psinfo->pr_sid = p->session;
+       i = p->state ? ffz(~p->state) + 1 : 0;
+Index: linux-2.6.0-test5/fs/bio.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/bio.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/bio.c 2003-09-27 11:38:36.101040192 +0800
+@@ -532,6 +532,12 @@
+  * check that the pages are still dirty.   If so, fine.  If not, redirty them
+  * in process context.
+  *
++ * We special-case compound pages here: normally this means reads into hugetlb
++ * pages.  The logic in here doesn't really work right for compound pages
++ * because the VM does not uniformly chase down the head page in all cases.
++ * But dirtiness of compound pages is pretty meaningless anyway: the VM doesn't
++ * handle them at all.  So we skip compound pages here at an early stage.
++ *
+  * Note that this code is very hard to test under normal circumstances because
+  * direct-io pins the pages with get_user_pages().  This makes
+  * is_page_cache_freeable return false, and the VM will not clean the pages.
+@@ -553,8 +559,21 @@
+       for (i = 0; i < bio->bi_vcnt; i++) {
+               struct page *page = bvec[i].bv_page;
++              if (page && !PageCompound(page))
++                      set_page_dirty_lock(page);
++      }
++}
++
++static void bio_release_pages(struct bio *bio)
++{
++      struct bio_vec *bvec = bio->bi_io_vec;
++      int i;
++
++      for (i = 0; i < bio->bi_vcnt; i++) {
++              struct page *page = bvec[i].bv_page;
++
+               if (page)
+-                      set_page_dirty_lock(bvec[i].bv_page);
++                      put_page(page);
+       }
+ }
+@@ -592,6 +611,7 @@
+               struct bio *next = bio->bi_private;
+               bio_set_pages_dirty(bio);
++              bio_release_pages(bio);
+               bio_put(bio);
+               bio = next;
+       }
+@@ -606,7 +626,7 @@
+       for (i = 0; i < bio->bi_vcnt; i++) {
+               struct page *page = bvec[i].bv_page;
+-              if (PageDirty(page)) {
++              if (PageDirty(page) || PageCompound(page)) {
+                       page_cache_release(page);
+                       bvec[i].bv_page = NULL;
+               } else {
+Index: linux-2.6.0-test5/fs/buffer.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/buffer.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/buffer.c      2003-09-27 11:38:36.122037000 +0800
+@@ -116,27 +116,50 @@
+ }
+ /*
+- * 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
+@@ -351,26 +374,18 @@
+       return ret;
+ }
+-asmlinkage long sys_fdatasync(unsigned int fd)
++int do_fdatasync(struct file * file)
+ {
+-      struct file * file;
+       struct dentry * dentry;
+       struct inode * inode;
+       int ret, err;
+-      ret = -EBADF;
+-      file = fget(fd);
+-      if (!file)
+-              goto out;
++      if (unlikely(!file->f_op || !file->f_op->fsync))
++              return -EINVAL;
+       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);
+       current->flags |= PF_SYNCWRITE;
+       ret = filemap_fdatawrite(inode->i_mapping);
+       err = file->f_op->fsync(file, dentry, 1);
+@@ -380,11 +395,24 @@
+       if (!ret)
+               ret = err;
+       current->flags &= ~PF_SYNCWRITE;
+-      up(&inode->i_sem);
++      return ret;
++}
+-out_putf:
+-      fput(file);
+-out:
++asmlinkage long sys_fdatasync(unsigned int fd)
++{
++      struct file * file;
++      struct inode * inode;
++      int ret;
++
++      ret = -EBADF;
++      file = fget(fd);
++      if (file) {
++              inode = file->f_dentry->d_inode;
++              down(&inode->i_sem);
++              ret = do_fdatasync(file);
++              up(&inode->i_sem);
++              fput(file);
++      }
+       return ret;
+ }
+@@ -1296,9 +1324,12 @@
+       __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 +1339,8 @@
+               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 +1348,11 @@
+       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 +1540,18 @@
+ }
+ 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 +2029,9 @@
+       /*
+        * 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;
+       }
+Index: linux-2.6.0-test5/fs/char_dev.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/char_dev.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/char_dev.c    2003-09-27 11:38:36.126036392 +0800
+@@ -445,3 +445,18 @@
+       kset_register(&kset_dynamic);
+       cdev_map = kobj_map_init(base_probe, &cdev_subsys);
+ }
++
++
++/* Let modules do char dev stuff */
++EXPORT_SYMBOL(register_chrdev_region);
++EXPORT_SYMBOL(unregister_chrdev_region);
++EXPORT_SYMBOL(alloc_chrdev_region);
++EXPORT_SYMBOL(cdev_init);
++EXPORT_SYMBOL(cdev_alloc);
++EXPORT_SYMBOL(cdev_get);
++EXPORT_SYMBOL(cdev_put);
++EXPORT_SYMBOL(cdev_del);
++EXPORT_SYMBOL(cdev_add);
++EXPORT_SYMBOL(cdev_unmap);
++EXPORT_SYMBOL(register_chrdev);
++EXPORT_SYMBOL(unregister_chrdev);
+Index: linux-2.6.0-test5/fs/coda/cache.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/cache.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/cache.c  2003-09-27 11:38:36.128036088 +0800
+@@ -23,13 +23,16 @@
+ #include <linux/coda_fs_i.h>
+ #include <linux/coda_cache.h>
++static atomic_t permission_epoch = ATOMIC_INIT(0);
++
+ /* replace or extend an acl cache hit */
+ void coda_cache_enter(struct inode *inode, int mask)
+ {
+       struct coda_inode_info *cii = ITOC(inode);
+-        if ( !coda_cred_ok(&cii->c_cached_cred) ) {
+-                coda_load_creds(&cii->c_cached_cred);
++      cii->c_cached_epoch = atomic_read(&permission_epoch);
++      if (cii->c_uid != current->fsuid) {
++                cii->c_uid = current->fsuid;
+                 cii->c_cached_perm = mask;
+         } else
+                 cii->c_cached_perm |= mask;
+@@ -42,22 +45,15 @@
+         cii->c_cached_perm = 0;
+ }
+-/* remove all acl caches for a principal (or all principals when cred == NULL)*/
+-void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred)
++/* remove all acl caches */
++void coda_cache_clear_all(struct super_block *sb)
+ {
+         struct coda_sb_info *sbi;
+-        struct coda_inode_info *cii;
+-        struct list_head *tmp;
+         sbi = coda_sbp(sb);
+         if (!sbi) BUG();
+-        list_for_each(tmp, &sbi->sbi_cihead)
+-        {
+-              cii = list_entry(tmp, struct coda_inode_info, c_cilist);
+-                if (!cred || coda_cred_eq(cred, &cii->c_cached_cred))
+-                        cii->c_cached_perm = 0;
+-      }
++      atomic_inc(&permission_epoch);
+ }
+@@ -67,8 +63,9 @@
+       struct coda_inode_info *cii = ITOC(inode);
+         int hit;
+       
+-        hit = ((mask & cii->c_cached_perm) == mask) &&
+-                coda_cred_ok(&cii->c_cached_cred);
++        hit = (mask & cii->c_cached_perm) == mask &&
++              cii->c_uid == current->fsuid &&
++              cii->c_cached_epoch == atomic_read(&permission_epoch);
+         return hit;
+ }
+Index: linux-2.6.0-test5/fs/coda/cnode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/cnode.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/cnode.c  2003-09-27 11:38:36.130035784 +0800
+@@ -11,18 +11,9 @@
+ #include <linux/coda_fs_i.h>
+ #include <linux/coda_psdev.h>
+-inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
++inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
+ {
+-      if (fid1->Vnode != fid2->Vnode)   return 0;
+-      if (fid1->Volume != fid2->Volume) return 0;
+-      if (fid1->Unique != fid2->Unique) return 0;
+-      return 1;
+-}
+-
+-inline int coda_isnullfid(ViceFid *fid)
+-{
+-      if (fid->Vnode || fid->Volume || fid->Unique) return 0;
+-      return 1;
++      return memcmp(fid1, fid2, sizeof(*fid1)) == 0;
+ }
+ static struct inode_operations coda_symlink_inode_operations = {
+@@ -47,18 +38,18 @@
+               inode->i_data.a_ops = &coda_symlink_aops;
+               inode->i_mapping = &inode->i_data;
+       } else
+-                init_special_inode(inode, inode->i_mode, attr->va_rdev);
++                init_special_inode(inode, inode->i_mode, huge_decode_dev(attr->va_rdev));
+ }
+ static int coda_test_inode(struct inode *inode, void *data)
+ {
+-      ViceFid *fid = (ViceFid *)data;
++      struct CodaFid *fid = (struct CodaFid *)data;
+       return coda_fideq(&(ITOC(inode)->c_fid), fid);
+ }
+ static int coda_set_inode(struct inode *inode, void *data)
+ {
+-      ViceFid *fid = (ViceFid *)data;
++      struct CodaFid *fid = (struct CodaFid *)data;
+       ITOC(inode)->c_fid = *fid;
+       return 0;
+ }
+@@ -68,12 +59,11 @@
+       return -1;
+ }
+-struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
++struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,
+                        struct coda_vattr * attr)
+ {
+       struct inode *inode;
+       struct coda_inode_info *cii;
+-      struct coda_sb_info *sbi = coda_sbp(sb);
+       unsigned long hash = coda_f2i(fid);
+       inode = iget5_locked(sb, hash, coda_test_inode, coda_set_inode, fid);
+@@ -86,7 +76,6 @@
+               /* we still need to set i_ino for things like stat(2) */
+               inode->i_ino = hash;
+               cii->c_mapcount = 0;
+-              list_add(&cii->c_cilist, &sbi->sbi_cihead);
+               unlock_new_inode(inode);
+       }
+@@ -101,7 +90,7 @@
+    - link the two up if this is needed
+    - fill in the attributes
+ */
+-int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
++int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_block *sb)
+ {
+         struct coda_vattr attr;
+         int error;
+@@ -122,8 +111,8 @@
+ }
+-void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid, 
+-                    struct ViceFid *newfid)
++void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid, 
++                    struct CodaFid *newfid)
+ {
+       struct coda_inode_info *cii;
+       unsigned long hash = coda_f2i(newfid);
+@@ -142,7 +131,7 @@
+ }
+ /* convert a fid to an inode. */
+-struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) 
++struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb) 
+ {
+       struct inode *inode;
+       unsigned long hash = coda_f2i(fid);
+Index: linux-2.6.0-test5/fs/coda/coda_linux.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/coda_linux.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/coda_linux.c     2003-09-27 11:38:36.133035328 +0800
+@@ -25,10 +25,14 @@
+ int coda_fake_statfs;
+ /* print a fid */
+-char * coda_f2s(ViceFid *f)
++char * coda_f2s(struct CodaFid *f)
+ {
+       static char s[60];
+-      sprintf(s, "(%-#lx.%-#lx.%-#lx)", f->Volume, f->Vnode, f->Unique);
++#ifdef CODA_FS_OLD_API
++      sprintf(s, "(%08x.%08x.%08x)", f->opaque[0], f->opaque[1], f->opaque[2]);
++#else
++      sprintf(s, "(%08x.%08x.%08x.%08x)", f->opaque[0], f->opaque[1], f->opaque[2], f->opaque[3]);
++#endif
+       return s;
+ }
+@@ -45,30 +49,6 @@
+     return ( i->i_sb->s_root->d_inode == i );
+ }
+-/* put the current process credentials in the cred */
+-void coda_load_creds(struct coda_cred *cred)
+-{
+-        cred->cr_uid = (vuid_t) current->uid;
+-        cred->cr_euid = (vuid_t) current->euid;
+-        cred->cr_suid = (vuid_t) current->suid;
+-        cred->cr_fsuid = (vuid_t) current->fsuid;
+-
+-        cred->cr_groupid = (vgid_t) current->gid;
+-        cred->cr_egid = (vgid_t) current->egid;
+-        cred->cr_sgid = (vgid_t) current->sgid;
+-        cred->cr_fsgid = (vgid_t) current->fsgid;
+-}
+-
+-int coda_cred_ok(struct coda_cred *cred)
+-{
+-      return(current->fsuid == cred->cr_fsuid);
+-}
+-
+-int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2)
+-{
+-      return (cred1->cr_fsuid == cred2->cr_fsuid);
+-}
+-
+ unsigned short coda_flags_to_cflags(unsigned short flags)
+ {
+       unsigned short coda_flags = 0;
+@@ -215,58 +195,3 @@
+       }
+ }
+-void print_vattr(struct coda_vattr *attr)
+-{
+-    char *typestr;
+-
+-    switch (attr->va_type) {
+-    case C_VNON:
+-      typestr = "C_VNON";
+-      break;
+-    case C_VREG:
+-      typestr = "C_VREG";
+-      break;
+-    case C_VDIR:
+-      typestr = "C_VDIR";
+-      break;
+-    case C_VBLK:
+-      typestr = "C_VBLK";
+-      break;
+-    case C_VCHR:
+-      typestr = "C_VCHR";
+-      break;
+-    case C_VLNK:
+-      typestr = "C_VLNK";
+-      break;
+-    case C_VSOCK:
+-      typestr = "C_VSCK";
+-      break;
+-    case C_VFIFO:
+-      typestr = "C_VFFO";
+-      break;
+-    case C_VBAD:
+-      typestr = "C_VBAD";
+-      break;
+-    default:
+-      typestr = "????";
+-      break;
+-    }
+-
+-
+-    printk("attr: type %s (%o)  mode %o uid %d gid %d rdev %d\n",
+-         typestr, (int)attr->va_type, (int)attr->va_mode, 
+-         (int)attr->va_uid, (int)attr->va_gid, (int)attr->va_rdev);
+-    
+-    printk("      fileid %d nlink %d size %d blocksize %d bytes %d\n",
+-            (int)attr->va_fileid, (int)attr->va_nlink, 
+-            (int)attr->va_size,
+-            (int)attr->va_blocksize,(int)attr->va_bytes);
+-    printk("      gen %ld flags %ld\n",
+-            attr->va_gen, attr->va_flags);
+-    printk("      atime sec %d nsec %d\n",
+-            (int)attr->va_atime.tv_sec, (int)attr->va_atime.tv_nsec);
+-    printk("      mtime sec %d nsec %d\n",
+-            (int)attr->va_mtime.tv_sec, (int)attr->va_mtime.tv_nsec);
+-    printk("      ctime sec %d nsec %d\n",
+-            (int)attr->va_ctime.tv_sec, (int)attr->va_ctime.tv_nsec);
+-}
+Index: linux-2.6.0-test5/fs/coda/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/dir.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/dir.c    2003-09-27 11:38:36.138034568 +0800
+@@ -93,7 +93,7 @@
+ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
+ {
+       struct inode *res_inode = NULL;
+-      struct ViceFid resfid = {0,0,0};
++      struct CodaFid resfid = { { 0, } };
+       int dropme = 0; /* to indicate entry should not be cached */
+       int type = 0;
+       int error = 0;
+@@ -196,7 +196,7 @@
+       const char *name=de->d_name.name;
+       int length=de->d_name.len;
+       struct inode *inode;
+-      struct ViceFid newfid;
++      struct CodaFid newfid;
+       struct coda_vattr attrs;
+       lock_kernel();
+@@ -236,7 +236,7 @@
+       const char *name=de->d_name.name;
+       int length=de->d_name.len;
+       struct inode *inode;
+-      struct ViceFid newfid;
++      struct CodaFid newfid;
+       struct coda_vattr attrs;
+       if ( coda_hasmknod == 0 )
+@@ -283,7 +283,7 @@
+       const char *name = de->d_name.name;
+       int len = de->d_name.len;
+       int error;
+-      struct ViceFid newfid;
++      struct CodaFid newfid;
+       lock_kernel();
+       coda_vfs_stat.mkdir++;
+@@ -588,8 +588,7 @@
+                       break;
+               }
+               /* validate whether the directory file actually makes sense */
+-              if (vdir->d_reclen < vdir_size + vdir->d_namlen ||
+-                  vdir->d_namlen > CODA_MAXNAMLEN) {
++              if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
+                       printk("coda_venus_readdir: Invalid dir: %ld\n",
+                              filp->f_dentry->d_inode->i_ino);
+                       ret = -EBADF;
+Index: linux-2.6.0-test5/fs/coda/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/file.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/file.c   2003-09-27 11:38:36.141034112 +0800
+@@ -136,7 +136,6 @@
+       cfi->cfi_magic = CODA_MAGIC;
+       cfi->cfi_mapcount = 0;
+       cfi->cfi_container = host_file;
+-      coda_load_creds(&cfi->cfi_cred);
+       BUG_ON(coda_file->private_data != NULL);
+       coda_file->private_data = cfi;
+@@ -176,7 +175,7 @@
+       coda_inode = coda_file->f_dentry->d_inode;
+       err = venus_store(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
+-                        &cfi->cfi_cred);
++                        coda_file->f_uid);
+       if (err == -EOPNOTSUPP) {
+               use_coda_close = 1;
+@@ -214,7 +213,7 @@
+       if (use_coda_close)
+               err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
+-                                coda_flags, &cfi->cfi_cred);
++                                coda_flags, coda_file->f_uid);
+       host_inode = cfi->cfi_container->f_dentry->d_inode;
+       cii = ITOC(coda_inode);
+Index: linux-2.6.0-test5/fs/coda/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/inode.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/inode.c  2003-09-27 11:38:36.143033808 +0800
+@@ -44,10 +44,9 @@
+       ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, SLAB_KERNEL);
+       if (!ei)
+               return NULL;
+-      memset(&ei->c_fid, 0, sizeof(struct ViceFid));
++      memset(&ei->c_fid, 0, sizeof(struct CodaFid));
+       ei->c_flags = 0;
+-      INIT_LIST_HEAD(&ei->c_cilist);
+-      memset(&ei->c_cached_cred, 0, sizeof(struct coda_cred));
++      ei->c_uid = 0;
+       ei->c_cached_perm = 0;
+       return &ei->vfs_inode;
+ }
+@@ -139,7 +138,7 @@
+         struct inode *root = 0; 
+       struct coda_sb_info *sbi = NULL;
+       struct venus_comm *vc = NULL;
+-        ViceFid fid;
++      struct CodaFid fid;
+         int error;
+       int idx;
+@@ -169,9 +168,7 @@
+       vc->vc_sb = sb;
+-      sbi->sbi_sb = sb;
+       sbi->sbi_vcomm = vc;
+-      INIT_LIST_HEAD(&sbi->sbi_cihead);
+         sb->s_fs_info = sbi;
+         sb->s_blocksize = 1024;       /* XXXXX  what do we put here?? */
+@@ -218,7 +215,6 @@
+       sbi = coda_sbp(sb);
+       sbi->sbi_vcomm->vc_sb = NULL;
+-        list_del_init(&sbi->sbi_cihead);
+       printk("Coda: Bye bye.\n");
+       kfree(sbi);
+@@ -226,9 +222,6 @@
+ static void coda_clear_inode(struct inode *inode)
+ {
+-      struct coda_inode_info *cii = ITOC(inode);
+-
+-      list_del_init(&cii->c_cilist);
+       coda_cache_clear_inode(inode);
+ }
+Index: linux-2.6.0-test5/fs/coda/psdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/psdev.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/psdev.c  2003-09-27 11:38:36.147033200 +0800
+@@ -61,7 +61,6 @@
+ struct venus_comm coda_comms[MAX_CODADEVS];
+-kmem_cache_t *cii_cache, *cred_cache, *upc_cache;
+ /*
+  * Device operations
+@@ -126,13 +125,13 @@
+               }
+               if  ( nbytes < sizeof(struct coda_out_hdr) ) {
+-                      printk("coda_downcall opc %ld uniq %ld, not enough!\n",
++                      printk("coda_downcall opc %d uniq %d, not enough!\n",
+                              hdr.opcode, hdr.unique);
+                       count = nbytes;
+                       goto out;
+               }
+               if ( nbytes > size ) {
+-                      printk("Coda: downcall opc %ld, uniq %ld, too much!",
++                      printk("Coda: downcall opc %d, uniq %d, too much!",
+                              hdr.opcode, hdr.unique);
+                       nbytes = size;
+               }
+@@ -171,7 +170,7 @@
+       unlock_kernel();
+       if (!req) {
+-              printk("psdev_write: msg (%ld, %ld) not found\n", 
++              printk("psdev_write: msg (%d, %d) not found\n", 
+                       hdr.opcode, hdr.unique);
+               retval = -ESRCH;
+               goto out;
+@@ -179,7 +178,7 @@
+         /* move data into response buffer. */
+       if (req->uc_outSize < nbytes) {
+-                printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %ld, uniq: %ld.\n",
++                printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %d, uniq: %d.\n",
+                      req->uc_outSize, (long)nbytes, hdr.opcode, hdr.unique);
+               nbytes = req->uc_outSize; /* don't have more space! */
+       }
+@@ -325,10 +324,7 @@
+       }
+         
+         /* Wakeup clients so they can return. */
+-      lh = vcp->vc_pending.next;
+-      next = lh;
+-      while ( (lh = next) != &vcp->vc_pending) {
+-              next = lh->next;
++      list_for_each_safe(lh, next, &vcp->vc_pending) {
+               req = list_entry(lh, struct upc_req, uc_chain);
+               /* Async requests need to be freed here */
+               if (req->uc_flags & REQ_ASYNC) {
+@@ -340,9 +336,7 @@
+               wake_up(&req->uc_sleep);
+         }
+         
+-      lh = &vcp->vc_processing;
+-      while ( (lh = lh->next) != &vcp->vc_processing) {
+-              req = list_entry(lh, struct upc_req, uc_chain);
++      list_for_each_entry(req, &vcp->vc_processing, uc_chain) {
+               req->uc_flags |= REQ_ABORT;
+               wake_up(&req->uc_sleep);
+         }
+@@ -390,7 +384,13 @@
+ {
+       int status;
+       int i;
+-      printk(KERN_INFO "Coda Kernel/Venus communications, v5.3.15, coda@cs.cmu.edu\n");
++      printk(KERN_INFO "Coda Kernel/Venus communications, "
++#ifdef CODA_FS_OLD_API
++             "v5.3.20"
++#else
++             "v6.0.0"
++#endif
++             ", coda@cs.cmu.edu\n");
+       status = coda_init_inodecache();
+       if (status)
+Index: linux-2.6.0-test5/fs/coda/upcall.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/coda/upcall.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/coda/upcall.c 2003-09-27 11:38:36.155031984 +0800
+@@ -54,9 +54,13 @@
+         inp->ih.opcode = opcode;
+       inp->ih.pid = current->pid;
+-      inp->ih.pgid = current->pgrp;
+-      coda_load_creds(&(inp->ih.cred));
+-
++      inp->ih.pgid = process_group(current);
++#ifdef CODA_FS_OLD_API
++      memset(&inp->ih.cred, 0, sizeof(struct coda_cred));
++      inp->ih.cred.cr_fsuid = current->fsuid;
++#else
++      inp->ih.uid = current->fsuid;
++#endif
+       return (void*)inp;
+ }
+@@ -74,7 +78,7 @@
+ /* the upcalls */
+-int venus_rootfid(struct super_block *sb, ViceFid *fidp)
++int venus_rootfid(struct super_block *sb, struct CodaFid *fidp)
+ {
+         union inputArgs *inp;
+         union outputArgs *outp;
+@@ -88,14 +92,14 @@
+       if (error) {
+               printk("coda_get_rootfid: error %d\n", error);
+       } else {
+-              *fidp = (ViceFid) outp->coda_root.VFid;
++              *fidp = outp->coda_root.VFid;
+       }
+       CODA_FREE(inp, insize);
+       return error;
+ }
+-int venus_getattr(struct super_block *sb, struct ViceFid *fid, 
++int venus_getattr(struct super_block *sb, struct CodaFid *fid, 
+                    struct coda_vattr *attr) 
+ {
+         union inputArgs *inp;
+@@ -114,7 +118,7 @@
+         return error;
+ }
+-int venus_setattr(struct super_block *sb, struct ViceFid *fid, 
++int venus_setattr(struct super_block *sb, struct CodaFid *fid, 
+                 struct coda_vattr *vattr)
+ {
+         union inputArgs *inp;
+@@ -133,9 +137,9 @@
+         return error;
+ }
+-int venus_lookup(struct super_block *sb, struct ViceFid *fid, 
++int venus_lookup(struct super_block *sb, struct CodaFid *fid, 
+                   const char *name, int length, int * type, 
+-                  struct ViceFid *resfid)
++                  struct CodaFid *resfid)
+ {
+         union inputArgs *inp;
+         union outputArgs *outp;
+@@ -162,17 +166,25 @@
+       return error;
+ }
+-int venus_store(struct super_block *sb, struct ViceFid *fid, int flags,
+-                struct coda_cred *cred)
++int venus_store(struct super_block *sb, struct CodaFid *fid, int flags,
++                vuid_t uid)
+ {
+         union inputArgs *inp;
+         union outputArgs *outp;
+         int insize, outsize, error;
++#ifdef CODA_FS_OLD_API
++      struct coda_cred cred = { 0, };
++      cred.cr_fsuid = uid;
++#endif
+       
+       insize = SIZE(store);
+       UPARG(CODA_STORE);
+       
+-      memcpy(&(inp->ih.cred), cred, sizeof(*cred));
++#ifdef CODA_FS_OLD_API
++      memcpy(&(inp->ih.cred), &cred, sizeof(cred));
++#else
++      inp->ih.uid = uid;
++#endif
+       
+         inp->coda_store.VFid = *fid;
+         inp->coda_store.flags = flags;
+@@ -183,7 +195,7 @@
+         return error;
+ }
+-int venus_release(struct super_block *sb, struct ViceFid *fid, int flags)
++int venus_release(struct super_block *sb, struct CodaFid *fid, int flags)
+ {
+         union inputArgs *inp;
+         union outputArgs *outp;
+@@ -201,17 +213,25 @@
+       return error;
+ }
+-int venus_close(struct super_block *sb, struct ViceFid *fid, int flags,
+-                struct coda_cred *cred)
++int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
++                vuid_t uid)
+ {
+       union inputArgs *inp;
+       union outputArgs *outp;
+       int insize, outsize, error;
++#ifdef CODA_FS_OLD_API
++      struct coda_cred cred = { 0, };
++      cred.cr_fsuid = uid;
++#endif
+       
+       insize = SIZE(release);
+       UPARG(CODA_CLOSE);
+       
+-      memcpy(&(inp->ih.cred), cred, sizeof(*cred));
++#ifdef CODA_FS_OLD_API
++      memcpy(&(inp->ih.cred), &cred, sizeof(cred));
++#else
++      inp->ih.uid = uid;
++#endif
+       
+         inp->coda_close.VFid = *fid;
+         inp->coda_close.flags = flags;
+@@ -222,7 +242,7 @@
+         return error;
+ }
+-int venus_open(struct super_block *sb, struct ViceFid *fid,
++int venus_open(struct super_block *sb, struct CodaFid *fid,
+                 int flags, struct file **fh)
+ {
+         union inputArgs *inp;
+@@ -243,9 +263,9 @@
+       return error;
+ }     
+-int venus_mkdir(struct super_block *sb, struct ViceFid *dirfid, 
++int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid, 
+                  const char *name, int length, 
+-                 struct ViceFid *newfid, struct coda_vattr *attrs)
++                 struct CodaFid *newfid, struct coda_vattr *attrs)
+ {
+         union inputArgs *inp;
+         union outputArgs *outp;
+@@ -273,8 +293,8 @@
+ }
+-int venus_rename(struct super_block *sb, struct ViceFid *old_fid, 
+-               struct ViceFid *new_fid, size_t old_length, 
++int venus_rename(struct super_block *sb, struct CodaFid *old_fid, 
++               struct CodaFid *new_fid, size_t old_length, 
+                size_t new_length, const char *old_name, 
+                const char *new_name)
+ {
+@@ -310,9 +330,9 @@
+       return error;
+ }
+-int venus_create(struct super_block *sb, struct ViceFid *dirfid, 
++int venus_create(struct super_block *sb, struct CodaFid *dirfid, 
+                const char *name, int length, int excl, int mode, dev_t rdev,
+-               struct ViceFid *newfid, struct coda_vattr *attrs) 
++               struct CodaFid *newfid, struct coda_vattr *attrs) 
+ {
+         union inputArgs *inp;
+         union outputArgs *outp;
+@@ -325,7 +345,7 @@
+         inp->coda_create.VFid = *dirfid;
+         inp->coda_create.attr.va_mode = mode;
+-        inp->coda_create.attr.va_rdev = rdev;
++        inp->coda_create.attr.va_rdev = huge_encode_dev(rdev);
+       inp->coda_create.excl = excl;
+         inp->coda_create.mode = mode;
+         inp->coda_create.name = offset;
+@@ -343,7 +363,7 @@
+       return error;        
+ }
+-int venus_rmdir(struct super_block *sb, struct ViceFid *dirfid, 
++int venus_rmdir(struct super_block *sb, struct CodaFid *dirfid, 
+                   const char *name, int length)
+ {
+         union inputArgs *inp;
+@@ -366,7 +386,7 @@
+       return error;
+ }
+-int venus_remove(struct super_block *sb, struct ViceFid *dirfid, 
++int venus_remove(struct super_block *sb, struct CodaFid *dirfid, 
+                   const char *name, int length)
+ {
+         union inputArgs *inp;
+@@ -388,7 +408,7 @@
+       return error;
+ }
+-int venus_readlink(struct super_block *sb, struct ViceFid *fid, 
++int venus_readlink(struct super_block *sb, struct CodaFid *fid, 
+                     char *buffer, int *length)
+ { 
+         union inputArgs *inp;
+@@ -421,8 +441,8 @@
+-int venus_link(struct super_block *sb, struct ViceFid *fid, 
+-                struct ViceFid *dirfid, const char *name, int len )
++int venus_link(struct super_block *sb, struct CodaFid *fid, 
++                struct CodaFid *dirfid, const char *name, int len )
+ {
+         union inputArgs *inp;
+         union outputArgs *outp;
+@@ -447,7 +467,7 @@
+         return error;
+ }
+-int venus_symlink(struct super_block *sb, struct ViceFid *fid,
++int venus_symlink(struct super_block *sb, struct CodaFid *fid,
+                    const char *name, int len,
+                    const char *symname, int symlen)
+ {
+@@ -482,7 +502,7 @@
+         return error;
+ }
+-int venus_fsync(struct super_block *sb, struct ViceFid *fid)
++int venus_fsync(struct super_block *sb, struct CodaFid *fid)
+ {
+         union inputArgs *inp;
+         union outputArgs *outp; 
+@@ -499,7 +519,7 @@
+       return error;
+ }
+-int venus_access(struct super_block *sb, struct ViceFid *fid, int mask)
++int venus_access(struct super_block *sb, struct CodaFid *fid, int mask)
+ {
+         union inputArgs *inp;
+         union outputArgs *outp; 
+@@ -518,7 +538,7 @@
+ }
+-int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
++int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
+                unsigned int cmd, struct PioctlData *data)
+ {
+         union inputArgs *inp;
+@@ -808,7 +828,7 @@
+  * The last  allows Venus to replace local fids with global ones
+  * during reintegration.
+  *
+- * CODA_REPLACE -- replace one ViceFid with another throughout the name cache */
++ * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
+ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
+ {
+@@ -819,25 +839,20 @@
+         switch (opcode) {
+         case CODA_FLUSH : {
+-                 coda_cache_clear_all(sb, NULL);
++                 coda_cache_clear_all(sb);
+                  shrink_dcache_sb(sb);
+                  coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
+                  return(0);
+         }
+         case CODA_PURGEUSER : {
+-                 struct coda_cred *cred = &out->coda_purgeuser.cred;
+-                 if ( !cred ) {
+-                         printk("PURGEUSER: null cred!\n");
+-                         return 0;
+-                 }
+-                 coda_cache_clear_all(sb, cred);
++                 coda_cache_clear_all(sb);
+                  return(0);
+         }
+         case CODA_ZAPDIR : {
+                 struct inode *inode;
+-                ViceFid *fid = &out->coda_zapdir.CodaFid;
++                struct CodaFid *fid = &out->coda_zapdir.CodaFid;
+                 inode = coda_fid_to_inode(fid, sb);
+                 if (inode) {
+@@ -851,7 +866,7 @@
+         case CODA_ZAPFILE : {
+                 struct inode *inode;
+-                struct ViceFid *fid = &out->coda_zapfile.CodaFid;
++                struct CodaFid *fid = &out->coda_zapfile.CodaFid;
+                 inode = coda_fid_to_inode(fid, sb);
+                 if ( inode ) {
+                         coda_flag_inode(inode, C_VATTR);
+@@ -862,7 +877,7 @@
+         case CODA_PURGEFID : {
+                 struct inode *inode;
+-                ViceFid *fid = &out->coda_purgefid.CodaFid;
++                struct CodaFid *fid = &out->coda_purgefid.CodaFid;
+                 inode = coda_fid_to_inode(fid, sb);
+                 if ( inode ) { 
+                       coda_flag_inode_children(inode, C_PURGE);
+@@ -878,8 +893,8 @@
+         case CODA_REPLACE : {
+                 struct inode *inode;
+-                ViceFid *oldfid = &out->coda_replace.OldFid;
+-                ViceFid *newfid = &out->coda_replace.NewFid;
++                struct CodaFid *oldfid = &out->coda_replace.OldFid;
++                struct CodaFid *newfid = &out->coda_replace.NewFid;
+                 inode = coda_fid_to_inode(oldfid, sb);
+                 if ( inode ) { 
+                         coda_replace_fid(inode, oldfid, newfid);
+Index: linux-2.6.0-test5/fs/dcache.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/dcache.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/dcache.c      2003-09-27 11:38:36.166030312 +0800
+@@ -82,7 +82,7 @@
+ /*
+  * Release the dentry's inode, using the filesystem
+  * d_iput() operation if defined.
+- * Called with dcache_lock held, drops it.
++ * Called with dcache_lock and per dentry lock held, drops both.
+  */
+ static inline void dentry_iput(struct dentry * dentry)
+ {
+@@ -90,13 +90,16 @@
+       if (inode) {
+               dentry->d_inode = NULL;
+               list_del_init(&dentry->d_alias);
++              spin_unlock(&dentry->d_lock);
+               spin_unlock(&dcache_lock);
+               if (dentry->d_op && dentry->d_op->d_iput)
+                       dentry->d_op->d_iput(dentry, inode);
+               else
+                       iput(inode);
+-      } else
++      } else {
++              spin_unlock(&dentry->d_lock);
+               spin_unlock(&dcache_lock);
++      }
+ }
+ /* 
+@@ -177,9 +180,8 @@
+                       dentry_stat.nr_unused--;
+               }
+               list_del(&dentry->d_child);
+-              spin_unlock(&dentry->d_lock);
+               dentry_stat.nr_dentry--;        /* For d_free, below */
+-              /* drops the lock, at that point nobody can reach this dentry */
++              /*drops the locks, at that point nobody can reach this dentry */
+               dentry_iput(dentry);
+               parent = dentry->d_parent;
+               d_free(dentry);
+@@ -341,7 +343,6 @@
+       __d_drop(dentry);
+       list_del(&dentry->d_child);
+-      spin_unlock(&dentry->d_lock);
+       dentry_stat.nr_dentry--;        /* For d_free, below */
+       dentry_iput(dentry);
+       parent = dentry->d_parent;
+@@ -1116,7 +1117,6 @@
+       spin_lock(&dcache_lock);
+       spin_lock(&dentry->d_lock);
+       if (atomic_read(&dentry->d_count) == 1) {
+-              spin_unlock(&dentry->d_lock);
+               dentry_iput(dentry);
+               return;
+       }
+Index: linux-2.6.0-test5/fs/devfs/base.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/devfs/base.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/devfs/base.c  2003-09-27 11:38:36.189026816 +0800
+@@ -1334,7 +1334,7 @@
+     struct task_struct *p = current;
+     if (p == fs_info->devfsd_task) return (TRUE);
+-    if (p->pgrp == fs_info->devfsd_pgrp) return (TRUE);
++    if (process_group(p) == fs_info->devfsd_pgrp) return (TRUE);
+     read_lock(&tasklist_lock);
+     for ( ; p != &init_task; p = p->real_parent)
+     {
+@@ -2744,8 +2744,8 @@
+           }
+           fs_info->devfsd_task = current;
+           spin_unlock (&lock);
+-          fs_info->devfsd_pgrp = (current->pgrp == current->pid) ?
+-              current->pgrp : 0;
++          fs_info->devfsd_pgrp = (process_group(current) == current->pid) ?
++              process_group(current) : 0;
+           fs_info->devfsd_file = file;
+           fs_info->devfsd_info = kmalloc (sizeof *fs_info->devfsd_info,
+                                           GFP_KERNEL);
+Index: linux-2.6.0-test5/fs/direct-io.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/direct-io.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/direct-io.c   2003-09-27 11:38:36.197025600 +0800
+@@ -58,6 +58,7 @@
+       struct bio *bio;                /* bio under assembly */
+       struct inode *inode;
+       int rw;
++      int is_reg_file;
+       unsigned blkbits;               /* doesn't change */
+       unsigned blkfactor;             /* When we're using an alignment which
+                                          is finer than the filesystem's soft
+@@ -205,6 +206,8 @@
+ {
+       if (dio->end_io)
+               dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private);
++      if (dio->is_reg_file)
++              up_read(&dio->inode->i_alloc_sem);
+ }
+ /*
+@@ -448,6 +451,7 @@
+       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 +469,17 @@
+               if (dio_count & blkmask)        
+                       fs_count++;
++              if (dio->is_reg_file) {
++                      if (dio->block_in_file >= (i_size_read(dio->inode) >>
++                                                      dio->blkbits))
++                              beyond_eof = 1;
++              }
++              /*
++               * AKPM: huh?  We call get_blocks(create==0) for hole
++               * overwrites?
++               */
+               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 +786,10 @@
+                       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 */
+@@ -841,18 +858,15 @@
+ 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,6 +877,10 @@
+       dio->start_zero_done = 0;
+       dio->block_in_file = offset >> blkbits;
+       dio->blocks_available = 0;
++      if (S_ISREG(inode->i_mode))
++              dio->is_reg_file = 1;
++      else
++              dio->is_reg_file = 0;
+       dio->cur_page = NULL;
+@@ -949,6 +967,8 @@
+        * OK, all BIOs are submitted, so we can decrement bio_count to truly
+        * reflect the number of to-be-processed BIOs.
+        */
++      if (dio->is_reg_file)
++              up(&dio->inode->i_sem);         /* Don't need i_sem any more */
+       if (dio->is_async) {
+               if (ret == 0)
+                       ret = dio->result;      /* Bytes written */
+@@ -993,6 +1013,7 @@
+       unsigned bdev_blkbits = 0;
+       unsigned blocksize_mask = (1 << blkbits) - 1;
+       ssize_t retval = -EINVAL;
++      struct dio *dio;
+       if (bdev)
+               bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
+@@ -1018,8 +1039,16 @@
+               }
+       }
+-      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;
++
++      return direct_io_worker(rw, iocb, inode, iov, offset,
++                              nr_segs, blkbits, get_blocks, end_io, dio);
+ out:
++      up(&inode->i_sem);
++      if (S_ISREG(inode->i_mode))
++              up_read(&inode->i_alloc_sem);
+       return retval;
+ }
+Index: linux-2.6.0-test5/fs/efs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/efs/inode.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/efs/inode.c   2003-09-27 11:38:36.201024992 +0800
+@@ -47,9 +47,11 @@
+       return;
+ }
+-void efs_read_inode(struct inode *inode) {
++void efs_read_inode(struct inode *inode)
++{
+       int i, inode_index;
+       dev_t device;
++      u32 rdev;
+       struct buffer_head *bh;
+       struct efs_sb_info    *sb = SUPER_INFO(inode->i_sb);
+       struct efs_inode_info *in = INODE_INFO(inode);
+@@ -104,20 +106,15 @@
+               inode->i_blocks = ((inode->i_size - 1) >> EFS_BLOCKSIZE_BITS) + 1;
+       }
+-      /*
+-       * BUG: irix dev_t is 32-bits. linux dev_t is only 16-bits.
+-       *
+-       * apparently linux will change to 32-bit dev_t sometime during
+-       * linux 2.3.
+-       *
+-       * as is, this code maps devices that can't be represented in
+-       * 16-bits (ie major > 255 or minor > 255) to major = minor = 255.
+-       *
+-       * during 2.3 when 32-bit dev_t become available, we should test
+-       * to see whether odev contains 65535. if this is the case then we
+-       * should then do device = be32_to_cpu(efs_inode->di_u.di_dev.ndev).
+-       */
+-      device = old_decode_dev(be16_to_cpu(efs_inode->di_u.di_dev.odev));
++      rdev = be16_to_cpu(efs_inode->di_u.di_dev.odev);
++      if (rdev == 0xffff) {
++              rdev = be32_to_cpu(efs_inode->di_u.di_dev.ndev);
++              if (sysv_major(rdev) > 0xfff)
++                      device = 0;
++              else
++                      device = MKDEV(sysv_major(rdev), sysv_minor(rdev));
++      } else
++              device = old_decode_dev(rdev);
+       /* get the number of extents for this object */
+       in->numextents = be16_to_cpu(efs_inode->di_numextents);
+Index: linux-2.6.0-test5/fs/eventpoll.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/eventpoll.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/eventpoll.c   2003-09-27 11:38:36.213023168 +0800
+@@ -288,8 +288,10 @@
+ static int ep_alloc_pages(char **pages, int numpages);
+ static int ep_free_pages(char **pages, int numpages);
+ static int ep_file_init(struct file *file, unsigned int hashbits);
+-static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file, int fd);
+-static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index);
++static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file,
++                                int fd);
++static struct list_head *ep_hash_entry(struct eventpoll *ep,
++                                     unsigned int index);
+ static int ep_init(struct eventpoll *ep, unsigned int hashbits);
+ static void ep_free(struct eventpoll *ep);
+ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
+@@ -299,7 +301,8 @@
+                                poll_table *pt);
+ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
+                    struct file *tfile, int fd);
+-static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event);
++static int ep_modify(struct eventpoll *ep, struct epitem *epi,
++                   struct epoll_event *event);
+ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
+ static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
+ static int ep_remove(struct eventpoll *ep, struct epitem *epi);
+@@ -309,11 +312,12 @@
+ static int ep_collect_ready_items(struct eventpoll *ep,
+                                 struct list_head *txlist, int maxevents);
+ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
+-                        struct epoll_event *events);
++                        struct epoll_event __user *events);
+ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist);
+ static int ep_events_transfer(struct eventpoll *ep,
+-                            struct epoll_event *events, int maxevents);
+-static int ep_poll(struct eventpoll *ep, struct epoll_event *events,
++                            struct epoll_event __user *events,
++                            int maxevents);
++static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
+                  int maxevents, long timeout);
+ static int eventpollfs_delete_dentry(struct dentry *dentry);
+ static struct inode *ep_eventpoll_inode(void);
+@@ -532,11 +536,13 @@
+ /*
+- * The following function implement the controller interface for the eventpoll
+- * file that enable the insertion/removal/change of file descriptors inside
+- * the interest set. It rapresents the kernel part of the user space epoll_ctl(2).
++ * The following function implements the controller interface for
++ * the eventpoll file that enables the insertion/removal/change of
++ * file descriptors inside the interest set.  It represents
++ * the kernel part of the user space epoll_ctl(2).
+  */
+-asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
++asmlinkage long
++sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
+ {
+       int error;
+       struct file *file, *tfile;
+@@ -637,8 +643,8 @@
+  * Implement the event wait interface for the eventpoll file. It is the kernel
+  * part of the user space epoll_wait(2).
+  */
+-asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+-                             int timeout)
++asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
++                             int maxevents, int timeout)
+ {
+       int error;
+       struct file *file;
+@@ -662,7 +668,7 @@
+               goto eexit_1;
+       /*
+-       * We have to check that the file structure underneath the file descriptor
++       * We have to check that the file structure underneath the fd
+        * the user passed to us _is_ an eventpoll file.
+        */
+       error = -EINVAL;
+@@ -1409,7 +1415,7 @@
+  * because of the way poll() is traditionally implemented in Linux.
+  */
+ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
+-                        struct epoll_event *events)
++                        struct epoll_event __user *events)
+ {
+       int eventcnt = 0, eventbuf = 0;
+       unsigned int revents;
+@@ -1521,7 +1527,8 @@
+ /*
+  * Perform the transfer of events to user space.
+  */
+-static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents)
++static int ep_events_transfer(struct eventpoll *ep,
++                            struct epoll_event __user *events, int maxevents)
+ {
+       int eventcnt = 0;
+       struct list_head txlist;
+@@ -1549,8 +1556,8 @@
+ }
+-static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
+-                 long timeout)
++static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
++                 int maxevents, long timeout)
+ {
+       int res, eavail;
+       unsigned long flags;
+Index: linux-2.6.0-test5/fs/exec.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/exec.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/exec.c        2003-09-27 11:38:36.221021952 +0800
+@@ -56,7 +56,7 @@
+ int core_uses_pid;
+ char core_pattern[65] = "core";
+-/* The maximal length of core_pattern is also specified in sysctl.c */ 
++/* The maximal length of core_pattern is also specified in sysctl.c */
+ static struct linux_binfmt *formats;
+ static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
+@@ -190,7 +190,7 @@
+  * memory to free pages in kernel mem. These are in a format ready
+  * to be put directly into the top of new user memory.
+  */
+-int copy_strings(int argc,char __user * __user * argv, struct linux_binprm *bprm) 
++int copy_strings(int argc,char __user * __user * argv, struct linux_binprm *bprm)
+ {
+       struct page *kmapped_page = NULL;
+       char *kaddr = NULL;
+@@ -213,7 +213,7 @@
+               }
+               bprm->p -= len;
+-              /* XXX: add architecture specific overflow check here. */ 
++              /* XXX: add architecture specific overflow check here. */
+               pos = bprm->p;
+               while (len > 0) {
+@@ -275,10 +275,10 @@
+ {
+       int r;
+       mm_segment_t oldfs = get_fs();
+-      set_fs(KERNEL_DS); 
++      set_fs(KERNEL_DS);
+       r = copy_strings(argc, (char __user * __user *)argv, bprm);
+       set_fs(oldfs);
+-      return r; 
++      return r;
+ }
+ #ifdef CONFIG_MMU
+@@ -374,7 +374,13 @@
+       /* Adjust bprm->p to point to the end of the strings. */
+       bprm->p = PAGE_SIZE * i - offset;
+-      stack_base = STACK_TOP - current->rlim[RLIMIT_STACK].rlim_max;
++
++      /* Limit stack size to 1GB */
++      stack_base = current->rlim[RLIMIT_STACK].rlim_max;
++      if (stack_base > (1 << 30))
++              stack_base = 1 << 30;
++      stack_base = PAGE_ALIGN(STACK_TOP - stack_base);
++
+       mm->arg_start = stack_base;
+       arg_size = i << PAGE_SHIFT;
+@@ -421,7 +427,7 @@
+               mpnt->vm_private_data = (void *) 0;
+               insert_vm_struct(mm, mpnt);
+               mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+-      } 
++      }
+       for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
+               struct page *page = bprm->page[i];
+@@ -803,7 +809,7 @@
+       /* An exec changes our domain. We are no longer part of the thread
+          group */
+-         
++
+       current->self_exec_id++;
+                       
+       flush_signal_handlers(current, 0);
+@@ -887,7 +893,7 @@
+  *
+  */
+-void compute_creds(struct linux_binprm *bprm) 
++void compute_creds(struct linux_binprm *bprm)
+ {
+       task_lock(current);
+       if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
+@@ -1052,7 +1058,7 @@
+               return retval;
+       bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
+-      memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
++      memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
+       bprm.file = file;
+       bprm.filename = filename;
+@@ -1083,21 +1089,21 @@
+               goto out;
+       retval = prepare_binprm(&bprm);
+-      if (retval < 0) 
+-              goto out; 
++      if (retval < 0)
++              goto out;
+       retval = copy_strings_kernel(1, &bprm.filename, &bprm);
+-      if (retval < 0) 
+-              goto out; 
++      if (retval < 0)
++              goto out;
+       bprm.exec = bprm.p;
+       retval = copy_strings(bprm.envc, envp, &bprm);
+-      if (retval < 0) 
+-              goto out; 
++      if (retval < 0)
++              goto out;
+       retval = copy_strings(bprm.argc, argv, &bprm);
+-      if (retval < 0) 
+-              goto out; 
++      if (retval < 0)
++              goto out;
+       retval = search_binary_handler(&bprm,regs);
+       if (retval >= 0) {
+Index: linux-2.6.0-test5/fs/ext2/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/inode.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/inode.c  2003-09-27 11:38:36.232020280 +0800
+@@ -257,11 +257,12 @@
+  *    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 @@
+       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 @@
+       *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 @@
+  * 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 @@
+               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 @@
+       }
+       /* 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 @@
+       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 @@
+ 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
+@@ -1126,8 +1152,12 @@
+               }
+       } else {
+               inode->i_op = &ext2_special_inode_operations;
+-              init_special_inode(inode, inode->i_mode,
++              if (raw_inode->i_block[0])
++                      init_special_inode(inode, inode->i_mode,
+                          old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
++              else 
++                      init_special_inode(inode, inode->i_mode,
++                         new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
+       }
+       brelse (bh);
+       ext2_set_inode_flags(inode);
+@@ -1215,9 +1245,17 @@
+       }
+       
+       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(old_encode_dev(inode->i_rdev));
+-      else for (n = 0; n < EXT2_N_BLOCKS; n++)
++      if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
++              if (old_valid_dev(inode->i_rdev)) {
++                      raw_inode->i_block[0] =
++                              cpu_to_le32(old_encode_dev(inode->i_rdev));
++                      raw_inode->i_block[1] = 0;
++              } else {
++                      raw_inode->i_block[0] = 0;
++                      raw_inode->i_block[1] =
++                              cpu_to_le32(new_encode_dev(inode->i_rdev));
++              }
++      } 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) {
+Index: linux-2.6.0-test5/fs/ext2/ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/ioctl.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/ioctl.c  2003-09-27 11:38:36.234019976 +0800
+@@ -10,6 +10,7 @@
+ #include "ext2.h"
+ #include <linux/time.h>
+ #include <linux/sched.h>
++#include <linux/mount.h>
+ #include <asm/current.h>
+ #include <asm/uaccess.h>
+@@ -29,7 +30,7 @@
+       case EXT2_IOC_SETFLAGS: {
+               unsigned int oldflags;
+-              if (IS_RDONLY(inode))
++              if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+                       return -EROFS;
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+@@ -68,7 +69,7 @@
+       case EXT2_IOC_SETVERSION:
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EPERM;
+-              if (IS_RDONLY(inode))
++              if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+                       return -EROFS;
+               if (get_user(inode->i_generation, (int *) arg))
+                       return -EFAULT; 
+Index: linux-2.6.0-test5/fs/ext2/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/namei.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/namei.c  2003-09-27 11:38:36.237019520 +0800
+@@ -142,7 +142,7 @@
+       struct inode * inode;
+       int err;
+-      if (!old_valid_dev(rdev))
++      if (!new_valid_dev(rdev))
+               return -EINVAL;
+       inode = ext2_new_inode (dir, mode);
+Index: linux-2.6.0-test5/fs/ext2/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/super.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/super.c  2003-09-27 11:38:36.246018152 +0800
+@@ -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 @@
+       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;
+ }
+Index: linux-2.6.0-test5/fs/ext2/symlink.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext2/symlink.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext2/symlink.c        2003-09-27 11:38:36.247018000 +0800
+@@ -20,7 +20,8 @@
+ #include "ext2.h"
+ #include "xattr.h"
+-static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
++static int
++ext2_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+       struct ext2_inode_info *ei = EXT2_I(dentry->d_inode);
+       return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data);
+Index: linux-2.6.0-test5/fs/ext3/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/inode.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/inode.c  2003-09-27 11:38:36.270014504 +0800
+@@ -2565,8 +2565,12 @@
+               }
+       } else {
+               inode->i_op = &ext3_special_inode_operations;
+-              init_special_inode(inode, inode->i_mode,
++              if (raw_inode->i_block[0])
++                      init_special_inode(inode, inode->i_mode,
+                          old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
++              else 
++                      init_special_inode(inode, inode->i_mode,
++                         new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
+       }
+       brelse (iloc.bh);
+       ext3_set_inode_flags(inode);
+@@ -2666,10 +2670,17 @@
+               }
+       }
+       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(old_encode_dev(inode->i_rdev));
+-      else for (block = 0; block < EXT3_N_BLOCKS; block++)
++      if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
++              if (old_valid_dev(inode->i_rdev)) {
++                      raw_inode->i_block[0] =
++                              cpu_to_le32(old_encode_dev(inode->i_rdev));
++                      raw_inode->i_block[1] = 0;
++              } else {
++                      raw_inode->i_block[0] = 0;
++                      raw_inode->i_block[1] =
++                              cpu_to_le32(new_encode_dev(inode->i_rdev));
++              }
++      } 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");
+Index: linux-2.6.0-test5/fs/ext3/ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/ioctl.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/ioctl.c  2003-09-27 11:38:36.271014352 +0800
+@@ -12,6 +12,7 @@
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
+ #include <linux/time.h>
++#include <linux/mount.h>
+ #include <asm/uaccess.h>
+@@ -34,7 +35,7 @@
+               unsigned int oldflags;
+               unsigned int jflag;
+-              if (IS_RDONLY(inode))
++              if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+                       return -EROFS;
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+@@ -110,7 +111,7 @@
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EPERM;
+-              if (IS_RDONLY(inode))
++              if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+                       return -EROFS;
+               if (get_user(generation, (int *) arg))
+                       return -EFAULT;
+Index: linux-2.6.0-test5/fs/ext3/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/namei.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/namei.c  2003-09-27 11:38:36.288011768 +0800
+@@ -1659,7 +1659,7 @@
+       struct inode *inode;
+       int err;
+-      if (!old_valid_dev(rdev))
++      if (!new_valid_dev(rdev))
+               return -EINVAL;
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+Index: linux-2.6.0-test5/fs/ext3/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ext3/super.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ext3/super.c  2003-09-27 11:38:36.305009184 +0800
+@@ -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>
+@@ -34,10 +35,6 @@
+ #include "xattr.h"
+ #include "acl.h"
+-#ifdef CONFIG_JBD_DEBUG
+-static int ext3_ro_after; /* Make fs read-only after this many jiffies */
+-#endif
+-
+ static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+                              int);
+@@ -50,64 +47,6 @@
+                                  struct ext3_super_block * es);
+ static int ext3_sync_fs(struct super_block *sb, int wait);
+-#ifdef CONFIG_JBD_DEBUG
+-int journal_no_write[2];
+-
+-/*
+- * Debug code for turning filesystems "read-only" after a specified
+- * amount of time.  This is for crash/recovery testing.
+- */
+-
+-static void make_rdonly(struct block_device *bdev, int *no_write)
+-{
+-      char b[BDEVNAME_SIZE];
+-
+-      if (bdev) {
+-              printk(KERN_WARNING "Turning device %s read-only\n", 
+-                     bdevname(bdev, b));
+-              *no_write = 0xdead0000 + bdev->bd_dev;
+-      }
+-}
+-
+-static void turn_fs_readonly(unsigned long arg)
+-{
+-      struct super_block *sb = (struct super_block *)arg;
+-
+-      make_rdonly(sb->s_bdev, &journal_no_write[0]);
+-      make_rdonly(EXT3_SB(sb)->s_journal->j_dev, &journal_no_write[1]);
+-      wake_up(&EXT3_SB(sb)->ro_wait_queue);
+-}
+-
+-static void setup_ro_after(struct super_block *sb)
+-{
+-      struct ext3_sb_info *sbi = EXT3_SB(sb);
+-      init_timer(&sbi->turn_ro_timer);
+-      if (ext3_ro_after) {
+-              printk(KERN_DEBUG "fs will go read-only in %d jiffies\n",
+-                     ext3_ro_after);
+-              init_waitqueue_head(&sbi->ro_wait_queue);
+-              journal_no_write[0] = 0;
+-              journal_no_write[1] = 0;
+-              sbi->turn_ro_timer.function = turn_fs_readonly;
+-              sbi->turn_ro_timer.data = (unsigned long)sb;
+-              sbi->turn_ro_timer.expires = jiffies + ext3_ro_after;
+-              ext3_ro_after = 0;
+-              add_timer(&sbi->turn_ro_timer);
+-      }
+-}
+-
+-static void clear_ro_after(struct super_block *sb)
+-{
+-      del_timer_sync(&EXT3_SB(sb)->turn_ro_timer);
+-      journal_no_write[0] = 0;
+-      journal_no_write[1] = 0;
+-      ext3_ro_after = 0;
+-}
+-#else
+-#define setup_ro_after(sb)    do {} while (0)
+-#define clear_ro_after(sb)    do {} while (0)
+-#endif
+-
+ /* 
+  * Wrappers for journal_start/end.
+  *
+@@ -481,7 +420,6 @@
+               invalidate_bdev(sbi->journal_bdev, 0);
+               ext3_blkdev_remove(sbi);
+       }
+-      clear_ro_after(sb);
+       sb->s_fs_info = NULL;
+       kfree(sbi);
+       return;
+@@ -589,36 +527,54 @@
+       .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)
+ {
+@@ -640,183 +596,180 @@
+       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);
+-#ifdef CONFIG_JBD_DEBUG
+-              else if (!strcmp (this_char, "ro-after")) {
+-                      unsigned long v;
+-                      if (want_numeric(value, "ro-after", &v))
+-                              return 0;
+-                      ext3_ro_after = v;
+-              }
++                      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
+-              /* 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")) {
++              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;
+ }
+@@ -892,7 +845,6 @@
+               ext3_check_inodes_bitmap (sb);
+       }
+ #endif
+-      setup_ro_after(sb);
+       return res;
+ }
+@@ -1092,9 +1044,6 @@
+       int i;
+       int needs_recovery;
+-#ifdef CONFIG_JBD_DEBUG
+-      ext3_ro_after = 0;
+-#endif
+       sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
+       if (!sbi)
+               return -ENOMEM;
+@@ -1103,7 +1052,6 @@
+       sbi->s_mount_opt = 0;
+       sbi->s_resuid = EXT3_DEF_RESUID;
+       sbi->s_resgid = EXT3_DEF_RESGID;
+-      setup_ro_after(sb);
+       blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
+       if (!blocksize) {
+@@ -1603,7 +1551,7 @@
+ {
+       journal_t *journal;
+       int journal_inum = le32_to_cpu(es->s_journal_inum);
+-      dev_t journal_dev = old_decode_dev(le32_to_cpu(es->s_journal_dev));
++      dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+       int err = 0;
+       int really_read_only;
+@@ -1868,8 +1816,6 @@
+       struct ext3_sb_info *sbi = EXT3_SB(sb);
+       unsigned long tmp;
+-      clear_ro_after(sb);
+-
+       /*
+        * Allow the "check" option to be passed as a remount option.
+        */
+@@ -1929,7 +1875,6 @@
+                               sb->s_flags &= ~MS_RDONLY;
+               }
+       }
+-      setup_ro_after(sb);
+       return 0;
+ }
+Index: linux-2.6.0-test5/fs/fat/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/fat/file.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/fat/file.c    2003-09-27 11:38:36.307008880 +0800
+@@ -11,8 +11,8 @@
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+-static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
+-                            loff_t *ppos);
++static ssize_t fat_file_write(struct file *filp, const char __user *buf,
++                            size_t count, loff_t *ppos);
+ struct file_operations fat_file_operations = {
+       .llseek         = generic_file_llseek,
+@@ -66,8 +66,8 @@
+       return 0;
+ }
+-static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
+-                            loff_t *ppos)
++static ssize_t fat_file_write(struct file *filp, const char __user *buf,
++                            size_t count, loff_t *ppos)
+ {
+       struct inode *inode = filp->f_dentry->d_inode;
+       int retval;
+Index: linux-2.6.0-test5/fs/fat/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/fat/inode.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/fat/inode.c   2003-09-27 11:38:36.317007360 +0800
+@@ -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 @@
+       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 @@
+       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 @@
+       *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)
+Index: linux-2.6.0-test5/fs/hfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hfs/super.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hfs/super.c   2003-09-27 11:38:36.322006600 +0800
+@@ -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 @@
+       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 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 @@
+       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;
+               }
+       }
+Index: linux-2.6.0-test5/fs/hpfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hpfs/inode.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hpfs/inode.c  2003-09-27 11:38:36.325006144 +0800
+@@ -159,7 +159,7 @@
+                               i->i_size = 0;
+                               i->i_blocks = 1;
+                               init_special_inode(i, mode,
+-                                      old_decode_dev(rdev));
++                                      new_decode_dev(rdev));
+                               return;
+                       }
+               }
+@@ -223,7 +223,7 @@
+                               hpfs_inode->i_ea_mode = 1;
+                       }
+               if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode)) {
+-                      ea = cpu_to_le32(old_encode_dev(i->i_rdev));
++                      ea = cpu_to_le32(new_encode_dev(i->i_rdev));
+                       hpfs_set_ea(i, fnode, "DEV", (char *)&ea, 4);
+               }
+       }
+Index: linux-2.6.0-test5/fs/hpfs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hpfs/namei.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hpfs/namei.c  2003-09-27 11:38:36.330005384 +0800
+@@ -194,7 +194,7 @@
+       int err;
+       if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
+       if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
+-      if (!old_valid_dev(rdev))
++      if (!new_valid_dev(rdev))
+               return -EINVAL;
+       lock_kernel();
+       if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail;
+Index: linux-2.6.0-test5/fs/hpfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hpfs/super.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hpfs/super.c  2003-09-27 11:38:36.336004472 +0800
+@@ -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 @@
+ /*
+  * 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 @@
+       /*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 @@
+                       *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;
+ }
+Index: linux-2.6.0-test5/fs/hugetlbfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/hugetlbfs/inode.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/hugetlbfs/inode.c     2003-09-27 11:38:36.342003560 +0800
+@@ -47,7 +47,6 @@
+ {
+       struct inode *inode = file->f_dentry->d_inode;
+       struct address_space *mapping = inode->i_mapping;
+-      struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
+       loff_t len, vma_len;
+       int ret;
+@@ -61,19 +60,8 @@
+               return -EINVAL;
+       vma_len = (loff_t)(vma->vm_end - vma->vm_start);
+-      if (sbinfo->free_blocks >= 0) { /* Check if there is any size limit. */
+-              spin_lock(&sbinfo->stat_lock);
+-              if ((vma_len >> HPAGE_SHIFT) <= sbinfo->free_blocks) {
+-                      sbinfo->free_blocks -= (vma_len >> HPAGE_SHIFT);
+-                      spin_unlock(&sbinfo->stat_lock);
+-              } else {
+-                      spin_unlock(&sbinfo->stat_lock);
+-                      return -ENOMEM;
+-              }
+-      }
+       down(&inode->i_sem);
+-
+       update_atime(inode);
+       vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
+       vma->vm_ops = &hugetlb_vm_ops;
+@@ -83,15 +71,6 @@
+               inode->i_size = len;
+       up(&inode->i_sem);
+-      /*
+-       * If the huge page allocation has failed then increment free_blocks.
+-       */
+-      if ((ret != 0) && (sbinfo->free_blocks >= 0)) {
+-              spin_lock(&sbinfo->stat_lock);
+-              sbinfo->free_blocks += (vma_len >> HPAGE_SHIFT);
+-              spin_unlock(&sbinfo->stat_lock);
+-      }
+-
+       return ret;
+ }
+@@ -178,7 +157,6 @@
+ void truncate_hugepages(struct address_space *mapping, loff_t lstart)
+ {
+-      struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
+       const pgoff_t start = lstart >> HPAGE_SHIFT;
+       struct pagevec pvec;
+       pgoff_t next;
+@@ -187,7 +165,7 @@
+       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;
+@@ -198,16 +176,9 @@
+                       struct page *page = pvec.pages[i];
+                       lock_page(page);
+-                      if (page->index > next)
+-                              next = page->index;
+-                      ++next;
+                       truncate_huge_page(page);
+                       unlock_page(page);
+-                      if (sbinfo->free_blocks >= 0) {
+-                              spin_lock(&sbinfo->stat_lock);
+-                              sbinfo->free_blocks++;
+-                              spin_unlock(&sbinfo->stat_lock);
+-                      }
++                      hugetlb_put_quota(mapping);
+               }
+               huge_pagevec_release(&pvec);
+       }
+@@ -712,6 +683,34 @@
+       return 0;
+ }
++int hugetlb_get_quota(struct address_space *mapping)
++{
++      int ret = 0;
++      struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
++
++      if (sbinfo->free_blocks > -1) {
++              spin_lock(&sbinfo->stat_lock);
++              if (sbinfo->free_blocks > 0)
++                      sbinfo->free_blocks--;
++              else
++                      ret = -ENOMEM;
++              spin_unlock(&sbinfo->stat_lock);
++      }
++
++      return ret;
++}
++
++void hugetlb_put_quota(struct address_space *mapping)
++{
++      struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
++
++      if (sbinfo->free_blocks > -1) {
++              spin_lock(&sbinfo->stat_lock);
++              sbinfo->free_blocks++;
++              spin_unlock(&sbinfo->stat_lock);
++      }
++}
++
+ static struct super_block *hugetlbfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
+ {
+Index: linux-2.6.0-test5/fs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/inode.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/inode.c       2003-09-27 11:38:36.351002192 +0800
+@@ -183,6 +183,7 @@
+       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);
+Index: linux-2.6.0-test5/fs/intermezzo/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/intermezzo/inode.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/intermezzo/inode.c    2003-09-27 11:38:36.353001888 +0800
+@@ -167,7 +167,6 @@
+ exit:
+         CDEBUG(D_MALLOC, "after umount: kmem %ld, vmem %ld\n",
+                presto_kmemory, presto_vmemory);
+-        MOD_DEC_USE_COUNT;
+         return ;
+ }
+Index: linux-2.6.0-test5/fs/isofs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/isofs/inode.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/isofs/inode.c 2003-09-27 11:38:36.364000216 +0800
+@@ -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 @@
+ }
+ #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 @@
+       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 @@
+       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_freebh:
+       brelse(bh);
+ out_freesbi:
++      if (opt.iocharset)
++              kfree(opt.iocharset);
+       kfree(sbi);
+       s->s_fs_info = NULL;
+       return -EINVAL;
+Index: linux-2.6.0-test5/fs/jbd/transaction.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jbd/transaction.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jbd/transaction.c     2003-09-27 11:38:36.380997632 +0800
+@@ -1932,9 +1932,6 @@
+       J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
+       assert_spin_locked(&transaction->t_journal->j_list_lock);
+-#ifdef __SMP__
+-      J_ASSERT (current->lock_depth >= 0);
+-#endif
+       J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
+       J_ASSERT_JH(jh, jh->b_transaction == transaction ||
+                               jh->b_transaction == 0);
+Index: linux-2.6.0-test5/fs/jffs2/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jffs2/file.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jffs2/file.c  2003-09-27 11:38:36.384997024 +0800
+@@ -105,8 +105,7 @@
+          it out again with the appropriate data attached */
+       if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
+               /* For these, we don't actually need to read the old node */
+-              dev =  (imajor(dentry->d_inode) << 8) | 
+-                      iminor(dentry->d_inode);
++              dev =  old_encode_dev(dentry->d_inode->i_rdev);
+               mdata = (char *)&dev;
+               mdatalen = sizeof(dev);
+               D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
+Index: linux-2.6.0-test5/fs/jffs2/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jffs2/super.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jffs2/super.c 2003-09-27 11:38:36.388996416 +0800
+@@ -173,7 +173,6 @@
+       int err;
+       struct nameidata nd;
+       int mtdnr;
+-      dev_t dev;
+       if (!dev_name)
+               return ERR_PTR(-EINVAL);
+@@ -227,26 +226,31 @@
+       if (err)
+               return ERR_PTR(err);
+-      if (!S_ISBLK(nd.dentry->d_inode->i_mode)) {
+-              path_release(&nd);
+-              return ERR_PTR(-EINVAL);
+-      }
++      err = -EINVAL;
++
++      if (!S_ISBLK(nd.dentry->d_inode->i_mode))
++              goto out;
++
+       if (nd.mnt->mnt_flags & MNT_NODEV) {
+-              path_release(&nd);
+-              return ERR_PTR(-EACCES);
++              err = -EACCES;
++              goto out;
+       }
+-      dev = nd.dentry->d_inode->i_rdev;
+-      path_release(&nd);
+-
+-      if (MAJOR(dev) != MTD_BLOCK_MAJOR) {
++      if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) {
+               if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */
+                       printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
+                              dev_name);
+-              return ERR_PTR(-EINVAL);
++              goto out;
+       }
+-      return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, MINOR(dev));
++      mtdnr = iminor(nd.dentry->d_inode);
++      path_release(&nd);
++
++      return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
++
++out:
++      path_release(&nd);
++      return ERR_PTR(err);
+ }
+Index: linux-2.6.0-test5/fs/jffs/inode-v23.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jffs/inode-v23.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jffs/inode-v23.c      2003-09-27 11:38:36.400994592 +0800
+@@ -139,7 +139,7 @@
+       c->thread_pid = kernel_thread (jffs_garbage_collect_thread, 
+                                       (void *) c, 
+-                                      CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++                                      CLONE_KERNEL);
+       D1(printk(KERN_NOTICE "JFFS: GC thread pid=%d.\n", (int) c->thread_pid));
+       D1(printk(KERN_NOTICE "JFFS: Successfully mounted device %s.\n",
+@@ -1734,7 +1734,7 @@
+                  the device should be read from the flash memory and then
+                  added to the inode's i_rdev member.  */
+               u16 val;
+-              jffs_read_data(f, (char *)val, 0, 2);
++              jffs_read_data(f, (char *)&val, 0, 2);
+               init_special_inode(inode, inode->i_mode,
+                       old_decode_dev(val));
+       }
+Index: linux-2.6.0-test5/fs/jfs/jfs_imap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/jfs_imap.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/jfs_imap.c        2003-09-27 11:38:36.422991248 +0800
+@@ -3041,10 +3041,11 @@
+       jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
+       jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
+       jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
+-      jfs_ip->dev = le32_to_cpu(dip->di_rdev);
+-      if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
+-              ip->i_rdev = old_decode_dev(jfs_ip->dev);
++      if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) {
++              jfs_ip->dev = le32_to_cpu(dip->di_rdev);
++              ip->i_rdev = new_decode_dev(jfs_ip->dev);
++      }
+       if (S_ISDIR(ip->i_mode)) {
+               memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384);
+@@ -3101,7 +3102,8 @@
+       dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
+       dip->di_otime.tv_nsec = 0;
+       dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
+-      dip->di_rdev = cpu_to_le32(jfs_ip->dev);
++      if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
++              dip->di_rdev = cpu_to_le32(jfs_ip->dev);
+ }
+ #ifdef        _JFS_DEBUG_IMAP
+Index: linux-2.6.0-test5/fs/jfs/jfs_mount.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/jfs_mount.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/jfs_mount.c       2003-09-27 11:38:36.427990488 +0800
+@@ -395,7 +395,7 @@
+       if (sbi->mntflag & JFS_INLINELOG)
+               sbi->logpxd = j_sb->s_logpxd;
+       else {
+-              sbi->logdev = old_decode_dev(le32_to_cpu(j_sb->s_logdev));
++              sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev));
+               memcpy(sbi->uuid, j_sb->s_uuid, sizeof(sbi->uuid));
+               memcpy(sbi->loguuid, j_sb->s_loguuid, sizeof(sbi->uuid));
+       }
+@@ -444,7 +444,7 @@
+       if (state == FM_MOUNT) {
+               /* record log's dev_t and mount serial number */
+-              j_sb->s_logdev = cpu_to_le32(sbi->log->bdev->bd_dev);
++              j_sb->s_logdev = cpu_to_le32(new_encode_dev(sbi->log->bdev->bd_dev));
+               j_sb->s_logserial = cpu_to_le32(sbi->log->serial);
+       } else if (state == FM_CLEAN) {
+               /*
+@@ -507,7 +507,7 @@
+       lrd.backchain = 0;
+       lrd.type = cpu_to_le16(LOG_MOUNT);
+       lrd.length = 0;
+-      lrd.aggregate = cpu_to_le32(sb->s_bdev->bd_dev);
++      lrd.aggregate = cpu_to_le32(new_encode_dev(sb->s_bdev->bd_dev));
+       lmLog(log, NULL, &lrd, NULL);
+       return 0;
+Index: linux-2.6.0-test5/fs/jfs/jfs_txnmgr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/jfs_txnmgr.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/jfs_txnmgr.c      2003-09-27 11:38:36.446987600 +0800
+@@ -1354,7 +1354,7 @@
+               /* initialize lrd common */
+               ip = tlck->ip;
+-              lrd->aggregate = cpu_to_le32(ip->i_sb->s_bdev->bd_dev);
++              lrd->aggregate = cpu_to_le32(new_encode_dev(ip->i_sb->s_bdev->bd_dev));
+               lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset);
+               lrd->log.redopage.inode = cpu_to_le32(ip->i_ino);
+Index: linux-2.6.0-test5/fs/jfs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/namei.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/namei.c   2003-09-27 11:38:36.456986080 +0800
+@@ -1312,7 +1312,7 @@
+       tid_t tid;
+       struct tblock *tblk;
+-      if (!old_valid_dev(rdev))
++      if (!new_valid_dev(rdev))
+               return -EINVAL;
+       jfs_info("jfs_mknod: %s", dentry->d_name.name);
+@@ -1344,7 +1344,7 @@
+               goto out3;
+       ip->i_op = &jfs_file_inode_operations;
+-      jfs_ip->dev = old_encode_dev(rdev);
++      jfs_ip->dev = new_encode_dev(rdev);
+       init_special_inode(ip, ip->i_mode, rdev);
+       insert_inode_hash(ip);
+Index: linux-2.6.0-test5/fs/jfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/jfs/super.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/jfs/super.c   2003-09-27 11:38:36.460985472 +0800
+@@ -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 @@
+       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 @@
+               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);
+@@ -284,6 +307,9 @@
+       jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
++      if (!new_valid_dev(sb->s_bdev->bd_dev))
++              return -EOVERFLOW;
++
+       sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
+       if (!sbi)
+               return -ENOSPC;
+@@ -501,24 +527,21 @@
+       /*
+        * I/O completion thread (endio)
+        */
+-      jfsIOthread = kernel_thread(jfsIOWait, 0,
+-                                  CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      jfsIOthread = kernel_thread(jfsIOWait, 0, CLONE_KERNEL);
+       if (jfsIOthread < 0) {
+               jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread);
+               goto end_txmngr;
+       }
+       wait_for_completion(&jfsIOwait);        /* Wait until thread starts */
+-      jfsCommitThread = kernel_thread(jfs_lazycommit, 0,
+-                                      CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      jfsCommitThread = kernel_thread(jfs_lazycommit, 0, CLONE_KERNEL);
+       if (jfsCommitThread < 0) {
+               jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsCommitThread);
+               goto kill_iotask;
+       }
+       wait_for_completion(&jfsIOwait);        /* Wait until thread starts */
+-      jfsSyncThread = kernel_thread(jfs_sync, 0,
+-                                    CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      jfsSyncThread = kernel_thread(jfs_sync, 0, CLONE_KERNEL);
+       if (jfsSyncThread < 0) {
+               jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread);
+               goto kill_committask;
+Index: linux-2.6.0-test5/fs/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/fs/Kconfig  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/Kconfig       2003-09-27 11:38:36.478982736 +0800
+@@ -761,8 +761,12 @@
+         This option will enlarge your kernel by about 67 KB. Several
+         programs depend on this, so everyone should say Y here.
++config PROC_KCORE
++      bool
++      default y if !ARM
++
+ config DEVFS_FS
+-      bool "/dev file system support (EXPERIMENTAL)"
++      bool "/dev file system support (OBSOLETE)"
+       depends on EXPERIMENTAL
+       help
+         This is support for devfs, a virtual file system (like /proc) which
+@@ -781,6 +785,13 @@
+         ptys, you will also need to enable (and mount) the /dev/pts
+         filesystem (CONFIG_DEVPTS_FS).
++        Note that devfs has been obsoleted by udev,
++        <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>.
++        It has been stripped down to a bare minimum and is only provided for
++        legacy installations that use its naming scheme which is
++        unfortunately different from the names normal Linux installations
++        use.
++
+         If unsure, say N.
+ config DEVFS_MOUNT
+@@ -864,7 +875,9 @@
+ config HUGETLBFS
+       bool "HugeTLB file system support"
+-      depends on HUGETLB_PAGE
++
++config HUGETLB_PAGE
++      def_bool HUGETLBFS
+ config RAMFS
+       bool
+@@ -1324,6 +1337,31 @@
+         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
+@@ -1505,7 +1543,7 @@
+         cifs module since smbfs is currently more stable and provides
+         support for older servers.  The intent of this module is to provide the
+         most advanced network file system function for CIFS compliant servers, 
+-        including support for dfs (heirarchical name space), secure per-user
++        including support for dfs (hierarchical name space), secure per-user
+         session establishment, safe distributed caching (oplock), optional
+         packet signing, Unicode and other internationalization improvements, and
+         optional Winbind (nsswitch) integration.  This module is in an early
+@@ -1562,6 +1600,20 @@
+         whenever you want), say M here and read
+         <file:Documentation/modules.txt>.  The module will be called coda.
++config CODA_FS_OLD_API
++      bool "Use 96-bit Coda file identifiers"
++      depends on CODA_FS
++      help
++        A new kernel-userspace API had to be introduced for Coda v6.0
++        to support larger 128-bit file identifiers as needed by the
++        new realms implementation.
++
++        However this new API is not backward compatible with older
++        clients. If you really need to run the old Coda userspace
++        cache manager then say Y.
++        
++        For most cases you probably want to say N.
++
+ config INTERMEZZO_FS
+       tristate "InterMezzo file system support (replicating fs) (EXPERIMENTAL)"
+       depends on INET && EXPERIMENTAL
+Index: linux-2.6.0-test5/fs/libfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/libfs.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/libfs.c       2003-09-27 11:38:36.482982128 +0800
+@@ -429,22 +429,3 @@
+       spin_unlock(&pin_fs_lock);
+       mntput(mnt);
+ }
+-
+-/* acceptable for old filesystems */
+-int old_valid_dev(dev_t dev)
+-{
+-      return MAJOR(dev) < 256 && MINOR(dev) < 256;
+-}
+-EXPORT_SYMBOL(old_valid_dev);
+-
+-u16 old_encode_dev(dev_t dev)
+-{
+-      return (MAJOR(dev) << 8) | MINOR(dev);
+-}
+-EXPORT_SYMBOL(old_encode_dev);
+-
+-dev_t old_decode_dev(u16 val)
+-{
+-      return MKDEV((val >> 8) & 255, val & 255);
+-}
+-EXPORT_SYMBOL(old_decode_dev);
+Index: linux-2.6.0-test5/fs/locks.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/locks.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/locks.c       2003-09-27 11:38:36.496980000 +0800
+@@ -221,7 +221,7 @@
+ static inline int flock_translate_cmd(int cmd) {
+       if (cmd & LOCK_MAND)
+               return cmd & (LOCK_MAND | LOCK_RW);
+-      switch (cmd &~ LOCK_NB) {
++      switch (cmd) {
+       case LOCK_SH:
+               return F_RDLCK;
+       case LOCK_EX:
+@@ -233,8 +233,8 @@
+ }
+ /* Fill in a file_lock structure with an appropriate FLOCK lock. */
+-static int flock_make_lock(struct file *filp,
+-              struct file_lock **lock, unsigned int cmd)
++static int flock_make_lock(struct file *filp, struct file_lock **lock,
++              unsigned int cmd)
+ {
+       struct file_lock *fl;
+       int type = flock_translate_cmd(cmd);
+@@ -247,7 +247,7 @@
+       fl->fl_file = filp;
+       fl->fl_pid = current->tgid;
+-      fl->fl_flags = (cmd & LOCK_NB) ? FL_FLOCK : FL_FLOCK | FL_SLEEP;
++      fl->fl_flags = FL_FLOCK;
+       fl->fl_type = type;
+       fl->fl_end = OFFSET_MAX;
+       
+@@ -1265,9 +1265,8 @@
+               locks_free_lock(fl);
+               goto out_unlock;
+       }
+-      fl->fl_next = *before;
+-      *before = fl;
+-      list_add(&fl->fl_link, &file_lock_list);
++
++      locks_insert_lock(before, fl);
+       error = f_setown(filp, current->tgid, 1);
+ out_unlock:
+@@ -1298,6 +1297,7 @@
+ {
+       struct file *filp;
+       struct file_lock *lock;
++      int can_sleep, unlock;
+       int error;
+       error = -EBADF;
+@@ -1305,12 +1305,18 @@
+       if (!filp)
+               goto out;
+-      if ((cmd != LOCK_UN) && !(cmd & LOCK_MAND) && !(filp->f_mode & 3))
++      can_sleep = !(cmd & LOCK_NB);
++      cmd &= ~LOCK_NB;
++      unlock = (cmd == LOCK_UN);
++
++      if (!unlock && !(cmd & LOCK_MAND) && !(filp->f_mode & 3))
+               goto out_putf;
+       error = flock_make_lock(filp, &lock, cmd);
+       if (error)
+               goto out_putf;
++      if (can_sleep)
++              lock->fl_flags |= FL_SLEEP;
+       error = security_file_lock(filp, cmd);
+       if (error)
+@@ -1318,7 +1324,7 @@
+       for (;;) {
+               error = flock_lock_file(filp, lock);
+-              if ((error != -EAGAIN) || (cmd & LOCK_NB))
++              if ((error != -EAGAIN) || !can_sleep)
+                       break;
+               error = wait_event_interruptible(lock->fl_wait, !lock->fl_next);
+               if (!error)
+@@ -1329,7 +1335,7 @@
+       }
+  out_free:
+-      if (error) {
++      if (list_empty(&lock->fl_link)) {
+               locks_free_lock(lock);
+       }
+Index: linux-2.6.0-test5/fs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/namei.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/namei.c       2003-09-27 11:38:36.511977720 +0800
+@@ -207,10 +207,14 @@
+ {
+       int retval;
+       int submask;
++      umode_t mode = inode->i_mode;
+       /* Ordinary permission routines do not understand MAY_APPEND. */
+       submask = mask & ~MAY_APPEND;
++      if (nd && (mask & MAY_WRITE) && MNT_IS_RDONLY(nd->mnt) &&
++              (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
++              return -EROFS;
+       if (inode->i_op && inode->i_op->permission)
+               retval = inode->i_op->permission(inode, submask, nd);
+       else
+@@ -1053,6 +1057,24 @@
+       return permission(dir,MAY_WRITE | MAY_EXEC, nd);
+ }
++static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
++       if (child->d_inode)
++               return -EEXIST;
++       if (IS_DEADDIR(dir))
++               return -ENOENT;
++       if (mnt->mnt_flags & MNT_RDONLY)
++               return -EROFS;
++       return 0;
++}
++
++static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
++       if (!child->d_inode)
++               return -ENOENT;
++       if (mnt->mnt_flags & MNT_RDONLY)
++               return -EROFS;
++       return 0;
++}
++
+ /* 
+  * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
+  * reasons.
+@@ -1174,7 +1196,8 @@
+                       return -EACCES;
+               flag &= ~O_TRUNC;
+-      } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
++      } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt)) &&
++              (flag & FMODE_WRITE))
+               return -EROFS;
+       /*
+        * An append-only file must be opened in append mode for writing.
+@@ -1400,23 +1423,28 @@
+ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
+ {
+       struct dentry *dentry;
++      int error;
+       down(&nd->dentry->d_inode->i_sem);
+-      dentry = ERR_PTR(-EEXIST);
++      error = -EEXIST;
+       if (nd->last_type != LAST_NORM)
+-              goto fail;
++              goto out;
+       nd->flags &= ~LOOKUP_PARENT;
+       dentry = lookup_hash(&nd->last, nd->dentry);
+       if (IS_ERR(dentry))
++              goto ret;
++      error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
++      if (error)
+               goto fail;
++      error = -ENOENT;
+       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
+-              goto enoent;
++              goto fail;
++ret:
+       return dentry;
+-enoent:
+-      dput(dentry);
+-      dentry = ERR_PTR(-ENOENT);
+ fail:
+-      return dentry;
++      dput(dentry);
++out:
++      return ERR_PTR(error);
+ }
+ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+@@ -1445,7 +1473,7 @@
+       return error;
+ }
+-asmlinkage long sys_mknod(const char __user * filename, int mode, dev_t dev)
++asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev)
+ {
+       int error = 0;
+       char * tmp;
+@@ -1471,8 +1499,12 @@
+               case 0: case S_IFREG:
+                       error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
+                       break;
+-              case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
+-                      error = vfs_mknod(nd.dentry->d_inode,dentry,mode,dev);
++              case S_IFCHR: case S_IFBLK:
++                      error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
++                                      new_decode_dev(dev));
++                      break;
++              case S_IFIFO: case S_IFSOCK:
++                      error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+                       break;
+               case S_IFDIR:
+                       error = -EPERM;
+@@ -1641,7 +1673,11 @@
+       dentry = lookup_hash(&nd.last, nd.dentry);
+       error = PTR_ERR(dentry);
+       if (!IS_ERR(dentry)) {
++              error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
++              if (error)
++                      goto exit2;
+               error = vfs_rmdir(nd.dentry->d_inode, dentry);
++      exit2:
+               dput(dentry);
+       }
+       up(&nd.dentry->d_inode->i_sem);
+@@ -1713,6 +1749,9 @@
+               /* Why not before? Because we want correct error value */
+               if (nd.last.name[nd.last.len])
+                       goto slashes;
++              error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
++              if (error)
++                      goto exit2;
+               inode = dentry->d_inode;
+               if (inode)
+                       atomic_inc(&inode->i_count);
+@@ -2077,6 +2116,9 @@
+       error = -EINVAL;
+       if (old_dentry == trap)
+               goto exit4;
++      error = -EROFS;
++      if (MNT_IS_RDONLY(newnd.mnt))
++              goto exit4;
+       new_dentry = lookup_hash(&newnd.last, new_dir);
+       error = PTR_ERR(new_dentry);
+       if (IS_ERR(new_dentry))
+Index: linux-2.6.0-test5/fs/namespace.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/namespace.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/namespace.c   2003-09-27 11:38:36.519976504 +0800
+@@ -225,7 +225,8 @@
+       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+       seq_putc(m, ' ');
+       mangle(m, mnt->mnt_sb->s_type->name);
+-      seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
++      seq_puts(m, (MNT_IS_RDONLY(mnt) ||
++              (mnt->mnt_sb->s_flags & MS_RDONLY)) ? " ro" : " rw");
+       for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
+               if (mnt->mnt_sb->s_flags & fs_infop->flag)
+                       seq_puts(m, fs_infop->str);
+@@ -516,11 +517,13 @@
+ /*
+  * do loopback mount.
+  */
+-static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
++static int do_loopback(struct nameidata *nd, char *old_name, unsigned long flags, int mnt_flags)
+ {
+       struct nameidata old_nd;
+       struct vfsmount *mnt = NULL;
++      int recurse = flags & MS_REC;
+       int err = mount_is_safe(nd);
++
+       if (err)
+               return err;
+       if (!old_name || !*old_name)
+@@ -547,6 +550,7 @@
+                       spin_unlock(&vfsmount_lock);
+               } else
+                       mntput(mnt);
++              mnt->mnt_flags = mnt_flags;
+       }
+       up_write(&current->namespace->sem);
+@@ -750,6 +754,8 @@
+               return -EINVAL;
+       /* Separate the per-mountpoint flags */
++      if (flags & MS_RDONLY)
++              mnt_flags |= MNT_RDONLY;
+       if (flags & MS_NOSUID)
+               mnt_flags |= MNT_NOSUID;
+       if (flags & MS_NODEV)
+@@ -771,7 +777,7 @@
+               retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+                                   data_page);
+       else if (flags & MS_BIND)
+-              retval = do_loopback(&nd, dev_name, flags & MS_REC);
++              retval = do_loopback(&nd, dev_name, flags, mnt_flags);
+       else if (flags & MS_MOVE)
+               retval = do_move_mount(&nd, dev_name);
+       else
+Index: linux-2.6.0-test5/fs/ncpfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ncpfs/dir.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ncpfs/dir.c   2003-09-27 11:38:36.527975288 +0800
+@@ -929,10 +929,10 @@
+       finfo.access = opmode;
+       if (ncp_is_nfs_extras(server, finfo.volume)) {
+               finfo.i.nfs.mode = mode;
+-              finfo.i.nfs.rdev = old_encode_dev(rdev);
++              finfo.i.nfs.rdev = new_encode_dev(rdev);
+               if (ncp_modify_nfs_info(server, finfo.volume,
+                                       finfo.i.dirEntNum,
+-                                      mode, old_encode_dev(rdev)) != 0)
++                                      mode, new_encode_dev(rdev)) != 0)
+                       goto out;
+       }
+@@ -1170,7 +1170,7 @@
+ static int ncp_mknod(struct inode * dir, struct dentry *dentry,
+                    int mode, dev_t rdev)
+ {
+-      if (!old_valid_dev(rdev))
++      if (!new_valid_dev(rdev))
+               return -EINVAL;
+       if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
+               DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode);
+Index: linux-2.6.0-test5/fs/ncpfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ncpfs/inode.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/ncpfs/inode.c 2003-09-27 11:38:36.534974224 +0800
+@@ -262,7 +262,7 @@
+ #ifdef CONFIG_NCPFS_NFS_NS
+               } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
+                       init_special_inode(inode, inode->i_mode,
+-                              old_decode_dev(info->i.nfs.rdev));
++                              new_decode_dev(info->i.nfs.rdev));
+ #endif
+ #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
+               } else if (S_ISLNK(inode->i_mode)) {
+Index: linux-2.6.0-test5/fs/nfsd/export.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/export.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/export.c 2003-09-27 11:38:36.542973008 +0800
+@@ -55,11 +55,16 @@
+ #define       EXPKEY_HASHMASK         (EXPKEY_HASHMAX -1)
+ static struct cache_head *expkey_table[EXPKEY_HASHMAX];
++static inline int key_len(int type)
++{
++      return type == 0 ? 8 : type == 1 ? 4 : 12;
++}
++
+ static inline int svc_expkey_hash(struct svc_expkey *item)
+ {
+       int hash = item->ek_fsidtype;
+       char * cp = (char*)item->ek_fsid;
+-      int len = (item->ek_fsidtype==0)?8:4;
++      int len = key_len(item->ek_fsidtype);
+       hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
+       hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS);
+@@ -89,7 +94,7 @@
+       qword_add(bpp, blen, ek->ek_client->name);
+       snprintf(type, 5, "%d", ek->ek_fsidtype);
+       qword_add(bpp, blen, type);
+-      qword_addhex(bpp, blen, (char*)ek->ek_fsid, ek->ek_fsidtype==0?8:4);
++      qword_addhex(bpp, blen, (char*)ek->ek_fsid, key_len(ek->ek_fsidtype));
+       (*bpp)[-1] = '\n';
+ }
+@@ -130,12 +135,12 @@
+       if (*ep)
+               goto out;
+       dprintk("found fsidtype %d\n", fsidtype);
+-      if (fsidtype > 1)
++      if (fsidtype > 2)
+               goto out;
+       if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
+               goto out;
+       dprintk("found fsid length %d\n", len);
+-      if (len != ((fsidtype==0)?8:4))
++      if (len != key_len(fsidtype))
+               goto out;
+       /* OK, we seem to have a valid key */
+@@ -206,8 +211,10 @@
+       ek = container_of(h, struct svc_expkey, h);
+       seq_printf(m, "%s %d 0x%08x", ek->ek_client->name,
+                  ek->ek_fsidtype, ek->ek_fsid[0]);
+-      if (ek->ek_fsid == 0)
+-              seq_printf(m, "%08x", ek->ek_fsid[0]);
++      if (ek->ek_fsidtype != 1)
++              seq_printf(m, "%08x", ek->ek_fsid[1]);
++      if (ek->ek_fsidtype == 2)
++              seq_printf(m, "%08x", ek->ek_fsid[2]);
+       if (test_bit(CACHE_VALID, &h->flags) && 
+           !test_bit(CACHE_NEGATIVE, &h->flags)) {
+               seq_printf(m, " ");
+@@ -230,13 +237,8 @@
+ static inline int svc_expkey_match (struct svc_expkey *a, struct svc_expkey *b)
+ {
+       if (a->ek_fsidtype != b->ek_fsidtype ||
+-          a->ek_client != b->ek_client)
+-              return 0;
+-      if (a->ek_fsid[0] != b->ek_fsid[0])
+-              return 0;
+-      if (a->ek_fsidtype == 1)
+-              return 1;
+-      if (a->ek_fsid[1] != b->ek_fsid[1])
++          a->ek_client != b->ek_client ||
++          memcmp(a->ek_fsid, b->ek_fsid, key_len(a->ek_fsidtype)) != 0)
+               return 0;
+       return 1;
+ }
+@@ -248,6 +250,7 @@
+       new->ek_fsidtype = item->ek_fsidtype;
+       new->ek_fsid[0] = item->ek_fsid[0];
+       new->ek_fsid[1] = item->ek_fsid[1];
++      new->ek_fsid[2] = item->ek_fsid[2];
+ }
+ static inline void svc_expkey_update(struct svc_expkey *new, struct svc_expkey *item)
+@@ -502,8 +505,7 @@
+       key.ek_client = clp;
+       key.ek_fsidtype = fsid_type;
+-      key.ek_fsid[0] = fsidv[0];
+-      key.ek_fsid[1] = fsidv[1];
++      memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
+       ek = svc_expkey_lookup(&key, 0);
+       if (ek != NULL)
+@@ -519,8 +521,7 @@
+       key.ek_client = clp;
+       key.ek_fsidtype = fsid_type;
+-      key.ek_fsid[0] = fsidv[0];
+-      key.ek_fsid[1] = fsidv[1];
++      memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
+       key.ek_export = exp;
+       key.h.expiry_time = NEVER;
+       key.h.flags = 0;
+@@ -539,10 +540,14 @@
+ static inline struct svc_expkey *
+ exp_get_key(svc_client *clp, dev_t dev, ino_t ino)
+ {
+-      u32 fsidv[2];
++      u32 fsidv[3];
+       
+-      mk_fsid_v0(fsidv, dev, ino);
+-      return exp_find_key(clp, 0, fsidv, NULL);
++      if (old_valid_dev(dev)) {
++              mk_fsid_v0(fsidv, dev, ino);
++              return exp_find_key(clp, 0, fsidv, NULL);
++      }
++      mk_fsid_v2(fsidv, dev, ino);
++      return exp_find_key(clp, 2, fsidv, NULL);
+ }
+ /*
+@@ -671,11 +676,15 @@
+ static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
+ {
+       u32 fsid[2];
+-      struct inode *inode;
++      struct inode *inode = exp->ex_dentry->d_inode;
++      dev_t dev = inode->i_sb->s_dev;
+-      inode = exp->ex_dentry->d_inode;
+-      mk_fsid_v0(fsid,  inode->i_sb->s_dev, inode->i_ino);
+-      return exp_set_key(clp, 0, fsid, exp);
++      if (old_valid_dev(dev)) {
++              mk_fsid_v0(fsid, dev, inode->i_ino);
++              return exp_set_key(clp, 0, fsid, exp);
++      }
++      mk_fsid_v2(fsid, dev, inode->i_ino);
++      return exp_set_key(clp, 2, fsid, exp);
+ }
+ static void exp_unhash(struct svc_export *exp)
+@@ -819,32 +828,42 @@
+ exp_unexport(struct nfsctl_export *nxp)
+ {
+       struct auth_domain *dom;
++      svc_export *exp;
++      struct nameidata nd;
+       int             err;
+       /* Consistency check */
+-      if (!exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
++      if (!exp_verify_string(nxp->ex_path, NFS_MAXPATHLEN) ||
++          !exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
+               return -EINVAL;
+       exp_writelock();
+       err = -EINVAL;
+       dom = auth_domain_find(nxp->ex_client);
+-
+-      if (dom) {
+-              struct svc_expkey *key = exp_get_key(dom, nxp->ex_dev, nxp->ex_ino);
+-              if (key && !IS_ERR(key) && key->ek_export) {
+-                      exp_do_unexport(key->ek_export);
+-                      err = 0;
+-                      expkey_put(&key->h, &svc_expkey_cache);
+-              } else
+-                      dprintk("nfsd: no export %x/%lx for %s\n",
+-                              (unsigned)nxp->ex_dev,
+-                              (unsigned long) nxp->ex_ino, nxp->ex_client);
+-              auth_domain_put(dom);
+-              cache_flush();
+-      } else
++      if (!dom) {
+               dprintk("nfsd: unexport couldn't find %s\n", nxp->ex_client);
++              goto out_unlock;
++      }
++
++      err = path_lookup(nxp->ex_path, 0, &nd);
++      if (err)
++              goto out_domain;
++      err = -EINVAL;
++      exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL);
++      path_release(&nd);
++      if (!exp)
++              goto out_domain;
++
++      exp_do_unexport(exp);
++      exp_put(exp);
++      err = 0;
++
++out_domain:
++      auth_domain_put(dom);
++      cache_flush();
++out_unlock:
+       exp_writeunlock();
+       return err;
+ }
+Index: linux-2.6.0-test5/fs/nfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/dir.c        2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/dir.c     2003-09-27 11:38:36.551971640 +0800
+@@ -859,7 +859,7 @@
+       dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id,
+               dir->i_ino, dentry->d_name.name);
+-      if (!old_valid_dev(rdev))
++      if (!new_valid_dev(rdev))
+               return -EINVAL;
+       attr.ia_mode = mode;
+Index: linux-2.6.0-test5/fs/nfs/direct.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/direct.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/direct.c  2003-09-27 11:38:36.555971032 +0800
+@@ -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 @@
+  * @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;
+ }
+Index: linux-2.6.0-test5/fs/nfsd/nfs3xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfs3xdr.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfs3xdr.c        2003-09-27 11:38:36.561970120 +0800
+@@ -186,12 +186,10 @@
+       p = xdr_encode_hyper(p, ((u64)stat.blocks) << 9);
+       *p++ = htonl((u32) MAJOR(stat.rdev));
+       *p++ = htonl((u32) MINOR(stat.rdev));
+-      if (rqstp->rq_reffh->fh_version == 1
+-          && rqstp->rq_reffh->fh_fsid_type == 1
+-          && (fhp->fh_export->ex_flags & NFSEXP_FSID))
++      if (is_fsid(fhp, rqstp->rq_reffh))
+               p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+       else
+-              p = xdr_encode_hyper(p, (u64) stat.dev);
++              p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat.dev));
+       p = xdr_encode_hyper(p, (u64) stat.ino);
+       p = encode_time3(p, &stat.atime);
+       lease_get_mtime(dentry->d_inode, &time); 
+@@ -222,12 +220,10 @@
+       p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
+       *p++ = fhp->fh_post_rdev[0];
+       *p++ = fhp->fh_post_rdev[1];
+-      if (rqstp->rq_reffh->fh_version == 1
+-          && rqstp->rq_reffh->fh_fsid_type == 1
+-          && (fhp->fh_export->ex_flags & NFSEXP_FSID))
++      if (is_fsid(fhp, rqstp->rq_reffh))
+               p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+       else
+-              p = xdr_encode_hyper(p, (u64) inode->i_sb->s_dev);
++              p = xdr_encode_hyper(p, (u64)huge_encode_dev(inode->i_sb->s_dev));
+       p = xdr_encode_hyper(p, (u64) inode->i_ino);
+       p = encode_time3(p, &fhp->fh_post_atime);
+       p = encode_time3(p, &fhp->fh_post_mtime);
+Index: linux-2.6.0-test5/fs/nfsd/nfsfh.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfsfh.c     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfsfh.c  2003-09-27 11:38:36.565969512 +0800
+@@ -125,6 +125,9 @@
+                       case 1:
+                               len = 1;
+                               break;
++                      case 2:
++                              len = 3;
++                              break;
+                       default:
+                               goto out;
+                       }
+@@ -137,7 +140,7 @@
+                       if (fh->fh_size != NFS_FHSIZE)
+                               goto out;
+                       /* assume old filehandle format */
+-                      xdev = u32_to_dev_t(fh->ofh_xdev);
++                      xdev = old_decode_dev(fh->ofh_xdev);
+                       xino = u32_to_ino_t(fh->ofh_xino);
+                       mk_fsid_v0(tfh, xdev, xino);
+                       exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle);
+@@ -329,12 +332,21 @@
+               parent->d_name.name, dentry->d_name.name,
+               (inode ? inode->i_ino : 0));
+-      if (ref_fh) {
++      /* for large devnums rules are simple */
++      if (!old_valid_dev(ex_dev)) {
++              ref_fh_version = 1;
++              if (exp->ex_flags & NFSEXP_FSID)
++                      ref_fh_fsid_type = 1;
++              else
++                      ref_fh_fsid_type = 2;
++      } else if (ref_fh) {
+               ref_fh_version = ref_fh->fh_handle.fh_version;
+               ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type;
+-              if (ref_fh == fhp)
+-                      fh_put(ref_fh);
++              if (!(exp->ex_flags & NFSEXP_FSID) || ref_fh_fsid_type == 2)
++                      ref_fh_fsid_type = 0;
+       }
++      if (ref_fh == fhp)
++              fh_put(ref_fh);
+       if (fhp->fh_locked || fhp->fh_dentry) {
+               printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
+@@ -353,7 +365,7 @@
+               memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
+               fhp->fh_handle.fh_size = NFS_FHSIZE;
+               fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
+-              fhp->fh_handle.ofh_dev =  htonl((MAJOR(ex_dev)<<16)| MINOR(ex_dev));
++              fhp->fh_handle.ofh_dev =  old_encode_dev(ex_dev);
+               fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
+               fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
+               fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
+@@ -363,19 +375,33 @@
+               fhp->fh_handle.fh_version = 1;
+               fhp->fh_handle.fh_auth_type = 0;
+               datap = fhp->fh_handle.fh_auth+0;
+-              if ((exp->ex_flags & NFSEXP_FSID) &&
+-                  (ref_fh_fsid_type == 1)) {
+-                      fhp->fh_handle.fh_fsid_type = 1;
+-                      /* fsid_type 1 == 4 bytes filesystem id */
+-                      mk_fsid_v1(datap, exp->ex_fsid);
+-                      datap += 1;
+-                      fhp->fh_handle.fh_size = 2*4;
+-              } else {
+-                      fhp->fh_handle.fh_fsid_type = 0;
+-                      /* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */
+-                      mk_fsid_v0(datap, ex_dev, exp->ex_dentry->d_inode->i_ino);
+-                      datap += 2;
+-                      fhp->fh_handle.fh_size = 3*4;
++              fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type;
++              switch (ref_fh_fsid_type) {
++                      case 1:
++                              /* fsid_type 1 == 4 bytes filesystem id */
++                              mk_fsid_v1(datap, exp->ex_fsid);
++                              datap += 1;
++                              fhp->fh_handle.fh_size = 2*4;
++                              break;
++                      case 2:
++                              /*
++                               * fsid_type 2:
++                               * 4byte major, 4byte minor, 4byte inode
++                               */
++                              mk_fsid_v2(datap, ex_dev,
++                                      exp->ex_dentry->d_inode->i_ino);
++                              datap += 3;
++                              fhp->fh_handle.fh_size = 4*4;
++                              break;
++                      default:
++                              /*
++                               * fsid_type 0:
++                               * 2byte major, 2byte minor, 4byte inode
++                               */
++                              mk_fsid_v0(datap, ex_dev,
++                                      exp->ex_dentry->d_inode->i_ino);
++                              datap += 2;
++                              fhp->fh_handle.fh_size = 3*4;
+               }
+               if (inode) {
+                       int size = fhp->fh_maxsize/4 - 3;
+Index: linux-2.6.0-test5/fs/nfsd/nfsproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfsproc.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfsproc.c        2003-09-27 11:38:36.570968752 +0800
+@@ -184,7 +184,7 @@
+       struct inode    *inode;
+       struct dentry   *dchild;
+       int             nfserr, type, mode;
+-      dev_t           rdev = 0;
++      dev_t           rdev = 0, wanted = new_decode_dev(attr->ia_size);
+       dprintk("nfsd: CREATE   %s %.*s\n",
+               SVCFH_fmt(dirfhp), argp->len, argp->name);
+@@ -230,7 +230,7 @@
+       inode = newfhp->fh_dentry->d_inode;
+       /* Unfudge the mode bits */
+-      if (attr->ia_valid & ATTR_MODE) { 
++      if (attr->ia_valid & ATTR_MODE) {
+               type = attr->ia_mode & S_IFMT;
+               mode = attr->ia_mode & ~S_IFMT;
+               if (!type) {
+@@ -242,7 +242,7 @@
+                               case S_IFCHR:
+                               case S_IFBLK:
+                                       /* reserve rdev for later checking */
+-                                      attr->ia_size = inode->i_rdev;
++                                      rdev = inode->i_rdev;
+                                       attr->ia_valid |= ATTR_SIZE;
+                                       /* FALLTHROUGH */
+@@ -277,22 +277,16 @@
+        */
+       if (type != S_IFREG) {
+               int     is_borc = 0;
+-              u32     size = attr->ia_size;
+-
+-              /* may need to change when we widen dev_t */
+-              rdev = old_decode_dev(size);
+               if (type != S_IFBLK && type != S_IFCHR) {
+                       rdev = 0;
+               } else if (type == S_IFCHR && !(attr->ia_valid & ATTR_SIZE)) {
+                       /* If you think you've seen the worst, grok this. */
+                       type = S_IFIFO;
+-              } else if (size != rdev) {
+-                      /* dev got truncated because of 16bit Linux dev_t */
+-                      nfserr = nfserr_inval;
+-                      goto out_unlock;
+               } else {
+                       /* Okay, char or block special */
+                       is_borc = 1;
++                      if (!rdev)
++                              rdev = wanted;
+               }
+               /* we've used the SIZE information, so discard it */
+@@ -300,11 +294,10 @@
+               /* Make sure the type and device matches */
+               nfserr = nfserr_exist;
+-              if (inode && (type != (inode->i_mode & S_IFMT) || 
+-                  (is_borc && inode->i_rdev != rdev)))
++              if (inode && type != (inode->i_mode & S_IFMT))
+                       goto out_unlock;
+       }
+-      
++
+       nfserr = 0;
+       if (!inode) {
+               /* File doesn't exist. Create it and set attrs */
+Index: linux-2.6.0-test5/fs/nfsd/nfsxdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfsd/nfsxdr.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfsd/nfsxdr.c 2003-09-27 11:38:36.573968296 +0800
+@@ -159,16 +159,14 @@
+       }
+       *p++ = htonl((u32) stat.blksize);
+       if (S_ISCHR(type) || S_ISBLK(type))
+-              *p++ = htonl((u32) stat.rdev);
++              *p++ = htonl(new_encode_dev(stat.rdev));
+       else
+               *p++ = htonl(0xffffffff);
+       *p++ = htonl((u32) stat.blocks);
+-      if (rqstp->rq_reffh->fh_version == 1 
+-          && rqstp->rq_reffh->fh_fsid_type == 1
+-          && (fhp->fh_export->ex_flags & NFSEXP_FSID))
++      if (is_fsid(fhp, rqstp->rq_reffh))
+               *p++ = htonl((u32) fhp->fh_export->ex_fsid);
+       else
+-              *p++ = htonl((u32) stat.dev);
++              *p++ = htonl(new_encode_dev(stat.dev));
+       *p++ = htonl((u32) stat.ino);
+       *p++ = htonl((u32) stat.atime.tv_sec);
+       *p++ = htonl(stat.atime.tv_nsec ? stat.atime.tv_nsec / 1000 : 0);
+Index: linux-2.6.0-test5/fs/nfs/nfs2xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs2xdr.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs2xdr.c 2003-09-27 11:38:36.578967536 +0800
+@@ -122,7 +122,7 @@
+       p = xdr_decode_time(p, &fattr->mtime);
+       p = xdr_decode_time(p, &fattr->ctime);
+       fattr->valid |= NFS_ATTR_FATTR;
+-      fattr->rdev = old_decode_dev(rdev);
++      fattr->rdev = new_decode_dev(rdev);
+       if (fattr->type == NFCHR && rdev == NFS2_FIFO_DEV) {
+               fattr->type = NFFIFO;
+               fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
+Index: linux-2.6.0-test5/fs/nfs/nfs3proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs3proc.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs3proc.c        2003-09-27 11:38:36.585966472 +0800
+@@ -225,81 +225,74 @@
+ }
+ 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;
+ }
+ /*
+@@ -651,7 +644,8 @@
+       default:        return -EINVAL;
+       }
+-      dprintk("NFS call  mknod %s %x\n", name->name, (unsigned)rdev);
++      dprintk("NFS call  mknod %s %u:%u\n", name->name,
++                      MAJOR(rdev), MINOR(rdev));
+       dir_attr.valid = 0;
+       fattr->valid = 0;
+       status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
+@@ -862,6 +856,7 @@
+       .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,
+Index: linux-2.6.0-test5/fs/nfs/nfs3xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs3xdr.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs3xdr.c 2003-09-27 11:38:36.591965560 +0800
+@@ -163,6 +163,8 @@
+       major = ntohl(*p++);
+       minor = ntohl(*p++);
+       fattr->rdev = MKDEV(major, minor);
++      if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
++              fattr->rdev = 0;
+       p = xdr_decode_hyper(p, &fattr->fsid_u.nfs3);
+       p = xdr_decode_hyper(p, &fattr->fileid);
+Index: linux-2.6.0-test5/fs/nfs/nfs4proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs4proc.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs4proc.c        2003-09-27 11:38:36.606963280 +0800
+@@ -1012,45 +1012,36 @@
+ }
+ 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 @@
+                       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 @@
+       .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,
+Index: linux-2.6.0-test5/fs/nfs/nfs4xdr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/nfs4xdr.c    2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/nfs4xdr.c 2003-09-27 11:38:36.622960848 +0800
+@@ -1503,7 +1503,9 @@
+               READ32(major);
+               READ32(minor);
+               nfp->rdev = MKDEV(major, minor);
+-              dprintk("read_attrs: rdev=0x%x\n", nfp->rdev);
++              if (MAJOR(nfp->rdev) != major || MINOR(nfp->rdev) != minor)
++                      nfp->rdev = 0;
++              dprintk("read_attrs: rdev=%u:%u\n", major, minor);
+         }
+         if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
+                 READ_BUF(8);
+Index: linux-2.6.0-test5/fs/nfs/pagelist.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/pagelist.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/pagelist.c        2003-09-27 11:38:36.625960392 +0800
+@@ -154,26 +154,6 @@
+ }
+ /**
+- * 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_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
+Index: linux-2.6.0-test5/fs/nfs/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/proc.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/proc.c    2003-09-27 11:38:36.631959480 +0800
+@@ -149,82 +149,62 @@
+ }
+ 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
+@@ -277,7 +257,7 @@
+               sattr->ia_valid &= ~ATTR_SIZE;
+       } else if (S_ISCHR(mode) || S_ISBLK(mode)) {
+               sattr->ia_valid |= ATTR_SIZE;
+-              sattr->ia_size   = rdev;        /* get out your barf bag */
++              sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
+       }
+       fattr->valid = 0;
+Index: linux-2.6.0-test5/fs/nfs/read.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/read.c       2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/read.c    2003-09-27 11:38:36.634959024 +0800
+@@ -69,19 +69,28 @@
+ 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 @@
+        */
+       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 @@
+                               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);
+Index: linux-2.6.0-test5/fs/nfs/write.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nfs/write.c      2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nfs/write.c   2003-09-27 11:38:36.643957656 +0800
+@@ -132,66 +132,73 @@
+ 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
+Index: linux-2.6.0-test5/fs/nls/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/Makefile     2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/Makefile  2003-09-27 11:38:36.644957504 +0800
+@@ -19,14 +19,13 @@
+ obj-$(CONFIG_NLS_CODEPAGE_865)        += nls_cp865.o
+ obj-$(CONFIG_NLS_CODEPAGE_866)        += nls_cp866.o
+ obj-$(CONFIG_NLS_CODEPAGE_869)        += nls_cp869.o
+-obj-$(CONFIG_NLS_CODEPAGE_874)        += nls_cp874.o nls_tis-620.o
+-obj-$(CONFIG_NLS_CODEPAGE_932)        += nls_cp932.o nls_sjis.o nls_euc-jp.o
+-obj-$(CONFIG_NLS_CODEPAGE_936)        += nls_cp936.o nls_gb2312.o
+-obj-$(CONFIG_NLS_CODEPAGE_949)        += nls_cp949.o nls_euc-kr.o
+-obj-$(CONFIG_NLS_CODEPAGE_950)        += nls_cp950.o nls_big5.o
++obj-$(CONFIG_NLS_CODEPAGE_874)        += nls_cp874.o
++obj-$(CONFIG_NLS_CODEPAGE_932)        += nls_cp932.o nls_euc-jp.o
++obj-$(CONFIG_NLS_CODEPAGE_936)        += nls_cp936.o
++obj-$(CONFIG_NLS_CODEPAGE_949)        += nls_cp949.o
++obj-$(CONFIG_NLS_CODEPAGE_950)        += nls_cp950.o
+ obj-$(CONFIG_NLS_CODEPAGE_1250) += nls_cp1250.o
+ obj-$(CONFIG_NLS_CODEPAGE_1251)       += nls_cp1251.o
+-obj-$(CONFIG_NLS_CODEPAGE_1255)       += nls_cp1255.o
+ obj-$(CONFIG_NLS_ISO8859_1)   += nls_iso8859-1.o
+ obj-$(CONFIG_NLS_ISO8859_2)   += nls_iso8859-2.o
+ obj-$(CONFIG_NLS_ISO8859_3)   += nls_iso8859-3.o
+@@ -34,7 +33,7 @@
+ obj-$(CONFIG_NLS_ISO8859_5)   += nls_iso8859-5.o
+ obj-$(CONFIG_NLS_ISO8859_6)   += nls_iso8859-6.o
+ obj-$(CONFIG_NLS_ISO8859_7)   += nls_iso8859-7.o
+-obj-$(CONFIG_NLS_ISO8859_8)   += nls_cp1255.o nls_iso8859-8.o
++obj-$(CONFIG_NLS_ISO8859_8)   += nls_cp1255.o
+ obj-$(CONFIG_NLS_ISO8859_9)   += nls_iso8859-9.o
+ obj-$(CONFIG_NLS_ISO8859_10)  += nls_iso8859-10.o
+ obj-$(CONFIG_NLS_ISO8859_13)  += nls_iso8859-13.o
+Index: linux-2.6.0-test5/fs/nls/nls_base.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_base.c   2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_base.c        2003-09-27 11:38:36.649956744 +0800
+@@ -203,9 +203,12 @@
+ {
+       struct nls_table *nls;
+       spin_lock(&nls_lock);
+-      for (nls = tables; nls; nls = nls->next)
++      for (nls = tables; nls; nls = nls->next) {
+               if (!strcmp(nls->charset, charset))
+                       break;
++              if (nls->alias && !strcmp(nls->alias, charset))
++                      break;
++      }
+       if (nls && !try_module_get(nls->owner))
+               nls = NULL;
+       spin_unlock(&nls_lock);
+Index: linux-2.6.0-test5/fs/nls/nls_cp1250.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp1250.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp1250.c      2003-09-27 11:38:36.653956136 +0800
+@@ -345,21 +345,3 @@
+ module_exit(exit_nls_cp1250)
+ MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+-
+Index: linux-2.6.0-test5/fs/nls/nls_cp1251.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp1251.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp1251.c      2003-09-27 11:38:36.657955528 +0800
+@@ -299,20 +299,4 @@
+ module_init(init_nls_cp1251)
+ module_exit(exit_nls_cp1251)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp1255.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp1255.c 2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp1255.c      2003-09-27 11:38:36.663954616 +0800
+@@ -360,6 +360,7 @@
+ static struct nls_table table = {
+       .charset        = "cp1255",
++      .alias          = "iso8859-8",
+       .uni2char       = uni2char,
+       .char2uni       = char2uni,
+       .charset2lower  = charset2lower,
+@@ -380,20 +381,5 @@
+ module_init(init_nls_cp1255)
+ module_exit(exit_nls_cp1255)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(iso8859-8);
+Index: linux-2.6.0-test5/fs/nls/nls_cp437.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp437.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp437.c       2003-09-27 11:38:36.668953856 +0800
+@@ -385,20 +385,4 @@
+ module_init(init_nls_cp437)
+ module_exit(exit_nls_cp437)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp737.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp737.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp737.c       2003-09-27 11:38:36.672953248 +0800
+@@ -348,20 +348,4 @@
+ module_init(init_nls_cp737)
+ module_exit(exit_nls_cp737)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp775.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp775.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp775.c       2003-09-27 11:38:36.677952488 +0800
+@@ -317,20 +317,4 @@
+ module_init(init_nls_cp775)
+ module_exit(exit_nls_cp775)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp850.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp850.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp850.c       2003-09-27 11:38:36.681951880 +0800
+@@ -313,20 +313,4 @@
+ module_init(init_nls_cp850)
+ module_exit(exit_nls_cp850)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp852.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp852.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp852.c       2003-09-27 11:38:36.685951272 +0800
+@@ -335,20 +335,4 @@
+ module_init(init_nls_cp852)
+ module_exit(exit_nls_cp852)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp855.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp855.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp855.c       2003-09-27 11:38:36.690950512 +0800
+@@ -297,20 +297,4 @@
+ module_init(init_nls_cp855)
+ module_exit(exit_nls_cp855)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp857.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp857.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp857.c       2003-09-27 11:38:36.694949904 +0800
+@@ -299,20 +299,4 @@
+ module_init(init_nls_cp857)
+ module_exit(exit_nls_cp857)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp860.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp860.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp860.c       2003-09-27 11:38:36.699949144 +0800
+@@ -362,20 +362,4 @@
+ module_init(init_nls_cp860)
+ module_exit(exit_nls_cp860)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp861.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp861.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp861.c       2003-09-27 11:38:36.704948384 +0800
+@@ -385,20 +385,4 @@
+ module_init(init_nls_cp861)
+ module_exit(exit_nls_cp861)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp862.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp862.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp862.c       2003-09-27 11:38:36.710947472 +0800
+@@ -419,20 +419,4 @@
+ module_init(init_nls_cp862)
+ module_exit(exit_nls_cp862)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp863.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp863.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp863.c       2003-09-27 11:38:36.715946712 +0800
+@@ -379,20 +379,4 @@
+ module_init(init_nls_cp863)
+ module_exit(exit_nls_cp863)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp864.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp864.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp864.c       2003-09-27 11:38:36.720945952 +0800
+@@ -405,20 +405,4 @@
+ module_init(init_nls_cp864)
+ module_exit(exit_nls_cp864)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp865.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp865.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp865.c       2003-09-27 11:38:36.725945192 +0800
+@@ -385,20 +385,4 @@
+ module_init(init_nls_cp865)
+ module_exit(exit_nls_cp865)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp866.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp866.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp866.c       2003-09-27 11:38:36.730944432 +0800
+@@ -303,20 +303,4 @@
+ module_init(init_nls_cp866)
+ module_exit(exit_nls_cp866)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp869.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp869.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp869.c       2003-09-27 11:38:36.734943824 +0800
+@@ -313,20 +313,4 @@
+ module_init(init_nls_cp869)
+ module_exit(exit_nls_cp869)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_cp874.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp874.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp874.c       2003-09-27 11:38:36.738943216 +0800
+@@ -251,6 +251,7 @@
+ static struct nls_table table = {
+       .charset        = "cp874",
++      .alias          = "tis-620",
+       .uni2char       = uni2char,
+       .char2uni       = char2uni,
+       .charset2lower  = charset2lower,
+@@ -271,20 +272,5 @@
+ module_init(init_nls_cp874)
+ module_exit(exit_nls_cp874)
+-/*
+- * 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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
+ MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(tis-620);
+Index: linux-2.6.0-test5/fs/nls/nls_cp932.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp932.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp932.c       2003-09-27 11:38:36.852925888 +0800
+@@ -7885,6 +7885,7 @@
+ static struct nls_table table = {
+       .charset        = "cp932",
++      .alias          = "sjis",
+       .uni2char       = uni2char,
+       .char2uni       = char2uni,
+       .charset2lower  = charset2lower,
+@@ -7904,22 +7905,6 @@
+ module_init(init_nls_cp932)
+ module_exit(exit_nls_cp932)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(sjis);
+Index: linux-2.6.0-test5/fs/nls/nls_cp936.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp936.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp936.c       2003-09-27 11:38:37.025899592 +0800
+@@ -11005,6 +11005,7 @@
+ static struct nls_table table = {
+       .charset        = "cp936",
++      .alias          = "gb2312",
+       .uni2char       = uni2char,
+       .char2uni       = char2uni,
+       .charset2lower  = charset2lower,
+@@ -11024,22 +11025,6 @@
+ module_init(init_nls_cp936)
+ module_exit(exit_nls_cp936)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(gb2312);
+Index: linux-2.6.0-test5/fs/nls/nls_cp949.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp949.c  2003-09-26 14:32:02.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp949.c       2003-09-27 11:38:37.242866608 +0800
+@@ -13922,6 +13922,7 @@
+ static struct nls_table table = {
+       .charset        = "cp949",
++      .alias          = "euc-kr",
+       .uni2char       = uni2char,
+       .char2uni       = char2uni,
+       .charset2lower  = charset2lower,
+@@ -13941,22 +13942,6 @@
+ module_init(init_nls_cp949)
+ module_exit(exit_nls_cp949)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(euc-kr);
+Index: linux-2.6.0-test5/fs/nls/nls_cp950.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_cp950.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_cp950.c       2003-09-27 11:38:37.389844264 +0800
+@@ -9461,6 +9461,7 @@
+ static struct nls_table table = {
+       .charset        = "cp950",
++      .alias          = "big5",
+       .uni2char       = uni2char,
+       .char2uni       = char2uni,
+       .charset2lower  = charset2lower,
+@@ -9480,22 +9481,6 @@
+ module_init(init_nls_cp950)
+ module_exit(exit_nls_cp950)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
++MODULE_ALIAS_NLS(big5);
+Index: linux-2.6.0-test5/fs/nls/nls_euc-jp.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_euc-jp.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_euc-jp.c      2003-09-27 11:38:37.397843048 +0800
+@@ -579,22 +579,5 @@
+ module_init(init_nls_euc_jp)
+ module_exit(exit_nls_euc_jp)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-13.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-13.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-13.c  2003-09-27 11:38:37.400842592 +0800
+@@ -282,21 +282,5 @@
+ module_init(init_nls_iso8859_13)
+ module_exit(exit_nls_iso8859_13)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-14.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-14.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-14.c  2003-09-27 11:38:37.479830584 +0800
+@@ -338,21 +338,5 @@
+ module_init(init_nls_iso8859_14)
+ module_exit(exit_nls_iso8859_14)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-15.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-15.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-15.c  2003-09-27 11:38:37.491828760 +0800
+@@ -304,21 +304,5 @@
+ module_init(init_nls_iso8859_15)
+ module_exit(exit_nls_iso8859_15)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-1.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-1.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-1.c   2003-09-27 11:38:37.583814776 +0800
+@@ -254,21 +254,5 @@
+ module_init(init_nls_iso8859_1)
+ module_exit(exit_nls_iso8859_1)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-2.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-2.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-2.c   2003-09-27 11:38:37.664802464 +0800
+@@ -305,21 +305,5 @@
+ module_init(init_nls_iso8859_2)
+ module_exit(exit_nls_iso8859_2)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-3.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-3.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-3.c   2003-09-27 11:38:37.738791216 +0800
+@@ -305,21 +305,5 @@
+ module_init(init_nls_iso8859_3)
+ module_exit(exit_nls_iso8859_3)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-4.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-4.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-4.c   2003-09-27 11:38:38.169725704 +0800
+@@ -305,21 +305,5 @@
+ module_init(init_nls_iso8859_4)
+ module_exit(exit_nls_iso8859_4)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-5.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-5.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-5.c   2003-09-27 11:38:38.190722512 +0800
+@@ -269,21 +269,5 @@
+ module_init(init_nls_iso8859_5)
+ module_exit(exit_nls_iso8859_5)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-6.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-6.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-6.c   2003-09-27 11:38:38.255712632 +0800
+@@ -260,21 +260,5 @@
+ module_init(init_nls_iso8859_6)
+ module_exit(exit_nls_iso8859_6)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-7.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-7.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-7.c   2003-09-27 11:38:38.312703968 +0800
+@@ -314,21 +314,5 @@
+ module_init(init_nls_iso8859_7)
+ module_exit(exit_nls_iso8859_7)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_iso8859-9.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_iso8859-9.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_iso8859-9.c   2003-09-27 11:38:38.975603192 +0800
+@@ -269,21 +269,5 @@
+ module_init(init_nls_iso8859_9)
+ module_exit(exit_nls_iso8859_9)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_koi8-r.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_koi8-r.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_koi8-r.c      2003-09-27 11:38:39.002599088 +0800
+@@ -320,21 +320,5 @@
+ module_init(init_nls_koi8_r)
+ module_exit(exit_nls_koi8_r)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_koi8-ru.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_koi8-ru.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_koi8-ru.c     2003-09-27 11:38:39.161574920 +0800
+@@ -79,21 +79,5 @@
+ module_init(init_nls_koi8_ru)
+ module_exit(exit_nls_koi8_ru)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/nls/nls_koi8-u.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/nls/nls_koi8-u.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/nls/nls_koi8-u.c      2003-09-27 11:38:39.166574160 +0800
+@@ -327,21 +327,5 @@
+ module_init(init_nls_koi8_u)
+ module_exit(exit_nls_koi8_u)
+-MODULE_LICENSE("Dual BSD/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-indent-level: 8
+- * c-brace-imaginary-offset: 0
+- * c-brace-offset: -8
+- * c-argdecl-indent: 8
+- * c-label-offset: -8
+- * c-continued-statement-offset: 8
+- * c-continued-brace-offset: 0
+- * End:
+- */
++MODULE_LICENSE("Dual BSD/GPL");
+Index: linux-2.6.0-test5/fs/open.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/open.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/open.c        2003-09-27 11:38:39.173573096 +0800
+@@ -187,11 +187,13 @@
+       if (length < 0)
+               return -EINVAL;
++      down_write(&dentry->d_inode->i_alloc_sem);
+       newattrs.ia_size = length;
+       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+       down(&dentry->d_inode->i_sem);
+       err = notify_change(dentry, &newattrs);
+       up(&dentry->d_inode->i_sem);
++      up_write(&dentry->d_inode->i_alloc_sem);
+       return err;
+ }
+@@ -224,7 +226,7 @@
+               goto dput_and_out;
+       error = -EROFS;
+-      if (IS_RDONLY(inode))
++      if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+               goto dput_and_out;
+       error = -EPERM;
+@@ -348,12 +350,16 @@
+       inode = nd.dentry->d_inode;
+       error = -EROFS;
+-      if (IS_RDONLY(inode))
++      if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+               goto dput_and_out;
+       /* Don't worry, the checks are done in inode_change_ok() */
+       newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
+       if (times) {
++              error = -EPERM;
++              if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
++                      goto dput_and_out;
++
+               error = get_user(newattrs.ia_atime.tv_sec, &times->actime);
+               newattrs.ia_atime.tv_nsec = 0;
+               if (!error) 
+@@ -364,6 +370,10 @@
+               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+       } else {
++                error = -EACCES;
++                if (IS_IMMUTABLE(inode))
++                        goto dput_and_out;
++
+               if (current->fsuid != inode->i_uid &&
+                   (error = permission(inode,MAY_WRITE,&nd)) != 0)
+                       goto dput_and_out;
+@@ -397,18 +407,26 @@
+       inode = nd.dentry->d_inode;
+       error = -EROFS;
+-      if (IS_RDONLY(inode))
++      if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+               goto dput_and_out;
+       /* Don't worry, the checks are done in inode_change_ok() */
+       newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
+       if (times) {
++              error = -EPERM;
++                if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
++                        goto dput_and_out;
++
+               newattrs.ia_atime.tv_sec = times[0].tv_sec;
+               newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
+               newattrs.ia_mtime.tv_sec = times[1].tv_sec;
+               newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
+               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+       } else {
++              error = -EACCES;
++                if (IS_IMMUTABLE(inode))
++                        goto dput_and_out;
++
+               if (current->fsuid != inode->i_uid &&
+                   (error = permission(inode,MAY_WRITE,&nd)) != 0)
+                       goto dput_and_out;
+@@ -471,8 +489,9 @@
+       if (!res) {
+               res = permission(nd.dentry->d_inode, mode, &nd);
+               /* 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))
++              if (!res && (mode & S_IWOTH)
++                 && !special_file(nd.dentry->d_inode->i_mode)
++                 && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt)))
+                       res = -EROFS;
+               path_release(&nd);
+       }
+@@ -577,7 +596,7 @@
+       inode = dentry->d_inode;
+       err = -EROFS;
+-      if (IS_RDONLY(inode))
++      if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
+               goto out_putf;
+       err = -EPERM;
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+@@ -609,7 +628,7 @@
+       inode = nd.dentry->d_inode;
+       error = -EROFS;
+-      if (IS_RDONLY(inode))
++      if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
+               goto dput_and_out;
+       error = -EPERM;
+@@ -630,7 +649,7 @@
+       return error;
+ }
+-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
++static int chown_common(struct vfsmount *mnt, struct dentry * dentry, uid_t user, gid_t group)
+ {
+       struct inode * inode;
+       int error;
+@@ -642,7 +661,7 @@
+               goto out;
+       }
+       error = -EROFS;
+-      if (IS_RDONLY(inode))
++      if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
+               goto out;
+       error = -EPERM;
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+@@ -672,7 +691,7 @@
+       error = user_path_walk(filename, &nd);
+       if (!error) {
+-              error = chown_common(nd.dentry, user, group);
++              error = chown_common(nd.mnt, nd.dentry, user, group);
+               path_release(&nd);
+       }
+       return error;
+@@ -685,7 +704,7 @@
+       error = user_path_walk_link(filename, &nd);
+       if (!error) {
+-              error = chown_common(nd.dentry, user, group);
++              error = chown_common(nd.mnt, nd.dentry, user, group);
+               path_release(&nd);
+       }
+       return error;
+@@ -699,7 +718,7 @@
+       file = fget(fd);
+       if (file) {
+-              error = chown_common(file->f_dentry, user, group);
++              error = chown_common(file->f_vfsmnt, file->f_dentry, user, group);
+               fput(file);
+       }
+       return error;
+Index: linux-2.6.0-test5/fs/proc/array.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/array.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/array.c  2003-09-27 11:38:39.176572640 +0800
+@@ -154,13 +154,16 @@
+       read_lock(&tasklist_lock);
+       buffer += sprintf(buffer,
+               "State:\t%s\n"
++              "SleepAVG:\t%lu%%\n"
+               "Tgid:\t%d\n"
+               "Pid:\t%d\n"
+               "PPid:\t%d\n"
+               "TracerPid:\t%d\n"
+               "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,
++              get_task_state(p),
++              (p->sleep_avg/1024)*100/(1000000000/1024),
++              p->tgid,
+               p->pid, p->pid ? p->real_parent->pid : 0,
+               p->pid && p->ptrace ? p->parent->pid : 0,
+               p->uid, p->euid, p->suid, p->fsuid,
+@@ -303,7 +306,7 @@
+               mm = mmgrab(mm);
+       if (task->tty) {
+               tty_pgrp = task->tty->pgrp;
+-              tty_nr = task->tty->device;
++              tty_nr = tty_devnum(task->tty);
+       }
+       task_unlock(task);
+       if (mm) {
+@@ -341,7 +344,7 @@
+               task->comm,
+               state,
+               ppid,
+-              task->pgrp,
++              process_group(task),
+               task->session,
+               tty_nr,
+               tty_pgrp,
+Index: linux-2.6.0-test5/fs/proc/base.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/base.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/base.c   2003-09-27 11:38:39.187570968 +0800
+@@ -44,28 +44,51 @@
+ #define fake_ino(pid,ino) (((pid)<<16)|(ino))
+ enum pid_directory_inos {
+-      PROC_PID_INO = 2,
+-      PROC_PID_STATUS,
+-      PROC_PID_MEM,
+-      PROC_PID_CWD,
+-      PROC_PID_ROOT,
+-      PROC_PID_EXE,
+-      PROC_PID_FD,
+-      PROC_PID_ENVIRON,
+-      PROC_PID_CMDLINE,
+-      PROC_PID_STAT,
+-      PROC_PID_STATM,
+-      PROC_PID_MAPS,
+-      PROC_PID_MOUNTS,
+-      PROC_PID_WCHAN,
++      PROC_TGID_INO = 2,
++      PROC_TGID_TASK,
++      PROC_TGID_STATUS,
++      PROC_TGID_MEM,
++      PROC_TGID_CWD,
++      PROC_TGID_ROOT,
++      PROC_TGID_EXE,
++      PROC_TGID_FD,
++      PROC_TGID_ENVIRON,
++      PROC_TGID_CMDLINE,
++      PROC_TGID_STAT,
++      PROC_TGID_STATM,
++      PROC_TGID_MAPS,
++      PROC_TGID_MOUNTS,
++      PROC_TGID_WCHAN,
+ #ifdef CONFIG_SECURITY
+-      PROC_PID_ATTR,
+-      PROC_PID_ATTR_CURRENT,
+-      PROC_PID_ATTR_PREV,
+-      PROC_PID_ATTR_EXEC,
+-      PROC_PID_ATTR_FSCREATE,
++      PROC_TGID_ATTR,
++      PROC_TGID_ATTR_CURRENT,
++      PROC_TGID_ATTR_PREV,
++      PROC_TGID_ATTR_EXEC,
++      PROC_TGID_ATTR_FSCREATE,
+ #endif
+-      PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
++      PROC_TGID_FD_DIR,
++      PROC_TID_INO,
++      PROC_TID_STATUS,
++      PROC_TID_MEM,
++      PROC_TID_CWD,
++      PROC_TID_ROOT,
++      PROC_TID_EXE,
++      PROC_TID_FD,
++      PROC_TID_ENVIRON,
++      PROC_TID_CMDLINE,
++      PROC_TID_STAT,
++      PROC_TID_STATM,
++      PROC_TID_MAPS,
++      PROC_TID_MOUNTS,
++      PROC_TID_WCHAN,
++#ifdef CONFIG_SECURITY
++      PROC_TID_ATTR,
++      PROC_TID_ATTR_CURRENT,
++      PROC_TID_ATTR_PREV,
++      PROC_TID_ATTR_EXEC,
++      PROC_TID_ATTR_FSCREATE,
++#endif
++      PROC_TID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
+ };
+ struct pid_entry {
+@@ -76,36 +99,68 @@
+ };
+ #define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
+-static struct pid_entry base_stuff[] = {
+-  E(PROC_PID_FD,      "fd",           S_IFDIR|S_IRUSR|S_IXUSR),
+-  E(PROC_PID_ENVIRON, "environ",      S_IFREG|S_IRUSR),
+-  E(PROC_PID_STATUS,  "status",       S_IFREG|S_IRUGO),
+-  E(PROC_PID_CMDLINE, "cmdline",      S_IFREG|S_IRUGO),
+-  E(PROC_PID_STAT,    "stat",         S_IFREG|S_IRUGO),
+-  E(PROC_PID_STATM,   "statm",        S_IFREG|S_IRUGO),
+-  E(PROC_PID_MAPS,    "maps",         S_IFREG|S_IRUGO),
+-  E(PROC_PID_MEM,     "mem",          S_IFREG|S_IRUSR|S_IWUSR),
+-  E(PROC_PID_CWD,     "cwd",          S_IFLNK|S_IRWXUGO),
+-  E(PROC_PID_ROOT,    "root",         S_IFLNK|S_IRWXUGO),
+-  E(PROC_PID_EXE,     "exe",          S_IFLNK|S_IRWXUGO),
+-  E(PROC_PID_MOUNTS,  "mounts",       S_IFREG|S_IRUGO),
++
++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_STATUS,    "status",  S_IFREG|S_IRUGO),
++      E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
++      E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
++      E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
++      E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
++      E(PROC_TGID_MEM,       "mem",     S_IFREG|S_IRUSR|S_IWUSR),
++      E(PROC_TGID_CWD,       "cwd",     S_IFLNK|S_IRWXUGO),
++      E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
++      E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
++      E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
+ #ifdef CONFIG_SECURITY
+-  E(PROC_PID_ATTR,    "attr",         S_IFDIR|S_IRUGO|S_IXUGO),
++      E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
+ #endif
+ #ifdef CONFIG_KALLSYMS
+-  E(PROC_PID_WCHAN,   "wchan",        S_IFREG|S_IRUGO),
++      E(PROC_TGID_WCHAN,     "wchan",   S_IFREG|S_IRUGO),
+ #endif
+-  {0,0,NULL,0}
++      {0,0,NULL,0}
+ };
++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_STATUS,     "status",  S_IFREG|S_IRUGO),
++      E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
++      E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
++      E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
++      E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
++      E(PROC_TID_MEM,        "mem",     S_IFREG|S_IRUSR|S_IWUSR),
++      E(PROC_TID_CWD,        "cwd",     S_IFLNK|S_IRWXUGO),
++      E(PROC_TID_ROOT,       "root",    S_IFLNK|S_IRWXUGO),
++      E(PROC_TID_EXE,        "exe",     S_IFLNK|S_IRWXUGO),
++      E(PROC_TID_MOUNTS,     "mounts",  S_IFREG|S_IRUGO),
++#ifdef CONFIG_SECURITY
++      E(PROC_TID_ATTR,       "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
++#endif
++#ifdef CONFIG_KALLSYMS
++      E(PROC_TID_WCHAN,      "wchan",   S_IFREG|S_IRUGO),
++#endif
++      {0,0,NULL,0}
++};
++
+ #ifdef CONFIG_SECURITY
+-static struct pid_entry attr_stuff[] = {
+-  E(PROC_PID_ATTR_CURRENT,    "current",      S_IFREG|S_IRUGO|S_IWUGO),
+-  E(PROC_PID_ATTR_PREV,       "prev", S_IFREG|S_IRUGO),
+-  E(PROC_PID_ATTR_EXEC,       "exec", S_IFREG|S_IRUGO|S_IWUGO),
+-  E(PROC_PID_ATTR_FSCREATE,   "fscreate",     S_IFREG|S_IRUGO|S_IWUGO),
+-  {0,0,NULL,0}
++static struct pid_entry tgid_attr_stuff[] = {
++      E(PROC_TGID_ATTR_CURRENT,  "current",  S_IFREG|S_IRUGO|S_IWUGO),
++      E(PROC_TGID_ATTR_PREV,     "prev",     S_IFREG|S_IRUGO),
++      E(PROC_TGID_ATTR_EXEC,     "exec",     S_IFREG|S_IRUGO|S_IWUGO),
++      E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
++      {0,0,NULL,0}
++};
++static struct pid_entry tid_attr_stuff[] = {
++      E(PROC_TID_ATTR_CURRENT,   "current",  S_IFREG|S_IRUGO|S_IWUGO),
++      E(PROC_TID_ATTR_PREV,      "prev",     S_IFREG|S_IRUGO),
++      E(PROC_TID_ATTR_EXEC,      "exec",     S_IFREG|S_IRUGO|S_IWUGO),
++      E(PROC_TID_ATTR_FSCREATE,  "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
++      {0,0,NULL,0}
+ };
+ #endif
++
+ #undef E
+ static inline struct task_struct *proc_task(struct inode *inode)
+@@ -128,7 +183,7 @@
+       struct task_struct *task = proc_task(inode);
+       struct files_struct *files;
+       struct file *file;
+-      int fd = proc_type(inode) - PROC_PID_FD_DIR;
++      int fd = proc_type(inode) - PROC_TID_FD_DIR;
+       task_lock(task);
+       files = task->files;
+@@ -675,7 +730,7 @@
+ {
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct task_struct *p = proc_task(inode);
+-      unsigned int fd, pid, ino;
++      unsigned int fd, tid, ino;
+       int retval;
+       char buf[NUMBUF];
+       struct files_struct * files;
+@@ -684,7 +739,7 @@
+       if (!pid_alive(p))
+               goto out;
+       retval = 0;
+-      pid = p->pid;
++      tid = p->pid;
+       fd = filp->f_pos;
+       switch (fd) {
+@@ -693,7 +748,7 @@
+                               goto out;
+                       filp->f_pos++;
+               case 1:
+-                      ino = fake_ino(pid, PROC_PID_INO);
++                      ino = fake_ino(tid, PROC_TID_INO);
+                       if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
+                               goto out;
+                       filp->f_pos++;
+@@ -723,7 +778,7 @@
+                                       i /= 10;
+                               } while (i);
+-                              ino = fake_ino(pid, PROC_PID_FD_DIR + fd);
++                              ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
+                               if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
+                                       spin_lock(&files->file_lock);
+                                       break;
+@@ -792,11 +847,18 @@
+       return ret;
+ }
+-static int proc_base_readdir(struct file * filp,
++static int proc_tgid_base_readdir(struct file * filp,
++                           void * dirent, filldir_t filldir)
++{
++      return proc_pident_readdir(filp,dirent,filldir,
++                                 tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
++}
++
++static int proc_tid_base_readdir(struct file * filp,
+                            void * dirent, filldir_t filldir)
+ {
+       return proc_pident_readdir(filp,dirent,filldir,
+-                                 base_stuff,ARRAY_SIZE(base_stuff));
++                                 tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
+ }
+ /* building an inode */
+@@ -843,7 +905,7 @@
+       ei->type = ino;
+       inode->i_uid = 0;
+       inode->i_gid = 0;
+-      if (ino == PROC_PID_INO || task_dumpable(task)) {
++      if (ino == PROC_TGID_INO || ino == PROC_TID_INO || task_dumpable(task)) {
+               inode->i_uid = task->euid;
+               inode->i_gid = task->egid;
+       }
+@@ -873,7 +935,7 @@
+       struct inode *inode = dentry->d_inode;
+       struct task_struct *task = proc_task(inode);
+       if (pid_alive(task)) {
+-              if (proc_type(inode) == PROC_PID_INO || task_dumpable(task)) {
++              if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
+                       inode->i_uid = task->euid;
+                       inode->i_gid = task->egid;
+               } else {
+@@ -887,11 +949,11 @@
+       return 0;
+ }
+-static int pid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
++static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
+ {
+       struct inode *inode = dentry->d_inode;
+       struct task_struct *task = proc_task(inode);
+-      int fd = proc_type(inode) - PROC_PID_FD_DIR;
++      int fd = proc_type(inode) - PROC_TID_FD_DIR;
+       struct files_struct *files;
+       task_lock(task);
+@@ -940,10 +1002,9 @@
+       return !pid_alive(proc_task(dentry->d_inode));
+ }
+-
+-static struct dentry_operations pid_fd_dentry_operations =
++static struct dentry_operations tid_fd_dentry_operations =
+ {
+-      .d_revalidate   = pid_fd_revalidate,
++      .d_revalidate   = tid_fd_revalidate,
+       .d_delete       = pid_delete_dentry,
+ };
+@@ -999,7 +1060,7 @@
+       if (!pid_alive(task))
+               goto out;
+-      inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
++      inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd);
+       if (!inode)
+               goto out;
+       ei = PROC_I(inode);
+@@ -1024,7 +1085,7 @@
+       inode->i_op = &proc_pid_link_inode_operations;
+       inode->i_size = 64;
+       ei->op.proc_get_link = proc_fd_link;
+-      dentry->d_op = &pid_fd_dentry_operations;
++      dentry->d_op = &tid_fd_dentry_operations;
+       d_add(dentry, inode);
+       return NULL;
+@@ -1037,11 +1098,19 @@
+       return ERR_PTR(-ENOENT);
+ }
++static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir);
++static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd);
++
+ static struct file_operations proc_fd_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_readfd,
+ };
++static struct file_operations proc_task_operations = {
++      .read           = generic_read_dir,
++      .readdir        = proc_task_readdir,
++};
++
+ /*
+  * proc directories can do almost nothing..
+  */
+@@ -1050,6 +1119,11 @@
+       .permission     = proc_permission,
+ };
++static struct inode_operations proc_task_inode_operations = {
++      .lookup         = proc_task_lookup,
++      .permission     = proc_permission,
++};
++
+ #ifdef CONFIG_SECURITY
+ static ssize_t proc_pid_attr_read(struct file * file, char * buf,
+                                 size_t count, loff_t *ppos)
+@@ -1122,8 +1196,10 @@
+       .write          = proc_pid_attr_write,
+ };
+-static struct file_operations proc_attr_operations;
+-static struct inode_operations proc_attr_inode_operations;
++static struct file_operations proc_tid_attr_operations;
++static struct inode_operations proc_tid_attr_inode_operations;
++static struct file_operations proc_tgid_attr_operations;
++static struct inode_operations proc_tgid_attr_inode_operations;
+ #endif
+ /* SMP-safe */
+@@ -1161,71 +1237,98 @@
+       inode->i_mode = p->mode;
+       /*
+        * Yes, it does not scale. And it should not. Don't add
+-       * new entries into /proc/<pid>/ without very good reasons.
++       * new entries into /proc/<tgid>/ without very good reasons.
+        */
+       switch(p->type) {
+-              case PROC_PID_FD:
++              case PROC_TGID_TASK:
++                      inode->i_nlink = 3;
++                      inode->i_op = &proc_task_inode_operations;
++                      inode->i_fop = &proc_task_operations;
++                      break;
++              case PROC_TID_FD:
++              case PROC_TGID_FD:
+                       inode->i_nlink = 2;
+                       inode->i_op = &proc_fd_inode_operations;
+                       inode->i_fop = &proc_fd_operations;
+                       break;
+-              case PROC_PID_EXE:
++              case PROC_TID_EXE:
++              case PROC_TGID_EXE:
+                       inode->i_op = &proc_pid_link_inode_operations;
+                       ei->op.proc_get_link = proc_exe_link;
+                       break;
+-              case PROC_PID_CWD:
++              case PROC_TID_CWD:
++              case PROC_TGID_CWD:
+                       inode->i_op = &proc_pid_link_inode_operations;
+                       ei->op.proc_get_link = proc_cwd_link;
+                       break;
+-              case PROC_PID_ROOT:
++              case PROC_TID_ROOT:
++              case PROC_TGID_ROOT:
+                       inode->i_op = &proc_pid_link_inode_operations;
+                       ei->op.proc_get_link = proc_root_link;
+                       break;
+-              case PROC_PID_ENVIRON:
++              case PROC_TID_ENVIRON:
++              case PROC_TGID_ENVIRON:
+                       inode->i_fop = &proc_info_file_operations;
+                       ei->op.proc_read = proc_pid_environ;
+                       break;
+-              case PROC_PID_STATUS:
++              case PROC_TID_STATUS:
++              case PROC_TGID_STATUS:
+                       inode->i_fop = &proc_info_file_operations;
+                       ei->op.proc_read = proc_pid_status;
+                       break;
+-              case PROC_PID_STAT:
++              case PROC_TID_STAT:
++              case PROC_TGID_STAT:
+                       inode->i_fop = &proc_info_file_operations;
+                       ei->op.proc_read = proc_pid_stat;
+                       break;
+-              case PROC_PID_CMDLINE:
++              case PROC_TID_CMDLINE:
++              case PROC_TGID_CMDLINE:
+                       inode->i_fop = &proc_info_file_operations;
+                       ei->op.proc_read = proc_pid_cmdline;
+                       break;
+-              case PROC_PID_STATM:
++              case PROC_TID_STATM:
++              case PROC_TGID_STATM:
+                       inode->i_fop = &proc_info_file_operations;
+                       ei->op.proc_read = proc_pid_statm;
+                       break;
+-              case PROC_PID_MAPS:
++              case PROC_TID_MAPS:
++              case PROC_TGID_MAPS:
+                       inode->i_fop = &proc_maps_operations;
+                       break;
+-              case PROC_PID_MEM:
++              case PROC_TID_MEM:
++              case PROC_TGID_MEM:
+                       inode->i_op = &proc_mem_inode_operations;
+                       inode->i_fop = &proc_mem_operations;
+                       break;
+-              case PROC_PID_MOUNTS:
++              case PROC_TID_MOUNTS:
++              case PROC_TGID_MOUNTS:
+                       inode->i_fop = &proc_mounts_operations;
+                       break;
+ #ifdef CONFIG_SECURITY
+-              case PROC_PID_ATTR:
++              case PROC_TID_ATTR:
++                      inode->i_nlink = 2;
++                      inode->i_op = &proc_tid_attr_inode_operations;
++                      inode->i_fop = &proc_tid_attr_operations;
++                      break;
++              case PROC_TGID_ATTR:
+                       inode->i_nlink = 2;
+-                      inode->i_op = &proc_attr_inode_operations;
+-                      inode->i_fop = &proc_attr_operations;
++                      inode->i_op = &proc_tgid_attr_inode_operations;
++                      inode->i_fop = &proc_tgid_attr_operations;
+                       break;
+-              case PROC_PID_ATTR_CURRENT:
+-              case PROC_PID_ATTR_PREV:
+-              case PROC_PID_ATTR_EXEC:
+-              case PROC_PID_ATTR_FSCREATE:
++              case PROC_TID_ATTR_CURRENT:
++              case PROC_TGID_ATTR_CURRENT:
++              case PROC_TID_ATTR_PREV:
++              case PROC_TGID_ATTR_PREV:
++              case PROC_TID_ATTR_EXEC:
++              case PROC_TGID_ATTR_EXEC:
++              case PROC_TID_ATTR_FSCREATE:
++              case PROC_TGID_ATTR_FSCREATE:
+                       inode->i_fop = &proc_pid_attr_operations;
+                       break;
+ #endif
+ #ifdef CONFIG_KALLSYMS
+-              case PROC_PID_WCHAN:
++              case PROC_TID_WCHAN:
++              case PROC_TGID_WCHAN:
+                       inode->i_fop = &proc_info_file_operations;
+                       ei->op.proc_read = proc_pid_wchan;
+                       break;
+@@ -1243,40 +1346,75 @@
+       return ERR_PTR(error);
+ }
+-static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+-      return proc_pident_lookup(dir, dentry, base_stuff);
++static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
++      return proc_pident_lookup(dir, dentry, tgid_base_stuff);
++}
++
++static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
++      return proc_pident_lookup(dir, dentry, tid_base_stuff);
+ }
+-static struct file_operations proc_base_operations = {
++static struct file_operations proc_tgid_base_operations = {
++      .read           = generic_read_dir,
++      .readdir        = proc_tgid_base_readdir,
++};
++
++static struct file_operations proc_tid_base_operations = {
+       .read           = generic_read_dir,
+-      .readdir        = proc_base_readdir,
++      .readdir        = proc_tid_base_readdir,
++};
++
++static struct inode_operations proc_tgid_base_inode_operations = {
++      .lookup         = proc_tgid_base_lookup,
+ };
+-static struct inode_operations proc_base_inode_operations = {
+-      .lookup         = proc_base_lookup,
++static struct inode_operations proc_tid_base_inode_operations = {
++      .lookup         = proc_tid_base_lookup,
+ };
+ #ifdef CONFIG_SECURITY
+-static int proc_attr_readdir(struct file * filp,
++static int proc_tgid_attr_readdir(struct file * filp,
+                            void * dirent, filldir_t filldir)
+ {
+       return proc_pident_readdir(filp,dirent,filldir,
+-                                 attr_stuff,ARRAY_SIZE(attr_stuff));
++                                 tgid_attr_stuff,ARRAY_SIZE(tgid_attr_stuff));
+ }
+-static struct file_operations proc_attr_operations = {
++static int proc_tid_attr_readdir(struct file * filp,
++                           void * dirent, filldir_t filldir)
++{
++      return proc_pident_readdir(filp,dirent,filldir,
++                                 tid_attr_stuff,ARRAY_SIZE(tid_attr_stuff));
++}
++
++static struct file_operations proc_tgid_attr_operations = {
++      .read           = generic_read_dir,
++      .readdir        = proc_tgid_attr_readdir,
++};
++
++static struct file_operations proc_tid_attr_operations = {
+       .read           = generic_read_dir,
+-      .readdir        = proc_attr_readdir,
++      .readdir        = proc_tid_attr_readdir,
+ };
+-static struct dentry *proc_attr_lookup(struct inode *dir,
++static struct dentry *proc_tgid_attr_lookup(struct inode *dir,
+                               struct dentry *dentry, struct nameidata *nd)
+ {
+-      return proc_pident_lookup(dir, dentry, attr_stuff);
++      return proc_pident_lookup(dir, dentry, tgid_attr_stuff);
+ }
+-static struct inode_operations proc_attr_inode_operations = {
+-      .lookup         = proc_attr_lookup,
++static struct dentry *proc_tid_attr_lookup(struct inode *dir,
++                              struct dentry *dentry, struct nameidata *nd)
++{
++      return proc_pident_lookup(dir, dentry, tid_attr_stuff);
++}
++
++static struct inode_operations proc_tgid_attr_inode_operations = {
++      .lookup         = proc_tgid_attr_lookup,
++};
++
++static struct inode_operations proc_tid_attr_inode_operations = {
++      .lookup         = proc_tid_attr_lookup,
+ };
+ #endif
+@@ -1286,14 +1424,14 @@
+ static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+       char tmp[30];
+-      sprintf(tmp, "%d", current->pid);
++      sprintf(tmp, "%d", current->tgid);
+       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", current->tgid);
+       return vfs_follow_link(nd,tmp);
+ }     
+@@ -1357,7 +1495,7 @@
+       struct task_struct *task;
+       struct inode *inode;
+       struct proc_inode *ei;
+-      unsigned pid;
++      unsigned tgid;
+       if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
+               inode = new_inode(dir->i_sb);
+@@ -1365,7 +1503,7 @@
+                       return ERR_PTR(-ENOMEM);
+               ei = PROC_I(inode);
+               inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+-              inode->i_ino = fake_ino(0, PROC_PID_INO);
++              inode->i_ino = fake_ino(0, PROC_TGID_INO);
+               ei->pde = NULL;
+               inode->i_mode = S_IFLNK|S_IRWXUGO;
+               inode->i_uid = inode->i_gid = 0;
+@@ -1374,19 +1512,19 @@
+               d_add(dentry, inode);
+               return NULL;
+       }
+-      pid = name_to_int(dentry);
+-      if (pid == ~0U)
++      tgid = name_to_int(dentry);
++      if (tgid == ~0U)
+               goto out;
+       read_lock(&tasklist_lock);
+-      task = find_task_by_pid(pid);
++      task = find_task_by_pid(tgid);
+       if (task)
+               get_task_struct(task);
+       read_unlock(&tasklist_lock);
+       if (!task)
+               goto out;
+-      inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
++      inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
+       if (!inode) {
+@@ -1394,8 +1532,53 @@
+               goto out;
+       }
+       inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+-      inode->i_op = &proc_base_inode_operations;
+-      inode->i_fop = &proc_base_operations;
++      inode->i_op = &proc_tgid_base_inode_operations;
++      inode->i_fop = &proc_tgid_base_operations;
++      inode->i_nlink = 3;
++      inode->i_flags|=S_IMMUTABLE;
++
++      dentry->d_op = &pid_base_dentry_operations;
++
++      spin_lock(&task->proc_lock);
++      task->proc_dentry = dentry;
++      d_add(dentry, inode);
++      spin_unlock(&task->proc_lock);
++
++      put_task_struct(task);
++      return NULL;
++out:
++      return ERR_PTR(-ENOENT);
++}
++
++/* SMP-safe */
++static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
++{
++      struct task_struct *task;
++      struct inode *inode;
++      unsigned tid;
++
++      tid = name_to_int(dentry);
++      if (tid == ~0U)
++              goto out;
++
++      read_lock(&tasklist_lock);
++      task = find_task_by_pid(tid);
++      if (task)
++              get_task_struct(task);
++      read_unlock(&tasklist_lock);
++      if (!task)
++              goto out;
++
++      inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
++
++
++      if (!inode) {
++              put_task_struct(task);
++              goto out;
++      }
++      inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
++      inode->i_op = &proc_tid_base_inode_operations;
++      inode->i_fop = &proc_tid_base_operations;
+       inode->i_nlink = 3;
+       inode->i_flags|=S_IMMUTABLE;
+@@ -1416,55 +1599,84 @@
+ #define PROC_MAXPIDS 20
+ /*
+- * Get a few pid's to return for filldir - we need to hold the
++ * Get a few tgid's to return for filldir - we need to hold the
+  * tasklist lock while doing this, and we must release it before
+  * we actually do the filldir itself, so we use a temp buffer..
+  */
+-static int get_pid_list(int index, unsigned int *pids)
++static int get_tgid_list(int index, unsigned int *tgids)
+ {
+       struct task_struct *p;
+-      int nr_pids = 0;
++      int nr_tgids = 0;
+       index--;
+       read_lock(&tasklist_lock);
+       for_each_process(p) {
+-              int pid = p->pid;
++              int tgid = p->pid;
+               if (!pid_alive(p))
+                       continue;
+               if (--index >= 0)
+                       continue;
+-              pids[nr_pids] = pid;
+-              nr_pids++;
+-              if (nr_pids >= PROC_MAXPIDS)
++              tgids[nr_tgids] = tgid;
++              nr_tgids++;
++              if (nr_tgids >= PROC_MAXPIDS)
+                       break;
+       }
+       read_unlock(&tasklist_lock);
+-      return nr_pids;
++      return nr_tgids;
++}
++
++/*
++ * Get a few tid's to return for filldir - we need to hold the
++ * tasklist lock while doing this, and we must release it before
++ * we actually do the filldir itself, so we use a temp buffer..
++ */
++static int get_tid_list(int index, unsigned int *tids, struct inode *dir)
++{
++      struct task_struct *leader_task = proc_task(dir);
++      struct task_struct *task = leader_task;
++      int nr_tids = 0;
++
++      index -= 2;
++      read_lock(&tasklist_lock);
++      do {
++              int tid = task->pid;
++              if (!pid_alive(task))
++                      continue;
++              if (--index >= 0)
++                      continue;
++              tids[nr_tids] = tid;
++              nr_tids++;
++              if (nr_tids >= PROC_MAXPIDS)
++                      break;
++      } while ((task = next_thread(task)) != leader_task);
++      read_unlock(&tasklist_lock);
++      return nr_tids;
+ }
++/* for the /proc/ directory itself, after non-process stuff has been done */
+ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+ {
+-      unsigned int pid_array[PROC_MAXPIDS];
++      unsigned int tgid_array[PROC_MAXPIDS];
+       char buf[PROC_NUMBUF];
+       unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
+-      unsigned int nr_pids, i;
++      unsigned int nr_tgids, i;
+       if (!nr) {
+-              ino_t ino = fake_ino(0,PROC_PID_INO);
++              ino_t ino = fake_ino(0,PROC_TGID_INO);
+               if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0)
+                       return 0;
+               filp->f_pos++;
+               nr++;
+       }
+-      nr_pids = get_pid_list(nr, pid_array);
++      nr_tgids = get_tgid_list(nr, tgid_array);
+-      for (i = 0; i < nr_pids; i++) {
+-              int pid = pid_array[i];
+-              ino_t ino = fake_ino(pid,PROC_PID_INO);
++      for (i = 0; i < nr_tgids; i++) {
++              int tgid = tgid_array[i];
++              ino_t ino = fake_ino(tgid,PROC_TGID_INO);
+               unsigned long j = PROC_NUMBUF;
+-              do buf[--j] = '0' + (pid % 10); while (pid/=10);
++              do buf[--j] = '0' + (tgid % 10); while (tgid/=10);
+               if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0)
+                       break;
+@@ -1472,3 +1684,55 @@
+       }
+       return 0;
+ }
++
++/* for the /proc/TGID/task/ directories */
++static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir)
++{
++      unsigned int tid_array[PROC_MAXPIDS];
++      char buf[PROC_NUMBUF];
++      unsigned int nr_tids, i;
++      struct dentry *dentry = filp->f_dentry;
++      struct inode *inode = dentry->d_inode;
++      int retval = -ENOENT;
++      ino_t ino;
++      unsigned long pos = filp->f_pos;  /* avoiding "long long" filp->f_pos */
++
++      if (!pid_alive(proc_task(inode)))
++              goto out;
++      retval = 0;
++
++      switch (pos) {
++      case 0:
++              ino = inode->i_ino;
++              if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
++                      goto out;
++              pos++;
++              /* fall through */
++      case 1:
++              ino = parent_ino(dentry);
++              if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
++                      goto out;
++              pos++;
++              /* fall through */
++      }
++
++      nr_tids = get_tid_list(pos, tid_array, inode);
++
++      for (i = 0; i < nr_tids; i++) {
++              unsigned long j = PROC_NUMBUF;
++              int tid = tid_array[i];
++
++              ino = fake_ino(tid,PROC_TID_INO);
++
++              do
++                      buf[--j] = '0' + (tid % 10);
++              while (tid /= 10);
++
++              if (filldir(dirent, buf+j, PROC_NUMBUF-j, pos, ino, DT_DIR) < 0)
++                      break;
++              pos++;
++      }
++out:
++      filp->f_pos = pos;
++      return retval;
++}
+Index: linux-2.6.0-test5/fs/proc/generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/generic.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/generic.c        2003-09-27 11:38:39.192570208 +0800
+@@ -18,13 +18,13 @@
+ #include <asm/uaccess.h>
+ #include <asm/bitops.h>
+-static ssize_t proc_file_read(struct file * file, char * buf,
++static ssize_t proc_file_read(struct file *file, char __user *buf,
+                             size_t nbytes, loff_t *ppos);
+-static ssize_t proc_file_write(struct file * file, const char * buffer,
++static ssize_t proc_file_write(struct file *file, const char __user *buffer,
+                              size_t count, loff_t *ppos);
+ static loff_t proc_file_lseek(struct file *, loff_t, int);
+-int proc_match(int len, const char *name,struct proc_dir_entry * de)
++int proc_match(int len, const char *name, struct proc_dir_entry *de)
+ {
+       if (de->namelen != len)
+               return 0;
+@@ -45,7 +45,8 @@
+ #define PROC_BLOCK_SIZE       (PAGE_SIZE - 1024)
+ static ssize_t
+-proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
++proc_file_read(struct file *file, char __user *buf, size_t nbytes,
++             loff_t *ppos)
+ {
+       struct inode * inode = file->f_dentry->d_inode;
+       char    *page;
+@@ -59,8 +60,7 @@
+       if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+               return -ENOMEM;
+-      while ((nbytes > 0) && !eof)
+-      {
++      while ((nbytes > 0) && !eof) {
+               count = MIN(PROC_BLOCK_SIZE, nbytes);
+               start = NULL;
+@@ -184,7 +184,7 @@
+ }
+ static ssize_t
+-proc_file_write(struct file * file, const char * buffer,
++proc_file_write(struct file *file, const char __user *buffer,
+               size_t count, loff_t *ppos)
+ {
+       struct inode *inode = file->f_dentry->d_inode;
+@@ -201,7 +201,7 @@
+ static loff_t
+-proc_file_lseek(struct file * file, loff_t offset, int orig)
++proc_file_lseek(struct file *file, loff_t offset, int orig)
+ {
+     lock_kernel();
+@@ -299,15 +299,16 @@
+       return i;
+ }
+-static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
++static int
++proc_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+-      char *s=PDE(dentry->d_inode)->data;
++      char *s = PDE(dentry->d_inode)->data;
+       return vfs_readlink(dentry, buffer, buflen, s);
+ }
+ static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
+ {
+-      char *s=PDE(dentry->d_inode)->data;
++      char *s = PDE(dentry->d_inode)->data;
+       return vfs_follow_link(nd, s);
+ }
+Index: linux-2.6.0-test5/fs/proc/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/inode.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/inode.c  2003-09-27 11:38:39.194569904 +0800
+@@ -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 <linux/init.h>
+@@ -136,34 +137,47 @@
+       .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;
+ }
+Index: linux-2.6.0-test5/fs/proc/kcore.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/kcore.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/kcore.c  2003-09-27 11:38:39.198569296 +0800
+@@ -27,7 +27,7 @@
+       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+ }
+-static ssize_t read_kcore(struct file *, char *, size_t, loff_t *);
++static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
+ struct file_operations proc_kcore_operations = {
+       .read           = read_kcore,
+@@ -175,6 +175,7 @@
+       elf->e_ident[EI_CLASS]  = ELF_CLASS;
+       elf->e_ident[EI_DATA]   = ELF_DATA;
+       elf->e_ident[EI_VERSION]= EV_CURRENT;
++      elf->e_ident[EI_OSABI] = ELF_OSABI;
+       memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+       elf->e_type     = ET_CORE;
+       elf->e_machine  = ELF_ARCH;
+@@ -267,7 +268,8 @@
+ /*
+  * read from the ELF header and then kernel memory
+  */
+-static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, loff_t *fpos)
++static ssize_t
++read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
+ {
+       ssize_t acc = 0;
+       size_t size, tsz;
+Index: linux-2.6.0-test5/fs/proc/kmsg.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/kmsg.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/kmsg.c   2003-09-27 11:38:39.199569144 +0800
+@@ -17,7 +17,7 @@
+ extern wait_queue_head_t log_wait;
+-extern int do_syslog(int type, char * bug, int count);
++extern int do_syslog(int type, char __user *bug, int count);
+ static int kmsg_open(struct inode * inode, struct file * file)
+ {
+@@ -30,13 +30,13 @@
+       return 0;
+ }
+-static ssize_t kmsg_read(struct file * file, char * buf,
++static ssize_t kmsg_read(struct file *file, char __user *buf,
+                        size_t count, loff_t *ppos)
+ {
+-      return do_syslog(2,buf,count);
++      return do_syslog(2, buf, count);
+ }
+-static unsigned int kmsg_poll(struct file *file, poll_table * wait)
++static unsigned int kmsg_poll(struct file *file, poll_table *wait)
+ {
+       poll_wait(file, &log_wait, wait);
+       if (do_syslog(9, 0, 0))
+Index: linux-2.6.0-test5/fs/proc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/Makefile    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/Makefile 2003-09-27 11:38:39.201568840 +0800
+@@ -8,6 +8,7 @@
+ proc-$(CONFIG_MMU)    := task_mmu.o
+ proc-y       += inode.o root.o base.o generic.o array.o \
+-              kmsg.o proc_tty.o proc_misc.o kcore.o
++              kmsg.o proc_tty.o proc_misc.o
+-proc-$(CONFIG_PROC_DEVICETREE)    += proc_devtree.o
++proc-$(CONFIG_PROC_KCORE)     += kcore.o
++proc-$(CONFIG_PROC_DEVICETREE)        += proc_devtree.o
+Index: linux-2.6.0-test5/fs/proc/proc_misc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/proc/proc_misc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/proc/proc_misc.c      2003-09-27 11:38:39.206568080 +0800
+@@ -343,7 +343,7 @@
+ #endif
+ extern struct seq_operations slabinfo_op;
+-extern ssize_t slabinfo_write(struct file *, const char *, size_t, loff_t *);
++extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
+ static int slabinfo_open(struct inode *inode, struct file *file)
+ {
+       return seq_open(file, &slabinfo_op);
+@@ -548,8 +548,8 @@
+  * buffer. Use of the program readprofile is recommended in order to
+  * get meaningful info out of these data.
+  */
+-static ssize_t read_profile(struct file *file, char *buf,
+-                          size_t count, loff_t *ppos)
++static ssize_t
++read_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+ {
+       unsigned long p = *ppos;
+       ssize_t read;
+@@ -580,13 +580,13 @@
+  * Writing a 'profiling multiplier' value into it also re-sets the profiling
+  * interrupt frequency, on architectures that support this.
+  */
+-static ssize_t write_profile(struct file * file, const char * buf,
++static ssize_t write_profile(struct file *file, const char __user *buf,
+                            size_t count, loff_t *ppos)
+ {
+ #ifdef CONFIG_SMP
+       extern int setup_profiling_timer (unsigned int multiplier);
+-      if (count==sizeof(int)) {
++      if (count == sizeof(int)) {
+               unsigned int multiplier;
+               if (copy_from_user(&multiplier, buf, sizeof(int)))
+@@ -610,8 +610,8 @@
+ /*
+  * writing 'C' to /proc/sysrq-trigger is like sysrq-C
+  */
+-static ssize_t write_sysrq_trigger(struct file *file, const char *buf,
+-                                   size_t count, loff_t *ppos)
++static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
++                                 size_t count, loff_t *ppos)
+ {
+       if (count) {
+               char c;
+@@ -638,6 +638,36 @@
+               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;
+@@ -685,12 +715,14 @@
+ #ifdef CONFIG_MODULES
+       create_seq_entry("modules", 0, &proc_modules_operations);
+ #endif
++#ifdef CONFIG_PROC_KCORE
+       proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
+       if (proc_root_kcore) {
+               proc_root_kcore->proc_fops = &proc_kcore_operations;
+               proc_root_kcore->size =
+                               (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
+       }
++#endif
+       if (prof_on) {
+               entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
+               if (entry) {
+@@ -703,6 +735,13 @@
+       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;
+Index: linux-2.6.0-test5/fs/reiserfs/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/file.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/file.c       2003-09-27 11:38:39.218566256 +0800
+@@ -485,6 +485,11 @@
+     /* Now the final thing, if we have grew the file, we must update it's size*/
+     if ( pos + write_bytes > inode->i_size) {
+       inode->i_size = pos + write_bytes; // Set new size
++      /* If the file have grown so much that tail packing is no longer possible, reset
++         "need to pack" flag */
++      if ( (have_large_tails (inode->i_sb) && inode->i_size > i_block_size (inode)*4) ||
++           (have_small_tails (inode->i_sb) && inode->i_size > i_block_size(inode)) )
++          REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;
+     }
+     /* Amount of on-disk blocks used by file have changed, update it */
+@@ -779,7 +784,7 @@
+     /* Now if all the write area lies past the file end, no point in
+        maping blocks, since there is none, so we just zero out remaining
+        parts of first and last pages in write area (if needed) */
+-    if ( (pos & ~(PAGE_CACHE_SIZE - 1)) > inode->i_size ) {
++    if ( (pos & ~((loff_t)PAGE_CACHE_SIZE - 1)) > inode->i_size ) {
+       if ( from != 0 ) {/* First page needs to be partially zeroed */
+           char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
+           memset(kaddr, 0, from);
+@@ -801,9 +806,9 @@
+        we need to allocate (calculated above) */
+     /* Mask write position to start on blocksize, we do it out of the
+        loop for performance reasons */
+-    pos &= ~(inode->i_sb->s_blocksize - 1);
++    pos &= ~((loff_t) inode->i_sb->s_blocksize - 1);
+     /* Set cpu key to the starting position in a file (on left block boundary)*/
+-    make_cpu_key (&key, inode, 1 + ((pos) & ~(inode->i_sb->s_blocksize - 1)), TYPE_ANY, 3/*key length*/);
++    make_cpu_key (&key, inode, 1 + ((pos) & ~((loff_t) inode->i_sb->s_blocksize - 1)), TYPE_ANY, 3/*key length*/);
+     reiserfs_write_lock(inode->i_sb); // We need that for at least search_by_key()
+     for ( i = 0; i < num_pages ; i++ ) { 
+@@ -999,9 +1004,41 @@
+     struct page * prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
+                               /* To simplify coding at this time, we store
+                                  locked pages in array for now */
+-    if ( count <= PAGE_CACHE_SIZE || file->f_flags & O_DIRECT)
++    if ( count <= PAGE_CACHE_SIZE )
+         return generic_file_write(file, buf, count, ppos);
++    if ( file->f_flags & O_DIRECT) { // Direct IO needs some special threating.
++      int result, after_file_end = 0;
++      if ( (*ppos + count >= inode->i_size) || (file->f_flags & O_APPEND) ) {
++          /* If we are appending a file, we need to put this savelink in here.
++             If we will crash while doing direct io, finish_unfinished will
++             cut the garbage from the file end. */
++          struct reiserfs_transaction_handle th;
++          reiserfs_write_lock(inode->i_sb);
++          journal_begin(&th, inode->i_sb,  JOURNAL_PER_BALANCE_CNT );
++          reiserfs_update_inode_transaction(inode);
++          add_save_link (&th, inode, 1 /* Truncate */);
++          journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
++          reiserfs_write_unlock(inode->i_sb);
++          after_file_end = 1;
++      }
++      result = generic_file_write(file, buf, count, ppos);
++
++      if ( after_file_end ) { /* Now update i_size and remove the savelink */
++          struct reiserfs_transaction_handle th;
++          reiserfs_write_lock(inode->i_sb);
++          journal_begin(&th, inode->i_sb, 1);
++          reiserfs_update_inode_transaction(inode);
++          reiserfs_update_sd(&th, inode);
++          journal_end(&th, inode->i_sb, 1);
++          remove_save_link (inode, 1/* truncate */);
++          reiserfs_write_unlock(inode->i_sb);
++      }
++
++      return result;
++    }
++
++
+     if ( unlikely((ssize_t) count < 0 ))
+         return -EINVAL;
+Index: linux-2.6.0-test5/fs/reiserfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/inode.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/inode.c      2003-09-27 11:38:39.253560936 +0800
+@@ -306,7 +306,7 @@
+       ** read old data off disk.  Set the up to date bit on the buffer instead
+       ** and jump to the end
+       */
+-          if (PageUptodate(bh_result->b_page)) {
++          if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
+               set_buffer_uptodate(bh_result);
+               goto finished ;
+     }
+@@ -420,6 +420,45 @@
+     return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE) ;
+ }
++/* This is special helper for reiserfs_get_block in case we are executing
++   direct_IO request. */
++static int reiserfs_get_blocks_direct_io(struct inode *inode,
++                                       sector_t iblock,
++                                       unsigned long max_blocks,
++                                       struct buffer_head *bh_result,
++                                       int create)
++{
++    int ret ;
++
++    bh_result->b_page = NULL;
++
++    /* We set the b_size before reiserfs_get_block call since it is
++       referenced in convert_tail_for_hole() that may be called from
++       reiserfs_get_block() */
++    bh_result->b_size = (1 << inode->i_blkbits);
++
++    ret = reiserfs_get_block(inode, iblock, bh_result, create) ;
++
++    /* don't allow direct io onto tail pages */
++    if (ret == 0 && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
++        /* make sure future calls to the direct io funcs for this offset
++        ** in the file fail by unmapping the buffer
++        */
++        reiserfs_unmap_buffer(bh_result);
++        ret = -EINVAL ;
++    }
++    /* Possible unpacked tail. Flush the data before pages have
++       disappeared */
++    if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
++        lock_kernel();
++        reiserfs_commit_for_inode(inode);
++        REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
++        unlock_kernel();
++    }
++    return ret ;
++}
++
++
+ /*
+ ** helper function for when reiserfs_get_block is called for a hole
+ ** but the file tail is still in a direct item
+@@ -448,7 +487,10 @@
+     tail_end = (tail_start | (bh_result->b_size - 1)) + 1 ;
+     index = tail_offset >> PAGE_CACHE_SHIFT ;
+-    if (index != hole_page->index) {
++    /* hole_page can be zero in case of direct_io, we are sure
++       that we cannot get here if we write with O_DIRECT into
++       tail page */
++    if (!hole_page || index != hole_page->index) {
+       tail_page = grab_cache_page(inode->i_mapping, index) ;
+       retval = -ENOMEM;
+       if (!tail_page) {
+@@ -554,7 +596,12 @@
+       return ret;
+     }
+-    REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;
++    /* If file is of such a size, that it might have a tail and tails are enabled
++    ** we should mark it as possibly needing tail packing on close
++    */
++    if ( (have_large_tails (inode->i_sb) && inode->i_size < i_block_size (inode)*4) ||
++       (have_small_tails (inode->i_sb) && inode->i_size < i_block_size(inode)) )
++      REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;
+     windex = push_journal_writer("reiserfs_get_block") ;
+   
+@@ -745,21 +792,26 @@
+           */
+           set_buffer_uptodate (unbh);
+-          /* we've converted the tail, so we must 
+-          ** flush unbh before the transaction commits
+-          */
+-          add_to_flushlist(inode, unbh) ;
+-
+-          /* mark it dirty now to prevent commit_write from adding
+-           ** this buffer to the inode's dirty buffer list
++          /* unbh->b_page == NULL in case of DIRECT_IO request, this means
++             buffer will disappear shortly, so it should not be added to
+            */
++          if ( unbh->b_page ) {
++              /* we've converted the tail, so we must
++              ** flush unbh before the transaction commits
++              */
++              add_to_flushlist(inode, unbh) ;
++
++              /* mark it dirty now to prevent commit_write from adding
++              ** this buffer to the inode's dirty buffer list
++              */
+               /*
+                * AKPM: changed __mark_buffer_dirty to mark_buffer_dirty().
+                * It's still atomic, but it sets the page dirty too,
+                * which makes it eligible for writeback at any time by the
+                * VM (which was also the case with __mark_buffer_dirty())
+                */
+-          mark_buffer_dirty(unbh) ;
++              mark_buffer_dirty(unbh) ;
++          }
+           //inode->i_blocks += inode->i_sb->s_blocksize / 512;
+           //mark_tail_converted (inode);
+@@ -1003,7 +1055,7 @@
+       inode->i_mapping->a_ops = &reiserfs_address_space_operations;
+     } else {
+       inode->i_blocks = 0;
+-      init_special_inode(inode, inode->i_mode, old_decode_dev(rdev));
++      init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
+     }
+ }
+@@ -1024,7 +1076,7 @@
+     set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec );
+     set_sd_v2_blocks(sd_v2, inode->i_blocks );
+     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+-      set_sd_v2_rdev(sd_v2, old_encode_dev(inode->i_rdev));
++      set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev));
+     else
+       set_sd_v2_generation(sd_v2, inode->i_generation);
+     flags = REISERFS_I(inode)->i_attrs;
+@@ -1048,7 +1100,7 @@
+     set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec );
+     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+-        set_sd_v1_rdev(sd_v1, old_encode_dev(inode->i_rdev));
++        set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev));
+     else
+         set_sd_v1_blocks(sd_v1, inode->i_blocks );
+@@ -2204,6 +2256,13 @@
+     if (pos > inode->i_size) {
+       struct reiserfs_transaction_handle th ;
+       reiserfs_write_lock(inode->i_sb);
++      /* If the file have grown beyond the border where it
++         can have a tail, unmark it as needing a tail
++         packing */
++      if ( (have_large_tails (inode->i_sb) && inode->i_size > i_block_size (inode)*4) ||
++           (have_small_tails (inode->i_sb) && inode->i_size > i_block_size(inode)) )
++          REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;
++
+       journal_begin(&th, inode->i_sb, 1) ;
+       reiserfs_update_inode_transaction(inode) ;
+       inode->i_size = pos ;
+@@ -2310,6 +2369,19 @@
+     return ret ;
+ }
++/* We thank Mingming Cao for helping us understand in great detail what
++   to do in this section of the code. */
++static int reiserfs_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 inode *inode = file->f_dentry->d_inode->i_mapping->host;
++
++    return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
++                            offset, nr_segs, reiserfs_get_blocks_direct_io, NULL);
++}
++
++
+ struct address_space_operations reiserfs_address_space_operations = {
+     .writepage = reiserfs_writepage,
+     .readpage = reiserfs_readpage, 
+@@ -2318,5 +2390,6 @@
+     .sync_page = block_sync_page,
+     .prepare_write = reiserfs_prepare_write,
+     .commit_write = reiserfs_commit_write,
+-    .bmap = reiserfs_aop_bmap
++    .bmap = reiserfs_aop_bmap,
++    .direct_IO = reiserfs_direct_IO
+ } ;
+Index: linux-2.6.0-test5/fs/reiserfs/ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/ioctl.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/ioctl.c      2003-09-27 11:38:39.255560632 +0800
+@@ -5,6 +5,7 @@
+ #include <linux/fs.h>
+ #include <linux/reiserfs_fs.h>
+ #include <linux/time.h>
++#include <linux/mount.h>
+ #include <asm/uaccess.h>
+ #include <linux/pagemap.h>
+ #include <linux/smp_lock.h>
+@@ -38,7 +39,7 @@
+               i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
+               return put_user(flags, (int *) arg);
+       case REISERFS_IOC_SETFLAGS: {
+-              if (IS_RDONLY(inode))
++              if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+                       return -EROFS;
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+@@ -70,7 +71,7 @@
+       case REISERFS_IOC_SETVERSION:
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EPERM;
+-              if (IS_RDONLY(inode))
++              if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
+                       return -EROFS;
+               if (get_user(inode->i_generation, (int *) arg))
+                       return -EFAULT; 
+Index: linux-2.6.0-test5/fs/reiserfs/journal.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/journal.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/journal.c    2003-09-27 11:38:39.284556224 +0800
+@@ -1406,6 +1406,10 @@
+                    *newest_mount_id) ;
+       return -1 ;
+     }
++    if ( get_desc_trans_len(desc) > SB_JOURNAL_TRANS_MAX(p_s_sb) ) {
++      reiserfs_warning("journal-2018: Bad transaction length %d encountered, ignoring transaction\n", get_desc_trans_len(desc));
++      return -1 ;
++    }
+     offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
+     /* ok, we have a journal description block, lets see if the transaction was valid */
+@@ -1422,11 +1426,12 @@
+                    get_commit_trans_id (commit), 
+                    get_commit_trans_len(commit));
+       brelse(c_bh) ;
+-      if (oldest_invalid_trans_id)
+-        *oldest_invalid_trans_id = get_desc_trans_id(desc) ;
++      if (oldest_invalid_trans_id) {
++      *oldest_invalid_trans_id = get_desc_trans_id(desc) ;
+       reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1004: "
+                      "transaction_is_valid setting oldest invalid trans_id "
+                      "to %d\n", get_desc_trans_id(desc)) ;
++      }
+       return -1; 
+     }
+     brelse(c_bh) ;
+@@ -1527,9 +1532,14 @@
+     } else {
+       real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(commit->j_realblock[i - trans_half])) ;
+     }
++    if ( real_blocks[i]->b_blocknr > SB_BLOCK_COUNT(p_s_sb) ) {
++      reiserfs_warning("journal-1207: REPLAY FAILURE fsck required! Block to replay is outside of filesystem\n");
++      goto abort_replay;
++    }
+     /* make sure we don't try to replay onto log or reserved area */
+     if (is_block_in_log_or_reserved_area(p_s_sb, real_blocks[i]->b_blocknr)) {
+       reiserfs_warning("journal-1204: REPLAY FAILURE fsck required! Trying to replay onto a log block\n") ;
++abort_replay:
+       brelse_array(log_blocks, i) ;
+       brelse_array(real_blocks, i) ;
+       brelse(c_bh) ;
+@@ -1906,7 +1916,7 @@
+       journal -> j_dev_bd = NULL;
+       journal -> j_dev_file = NULL;
+       jdev = SB_ONDISK_JOURNAL_DEVICE( super ) ?
+-              old_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev; 
++              new_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev; 
+       if (bdev_read_only(super->s_bdev))
+           blkdev_mode = FMODE_READ;
+Index: linux-2.6.0-test5/fs/reiserfs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/namei.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/namei.c      2003-09-27 11:38:39.295554552 +0800
+@@ -613,7 +613,7 @@
+     struct reiserfs_transaction_handle th ;
+     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+-    if (!old_valid_dev(rdev))
++    if (!new_valid_dev(rdev))
+       return -EINVAL;
+     if (!(inode = new_inode(dir->i_sb))) {
+Index: linux-2.6.0-test5/fs/reiserfs/procfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/procfs.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/procfs.c     2003-09-27 11:38:39.301553640 +0800
+@@ -13,6 +13,7 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/time.h>
++#include <linux/seq_file.h>
+ #include <asm/uaccess.h>
+ #include <linux/reiserfs_fs.h>
+ #include <linux/reiserfs_fs_sb.h>
+@@ -29,58 +30,10 @@
+  *
+  */
+-static struct super_block *procinfo_prologue(dev_t dev)
++static int show_version(struct seq_file *m, struct super_block *sb)
+ {
+-      struct super_block *result;
+-
+-      /* get super-block by device */
+-      result = user_get_super(dev);
+-      if( result != NULL ) {
+-              if( !is_reiserfs_super( result ) ) {
+-                      printk( KERN_DEBUG "reiserfs: procfs-52: "
+-                              "non-reiserfs super found\n" );
+-                      drop_super( result );
+-                      result = NULL;
+-              }
+-      } else
+-              printk( KERN_DEBUG "reiserfs: procfs-74: "
+-                      "race between procinfo and umount\n" );
+-      return result;
+-}
+-
+-int procinfo_epilogue( struct super_block *super )
+-{
+-      drop_super( super );
+-      return 0;
+-}
+-
+-int reiserfs_proc_tail( int len, char *buffer, char **start, 
+-                      off_t offset, int count, int *eof )
+-{
+-      /* this is black procfs magic */
+-      if( offset >= len ) {
+-              *start = buffer;
+-              *eof = 1;
+-              return 0;
+-      }
+-      *start = buffer + offset;
+-      if( ( len -= offset ) > count ) {
+-              return count;
+-      }
+-      *eof = 1;
+-      return len;
+-}
+-
+-int reiserfs_version_in_proc( char *buffer, char **start, off_t offset,
+-                            int count, int *eof, void *data )
+-{
+-      int len = 0;
+-      struct super_block *sb;
+       char *format;
+     
+-      sb = procinfo_prologue((int)data);
+-      if( sb == NULL )
+-              return -ENOENT;
+       if ( REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6) ) {
+               format = "3.6";
+       } else if ( REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_5) ) {
+@@ -89,7 +42,7 @@
+               format = "unknown";
+       }
+-      len += sprintf( &buffer[ len ], "%s format\twith checks %s\n",
++      seq_printf(m, "%s format\twith checks %s\n",
+                       format,
+ #if defined( CONFIG_REISERFS_CHECK )
+                       "on"
+@@ -97,15 +50,15 @@
+                       "off"
+ #endif
+               );
+-      procinfo_epilogue( sb );
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++      return 0;
+ }
+ int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset,
+                                    int count, int *eof, void *data )
+ {
+-      int len = 0;
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++      *start = buffer;
++      *eof = 1;
++      return 0;
+ }
+ #define SF( x ) ( r -> x )
+@@ -129,19 +82,11 @@
+ #define DJP( x ) le32_to_cpu( jp -> x ) 
+ #define JF( x ) ( r -> s_journal -> x )
+-int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
+-                          int count, int *eof, void *data )
++static int show_super(struct seq_file *m, struct super_block *sb)
+ {
+-      struct super_block *sb;
+-      struct reiserfs_sb_info *r;
+-      int len = 0;
++      struct reiserfs_sb_info *r = REISERFS_SB(sb);
+     
+-      sb = procinfo_prologue((int)data);
+-      if( sb == NULL )
+-              return -ENOENT;
+-      r = REISERFS_SB(sb);
+-      len += sprintf( &buffer[ len ], 
+-                      "state: \t%s\n"
++      seq_printf(m,   "state: \t%s\n"
+                       "mount options: \t%s%s%s%s%s%s%s%s%s%s%s%s\n"
+                       "gen. counter: \t%i\n"
+                       "s_kmallocs: \t%i\n"
+@@ -217,25 +162,15 @@
+                       SFP( leaked_oid ),
+                       SFP( leaves_removable ) );
+-      procinfo_epilogue( sb );
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++      return 0;
+ }
+-int reiserfs_per_level_in_proc( char *buffer, char **start, off_t offset,
+-                              int count, int *eof, void *data )
++static int show_per_level(struct seq_file *m, struct super_block *sb)
+ {
+-      struct super_block *sb;
+-      struct reiserfs_sb_info *r;
+-      int len = 0;
++      struct reiserfs_sb_info *r = REISERFS_SB(sb);
+       int level;
+-      
+-      sb = procinfo_prologue((int)data);
+-      if( sb == NULL )
+-              return -ENOENT;
+-      r = REISERFS_SB(sb);
+-      len += sprintf( &buffer[ len ],
+-                      "level\t"
++      seq_printf(m,   "level\t"
+                       "     balances"
+                       " [sbk:  reads"
+                       "   fs_changed"
+@@ -256,12 +191,7 @@
+               );
+       for( level = 0 ; level < MAX_HEIGHT ; ++ level ) {
+-              if( len > PAGE_SIZE - 240 ) {
+-                      len += sprintf( &buffer[ len ], "... and more\n" );
+-                      break;
+-              }
+-              len += sprintf( &buffer[ len ], 
+-                              "%i\t"
++              seq_printf(m,   "%i\t"
+                               " %12lu"
+                               " %12lu"
+                               " %12lu"
+@@ -296,24 +226,14 @@
+                               SFPL( need_r_neighbor )
+                       );
+       }
+-
+-      procinfo_epilogue( sb );
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++      return 0;
+ }
+-int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset,
+-                           int count, int *eof, void *data )
++static int show_bitmap(struct seq_file *m, struct super_block *sb)
+ {
+-      struct super_block *sb;
+-      struct reiserfs_sb_info *r;
+-      int len = 0;
+-    
+-      sb = procinfo_prologue((int)data);
+-      if( sb == NULL )
+-              return -ENOENT;
+-      r = REISERFS_SB(sb);
++      struct reiserfs_sb_info *r = REISERFS_SB(sb);
+-      len += sprintf( &buffer[ len ], "free_block: %lu\n"
++      seq_printf(m,   "free_block: %lu\n"
+                       "  scan_bitmap:"
+                       "          wait"
+                       "          bmap"
+@@ -339,30 +259,17 @@
+                       SFPF( in_journal_hint ),
+                       SFPF( in_journal_nohint ) );
+-      procinfo_epilogue( sb );
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++      return 0;
+ }
+-int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
+-                                  int count, int *eof, void *data )
++static int show_on_disk_super(struct seq_file *m, struct super_block *sb)
+ {
+-      struct super_block *sb;
+-      struct reiserfs_sb_info *sb_info;
+-      struct reiserfs_super_block *rs;
+-      int hash_code;
+-      __u32 flags;
+-      int len = 0;
+-    
+-      sb = procinfo_prologue((int)data);
+-      if( sb == NULL )
+-              return -ENOENT;
+-      sb_info = REISERFS_SB(sb);
+-      rs = sb_info -> s_rs;
+-      hash_code = DFL( s_hash_function_code );
+-      flags = DJF( s_flags );
++      struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
++      struct reiserfs_super_block *rs = sb_info -> s_rs;
++      int hash_code = DFL( s_hash_function_code );
++      __u32 flags = DJF( s_flags );
+-      len += sprintf( &buffer[ len ], 
+-                      "block_count: \t%i\n"
++      seq_printf(m,   "block_count: \t%i\n"
+                       "free_blocks: \t%i\n"
+                       "root_block: \t%i\n"
+                       "blocksize: \t%i\n"
+@@ -399,84 +306,49 @@
+                       ? "attrs_cleared" : "",
+                       DF (s_reserved_for_journal));
+-      procinfo_epilogue( sb );
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++      return 0;
+ }
+-int reiserfs_oidmap_in_proc( char *buffer, char **start, off_t offset,
+-                           int count, int *eof, void *data )
++static int show_oidmap(struct seq_file *m, struct super_block *sb)
+ {
+-      struct super_block *sb;
+-      struct reiserfs_sb_info *sb_info;
+-      struct reiserfs_super_block *rs;
++      struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
++      struct reiserfs_super_block *rs = sb_info -> s_rs;
++      unsigned int mapsize = le16_to_cpu( rs -> s_v1.s_oid_cursize );
++      unsigned long total_used = 0;
+       int i;
+-      unsigned int mapsize;
+-      unsigned long total_used;
+-      int len = 0;
+-      int exact;
+-    
+-      sb = procinfo_prologue((int)data);
+-      if( sb == NULL )
+-              return -ENOENT;
+-      sb_info = REISERFS_SB(sb);
+-      rs = sb_info -> s_rs;
+-      mapsize = le16_to_cpu( rs -> s_v1.s_oid_cursize );
+-      total_used = 0;
+       for( i = 0 ; i < mapsize ; ++i ) {
+               __u32 right;
+               right = ( i == mapsize - 1 ) ? MAX_KEY_OBJECTID : MAP( i + 1 );
+-              len += sprintf( &buffer[ len ], "%s: [ %x .. %x )\n",
++              seq_printf(m, "%s: [ %x .. %x )\n",
+                               ( i & 1 ) ? "free" : "used", MAP( i ), right );
+               if( ! ( i & 1 ) ) {
+                       total_used += right - MAP( i );
+               }
+-              if( len > PAGE_SIZE - 100 ) {
+-                      len += sprintf( &buffer[ len ], "... and more\n" );
+-                      break;
+-              }
+       }
+ #if defined( REISERFS_USE_OIDMAPF )
+       if( sb_info -> oidmap.use_file && ( sb_info -> oidmap.mapf != NULL ) ) {
+-              loff_t size;
+-
+-              size = sb_info -> oidmap.mapf -> f_dentry -> d_inode -> i_size;
++              loff_t size = sb_info->oidmap.mapf->f_dentry->d_inode->i_size;
+               total_used += size / sizeof( reiserfs_oidinterval_d_t );
+-              exact = 1;
+-      } else
+-#endif
+-      {
+-              exact = ( i == mapsize );
+       }
+-      len += sprintf( &buffer[ len ], "total: \t%i [%i/%i] used: %lu [%s]\n", 
+-                      i, 
++#endif
++      seq_printf(m, "total: \t%i [%i/%i] used: %lu [exact]\n", 
++                      mapsize, 
+                       mapsize, le16_to_cpu( rs -> s_v1.s_oid_maxsize ),
+-                      total_used, exact ? "exact" : "estimation" );
+-
+-      procinfo_epilogue( sb );
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++                      total_used);
++      return 0;
+ }
+-int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
+-                            int count, int *eof, void *data )
++static int show_journal(struct seq_file *m, struct super_block *sb)
+ {
+-      struct super_block *sb;
+-      struct reiserfs_sb_info *r;
+-      struct reiserfs_super_block *rs;
+-      struct journal_params *jp;      
+-      int len = 0;
++      struct reiserfs_sb_info *r = REISERFS_SB(sb);
++      struct reiserfs_super_block *rs = r -> s_rs;
++      struct journal_params *jp = &rs->s_v1.s_journal;
+       char b[BDEVNAME_SIZE];
+     
+-      sb = procinfo_prologue((int)data);
+-      if( sb == NULL )
+-              return -ENOENT;
+-      r = REISERFS_SB(sb);
+-      rs = r -> s_rs;
+-      jp = &rs->s_v1.s_journal;
+-      len += sprintf( &buffer[ len ], 
+-                      /* on-disk fields */
++      seq_printf(m,    /* on-disk fields */
+                       "jp_journal_1st_block: \t%i\n"
+                       "jp_journal_dev: \t%s[%x]\n"
+                       "jp_journal_size: \t%i\n"
+@@ -567,21 +439,115 @@
+                       SFPJ( prepare ),
+                       SFPJ( prepare_retry )
+               );
++      return 0;
++}
++
++/* iterator */
++static int test_sb(struct super_block *sb, void *data)
++{
++      return data == sb;
++}
++
++static int set_sb(struct super_block *sb, void *data)
++{
++      return -ENOENT;
++}
++
++static void *r_start(struct seq_file *m, loff_t *pos)
++{
++      struct proc_dir_entry *de = m->private;
++      struct super_block *s = de->parent->data;
++      loff_t l = *pos;
++
++      if (l)
++              return NULL;
++
++      if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, s)))
++              return NULL;
++
++      up_write(&s->s_umount);
+-      procinfo_epilogue( sb );
+-      return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
++      if (de->deleted) {
++              deactivate_super(s);
++              return NULL;
++      }
++
++      return s;
++}
++
++static void *r_next(struct seq_file *m, void *v, loff_t *pos)
++{
++      ++*pos;
++      return NULL;
++}
++
++static void r_stop(struct seq_file *m, void *v)
++{
++      struct proc_dir_entry *de = m->private;
++      struct super_block *s = de->data;
++      deactivate_super(s);
++}
++
++static int r_show(struct seq_file *m, void *v)
++{
++      struct proc_dir_entry *de = m->private;
++      int (*show)(struct seq_file *, struct super_block *) = de->data;
++      return show(m, v);
++}
++
++static struct seq_operations r_ops = {
++      .start = r_start,
++      .next = r_next,
++      .stop = r_stop,
++      .show = r_show,
++};
++
++static int r_open(struct inode *inode, struct file *file)
++{
++      int ret = seq_open(file, &r_ops);
++
++      if (!ret) {
++              struct seq_file *m = file->private_data;
++              m->private = PDE(inode);
++      }
++      return ret;
+ }
++static struct file_operations r_file_operations = {
++      .open           = r_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release,
++};
+ static struct proc_dir_entry *proc_info_root = NULL;
+ static const char proc_info_root_name[] = "fs/reiserfs";
++static void add_file(struct super_block *sb, char *name,
++      int (*func)(struct seq_file *, struct super_block *))
++{
++      struct proc_dir_entry *de;
++      de = create_proc_entry(name, 0, REISERFS_SB(sb)->procdir);
++      if (de) {
++              de->data = func;
++              de->proc_fops = &r_file_operations;
++      }
++}
++
+ int reiserfs_proc_info_init( struct super_block *sb )
+ {
+       spin_lock_init( & __PINFO( sb ).lock );
+       REISERFS_SB(sb)->procdir = proc_mkdir(reiserfs_bdevname (sb), proc_info_root);
+       if( REISERFS_SB(sb)->procdir ) {
+-              REISERFS_SB(sb)->procdir -> owner = THIS_MODULE;
++              REISERFS_SB(sb)->procdir->owner = THIS_MODULE;
++              REISERFS_SB(sb)->procdir->data = sb;
++              add_file(sb, "version", show_version);
++              add_file(sb, "super", show_super);
++              add_file(sb, "per-level", show_per_level);
++              add_file(sb, "bitmap", show_bitmap);
++              add_file(sb, "on-disk-super", show_on_disk_super);
++              add_file(sb, "oidmap", show_oidmap);
++              add_file(sb, "journal", show_journal);
+               return 0;
+       }
+       reiserfs_warning( "reiserfs: cannot create /proc/%s/%s\n",
+@@ -589,9 +555,18 @@
+       return 1;
+ }
+-
+ int reiserfs_proc_info_done( struct super_block *sb )
+ {
++      struct proc_dir_entry *de = REISERFS_SB(sb)->procdir;
++      if (de) {
++              remove_proc_entry("journal", de);
++              remove_proc_entry("oidmap", de);
++              remove_proc_entry("on-disk-super", de);
++              remove_proc_entry("bitmap", de);
++              remove_proc_entry("per-level", de);
++              remove_proc_entry("super", de);
++              remove_proc_entry("version", de);
++      }
+       spin_lock( & __PINFO( sb ).lock );
+       __PINFO( sb ).exiting = 1;
+       spin_unlock( & __PINFO( sb ).lock );
+@@ -602,23 +577,6 @@
+       return 0;
+ }
+-/* Create /proc/fs/reiserfs/DEV/name and attach read procedure @func
+-   to it.  Other parts of reiserfs use this function to make their
+-   per-device statistics available via /proc */
+-
+-struct proc_dir_entry *reiserfs_proc_register( struct super_block *sb, 
+-                                             char *name, read_proc_t *func )
+-{
+-      return ( REISERFS_SB(sb)->procdir ) ? create_proc_read_entry
+-              ( name, 0, REISERFS_SB(sb)->procdir, func, 
+-                ( void * )(int) sb->s_bdev->bd_dev) : NULL;
+-}
+-
+-void reiserfs_proc_unregister( struct super_block *sb, const char *name )
+-{
+-      remove_proc_entry( name, REISERFS_SB(sb)->procdir );
+-}
+-
+ struct proc_dir_entry *reiserfs_proc_register_global( char *name, 
+                                                     read_proc_t *func )
+ {
+@@ -662,14 +620,6 @@
+ int reiserfs_proc_info_init( struct super_block *sb ) { return 0; }
+ int reiserfs_proc_info_done( struct super_block *sb ) { return 0; }
+-struct proc_dir_entry *reiserfs_proc_register( struct super_block *sb, 
+-                                             char *name, 
+-                                             read_proc_t *func ) 
+-{ return NULL; }
+-
+-void reiserfs_proc_unregister( struct super_block *sb, const char *name ) 
+-{;}
+-
+ struct proc_dir_entry *reiserfs_proc_register_global( char *name, 
+                                                     read_proc_t *func )
+ { return NULL; }
+@@ -684,34 +634,6 @@
+                                    int count, int *eof, void *data )
+ { return 0; }
+-int reiserfs_version_in_proc( char *buffer, char **start, off_t offset,
+-                            int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
+-                          int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_per_level_in_proc( char *buffer, char **start, off_t offset,
+-                              int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset,
+-                           int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
+-                                  int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_oidmap_in_proc( char *buffer, char **start, off_t offset,
+-                           int count, int *eof, void *data )
+-{ return 0; }
+-
+-int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
+-                            int count, int *eof, void *data )
+-{ return 0; }
+-
+ /* REISERFS_PROC_INFO */
+ #endif
+Index: linux-2.6.0-test5/fs/reiserfs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/super.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/super.c      2003-09-27 11:38:39.314551664 +0800
+@@ -23,7 +23,7 @@
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
+-static struct file_system_type reiserfs_fs_type;
++struct file_system_type reiserfs_fs_type;
+ const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
+ const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
+@@ -56,11 +56,6 @@
+         is_reiserfs_jr (rs));
+ }
+-int is_reiserfs_super (struct super_block *s)
+-{
+-      return s -> s_type == & reiserfs_fs_type ;
+-}
+-
+ static int reiserfs_remount (struct super_block * s, int * flags, char * data);
+ static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);
+@@ -391,13 +386,6 @@
+                     REISERFS_SB(s)->reserved_blocks);
+   }
+-  reiserfs_proc_unregister( s, "journal" );
+-  reiserfs_proc_unregister( s, "oidmap" );
+-  reiserfs_proc_unregister( s, "on-disk-super" );
+-  reiserfs_proc_unregister( s, "bitmap" );
+-  reiserfs_proc_unregister( s, "per-level" );
+-  reiserfs_proc_unregister( s, "super" );
+-  reiserfs_proc_unregister( s, "version" );
+   reiserfs_proc_info_done( s );
+   kfree(s->s_fs_info);
+@@ -1264,6 +1252,18 @@
+       printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", reiserfs_bdevname (s));
+       goto error;    
+     }
++
++    rs = SB_DISK_SUPER_BLOCK (s);
++    /* Let's do basic sanity check to verify that underlying device is not
++       smaller than the filesystem. If the check fails then abort and scream,
++       because bad stuff will happen otherwise. */
++    if ( s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs)*sb_blocksize(rs) ) {
++      printk("Filesystem on %s cannot be mounted because it is bigger than the device\n", reiserfs_bdevname(s));
++      printk("You may need to run fsck or increase size of your LVM partition\n");
++      printk("Or may be you forgot to reboot after fdisk when it told you to\n");
++      goto error;
++    }
++
+     sbi->s_mount_state = SB_REISERFS_STATE(s);
+     sbi->s_mount_state = REISERFS_VALID_FS ;
+@@ -1324,7 +1324,6 @@
+       goto error ;
+     }
+-    rs = SB_DISK_SUPER_BLOCK (s);
+     if (is_reiserfs_3_5 (rs) || (is_reiserfs_jr (rs) && SB_VERSION (s) == REISERFS_VERSION_1))
+       set_bit(REISERFS_3_5, &(sbi->s_properties));
+     else
+@@ -1378,13 +1377,7 @@
+     handle_attrs( s );
+     reiserfs_proc_info_init( s );
+-    reiserfs_proc_register( s, "version", reiserfs_version_in_proc );
+-    reiserfs_proc_register( s, "super", reiserfs_super_in_proc );
+-    reiserfs_proc_register( s, "per-level", reiserfs_per_level_in_proc );
+-    reiserfs_proc_register( s, "bitmap", reiserfs_bitmap_in_proc );
+-    reiserfs_proc_register( s, "on-disk-super", reiserfs_on_disk_super_in_proc );
+-    reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc );
+-    reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
++
+     init_waitqueue_head (&(sbi->s_wait));
+     sbi->bitmap_lock = SPIN_LOCK_UNLOCKED;
+@@ -1469,7 +1462,7 @@
+       destroy_inodecache ();
+ }
+-static struct file_system_type reiserfs_fs_type = {
++struct file_system_type reiserfs_fs_type = {
+       .owner          = THIS_MODULE,
+       .name           = "reiserfs",
+       .get_sb         = get_super_block,
+Index: linux-2.6.0-test5/fs/reiserfs/tail_conversion.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/reiserfs/tail_conversion.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/reiserfs/tail_conversion.c    2003-09-27 11:38:39.317551208 +0800
+@@ -104,8 +104,10 @@
+       /* we only send the unbh pointer if the buffer is not up to date.
+       ** this avoids overwriting good data from writepage() with old data
+       ** from the disk or buffer cache
++      ** Special case: unbh->b_page will be NULL if we are coming through
++      ** DIRECT_IO handler here.
+       */
+-      if (buffer_uptodate(unbh) || PageUptodate(unbh->b_page)) {
++      if (!unbh->b_page || buffer_uptodate(unbh) || PageUptodate(unbh->b_page)) {
+           up_to_date_bh = NULL ;
+       } else {
+           up_to_date_bh = unbh ;
+Index: linux-2.6.0-test5/fs/smbfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/dir.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/dir.c   2003-09-27 11:38:39.321550600 +0800
+@@ -661,7 +661,7 @@
+       attr.ia_uid = current->euid;
+       attr.ia_gid = current->egid;
+-      if (!old_valid_dev(dev))
++      if (!new_valid_dev(dev))
+               return -EINVAL;
+       smb_invalid_dir_cache(dir);
+Index: linux-2.6.0-test5/fs/smbfs/inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/inode.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/inode.c 2003-09-27 11:38:39.327549688 +0800
+@@ -25,6 +25,7 @@
+ #include <linux/mount.h>
+ #include <linux/net.h>
+ #include <linux/vfs.h>
++#include <linux/highuid.h>
+ #include <linux/smb_fs.h>
+ #include <linux/smbno.h>
+ #include <linux/smb_mount.h>
+@@ -447,6 +448,19 @@
+ }
+ static void
++smb_unload_nls(struct smb_sb_info *server)
++{
++      if (server->remote_nls) {
++              unload_nls(server->remote_nls);
++              server->remote_nls = NULL;
++      }
++      if (server->local_nls) {
++              unload_nls(server->local_nls);
++              server->local_nls = NULL;
++      }
++}
++
++static void
+ smb_put_super(struct super_block *sb)
+ {
+       struct smb_sb_info *server = SMB_SB(sb);
+@@ -461,15 +475,7 @@
+               kill_proc(server->conn_pid, SIGTERM, 1);
+       smb_kfree(server->ops);
+-
+-      if (server->remote_nls) {
+-              unload_nls(server->remote_nls);
+-              server->remote_nls = NULL;
+-      }
+-      if (server->local_nls) {
+-              unload_nls(server->local_nls);
+-              server->local_nls = NULL;
+-      }
++      smb_unload_nls(server);
+       sb->s_fs_info = NULL;
+       smb_unlock_server(server);
+       smb_kfree(server);
+@@ -545,10 +551,8 @@
+       if (ver == SMB_MOUNT_OLDVERSION) {
+               mnt->version = oldmnt->version;
+-              /* FIXME: is this enough to convert uid/gid's ? */
+-              mnt->mounted_uid = oldmnt->mounted_uid;
+-              mnt->uid = oldmnt->uid;
+-              mnt->gid = oldmnt->gid;
++              mnt->uid = low2highuid(oldmnt->uid);
++              mnt->gid = low2highuid(oldmnt->gid);
+               mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
+               mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
+@@ -557,9 +561,8 @@
+       } else {
+               if (parse_options(mnt, raw_data))
+                       goto out_bad_option;
+-
+-              mnt->mounted_uid = current->uid;
+       }
++      mnt->mounted_uid = current->uid;
+       smb_setcodepage(server, &mnt->codepage);
+       /*
+@@ -571,6 +574,11 @@
+       else if (mnt->flags & SMB_MOUNT_DIRATTR)
+               printk("SMBFS: Using dir ff getattr\n");
++      if (smbiod_register_server(server) < 0) {
++              printk(KERN_ERR "smbfs: failed to start smbiod\n");
++              goto out_no_smbiod;
++      }
++
+       /*
+        * Keep the super block locked while we get the root inode.
+        */
+@@ -584,12 +592,12 @@
+               goto out_no_root;
+       smb_new_dentry(sb->s_root);
+-      smbiod_register_server(server);
+-
+       return 0;
+ out_no_root:
+       iput(root_inode);
++out_no_smbiod:
++      smb_unload_nls(server);
+ out_bad_option:
+       smb_kfree(mem);
+ out_no_mem:
+Index: linux-2.6.0-test5/fs/smbfs/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/Makefile   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/Makefile        2003-09-27 11:38:39.328549536 +0800
+@@ -32,6 +32,8 @@
+       @echo >> proto2.h " */"
+       @echo >> proto2.h ""
+       @echo >> proto2.h "struct smb_request;"
++      @echo >> proto2.h "struct sock;"
++      @echo >> proto2.h "struct statfs;"
+       @echo >> proto2.h ""
+       cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
+       mv proto2.h proto.h
+Index: linux-2.6.0-test5/fs/smbfs/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/proc.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/proc.c  2003-09-27 11:38:39.350546192 +0800
+@@ -212,12 +212,9 @@
+ }
+ static struct nls_table unicode_table = {
+-      "unicode",
+-      uni2char,
+-      char2uni,
+-      NULL,           /* not used by smbfs */
+-      NULL,
+-      NULL,           /* not a module */
++      .charset        = "unicode",
++      .uni2char       = uni2char,
++      .char2uni       = char2uni,
+ };
+ /* ----------------------------------------------------------- */
+@@ -2115,6 +2112,9 @@
+               __u64 minor = LVAL(p, 68);
+               fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff);
++              if (MAJOR(fattr->f_rdev) != (major & 0xffffffff) ||
++                  MINOR(fattr->f_rdev) != (minor & 0xffffffff))
++                      fattr->f_rdev = 0;
+       }
+       fattr->f_mode |= LVAL(p, 84);
+ }
+Index: linux-2.6.0-test5/fs/smbfs/proto.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/proto.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/proto.h 2003-09-27 11:38:39.353545736 +0800
+@@ -1,5 +1,5 @@
+ /*
+- *  Autogenerated with cproto on:  Sun Sep 29 21:48:59 CEST 2002
++ *  Autogenerated with cproto on:  Sat Sep 13 17:18:51 CEST 2003
+  */
+ struct smb_request;
+@@ -34,6 +34,7 @@
+ extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
+ extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
+ extern int smb_proc_query_cifsunix(struct smb_sb_info *server);
++extern void smb_install_null_ops(struct smb_ops *ops);
+ /* dir.c */
+ extern struct file_operations smb_dir_operations;
+ extern struct inode_operations smb_dir_inode_operations;
+@@ -71,7 +72,7 @@
+ extern int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+ /* smbiod.c */
+ extern void smbiod_wake_up(void);
+-extern void smbiod_register_server(struct smb_sb_info *server);
++extern int smbiod_register_server(struct smb_sb_info *server);
+ extern void smbiod_unregister_server(struct smb_sb_info *server);
+ extern void smbiod_flush(struct smb_sb_info *server);
+ extern int smbiod_retry(struct smb_sb_info *server);
+Index: linux-2.6.0-test5/fs/smbfs/smbiod.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/smbfs/smbiod.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/smbfs/smbiod.c        2003-09-27 11:38:39.355545432 +0800
+@@ -49,7 +49,7 @@
+ static long smbiod_flags;
+ static int smbiod(void *);
+-static void smbiod_start(void);
++static int smbiod_start(void);
+ /*
+  * called when there's work for us to do
+@@ -65,30 +65,36 @@
+ /*
+  * start smbiod if none is running
+  */
+-static void smbiod_start()
++static int smbiod_start()
+ {
+       pid_t pid;
+       if (smbiod_state != SMBIOD_DEAD)
+-              return;
++              return 0;
+       smbiod_state = SMBIOD_STARTING;
++      __module_get(THIS_MODULE);
+       spin_unlock(&servers_lock);
+       pid = kernel_thread(smbiod, NULL, 0);
++      if (pid < 0)
++              module_put(THIS_MODULE);
+       spin_lock(&servers_lock);
+-      smbiod_state = SMBIOD_RUNNING;
++      smbiod_state = pid < 0 ? SMBIOD_DEAD : SMBIOD_RUNNING;
+       smbiod_pid = pid;
++      return pid;
+ }
+ /*
+  * register a server & start smbiod if necessary
+  */
+-void smbiod_register_server(struct smb_sb_info *server)
++int smbiod_register_server(struct smb_sb_info *server)
+ {
++      int ret;
+       spin_lock(&servers_lock);
+       list_add(&server->entry, &smb_servers);
+       VERBOSE("%p\n", server);
+-      smbiod_start();
++      ret = smbiod_start();
+       spin_unlock(&servers_lock);
++      return ret;
+ }
+ /*
+@@ -282,7 +288,6 @@
+  */
+ static int smbiod(void *unused)
+ {
+-      MOD_INC_USE_COUNT;
+       daemonize("smbiod");
+       allow_signal(SIGKILL);
+@@ -330,6 +335,5 @@
+       }
+       VERBOSE("SMB Kernel thread exiting (%d) ...\n", current->pid);
+-      MOD_DEC_USE_COUNT;
+-      return 0;
++      module_put_and_exit(0);
+ }
+Index: linux-2.6.0-test5/fs/stat.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/stat.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/stat.c        2003-09-27 11:38:39.359544824 +0800
+@@ -117,13 +117,13 @@
+       }
+       memset(&tmp, 0, sizeof(struct __old_kernel_stat));
+-      tmp.st_dev = stat->dev;
++      tmp.st_dev = old_encode_dev(stat->dev);
+       tmp.st_ino = stat->ino;
+       tmp.st_mode = stat->mode;
+       tmp.st_nlink = stat->nlink;
+       SET_OLDSTAT_UID(tmp, stat->uid);
+       SET_OLDSTAT_GID(tmp, stat->gid);
+-      tmp.st_rdev = stat->rdev;
++      tmp.st_rdev = old_encode_dev(stat->rdev);
+ #if BITS_PER_LONG == 32
+       if (stat->size > MAX_NON_LFS)
+               return -EOVERFLOW;
+@@ -172,14 +172,30 @@
+ {
+       struct stat tmp;
++#if BITS_PER_LONG == 32
++      if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++#else
++      if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++#endif
++
+       memset(&tmp, 0, sizeof(tmp));
+-      tmp.st_dev = stat->dev;
++#if BITS_PER_LONG == 32
++      tmp.st_dev = old_encode_dev(stat->dev);
++#else
++      tmp.st_dev = new_encode_dev(stat->dev);
++#endif
+       tmp.st_ino = stat->ino;
+       tmp.st_mode = stat->mode;
+       tmp.st_nlink = stat->nlink;
+       SET_STAT_UID(tmp, stat->uid);
+       SET_STAT_GID(tmp, stat->gid);
+-      tmp.st_rdev = stat->rdev;
++#if BITS_PER_LONG == 32
++      tmp.st_rdev = old_encode_dev(stat->rdev);
++#else
++      tmp.st_rdev = new_encode_dev(stat->rdev);
++#endif
+ #if BITS_PER_LONG == 32
+       if (stat->size > MAX_NON_LFS)
+               return -EOVERFLOW;
+@@ -263,7 +279,16 @@
+       struct stat64 tmp;
+       memset(&tmp, 0, sizeof(struct stat64));
+-      tmp.st_dev = stat->dev;
++#ifdef CONFIG_MIPS
++      /* mips has weird padding, so we don't get 64 bits there */
++      if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
++              return -EOVERFLOW;
++      tmp.st_dev = new_encode_dev(stat->dev);
++      tmp.st_rdev = new_encode_dev(stat->rdev);
++#else
++      tmp.st_dev = huge_encode_dev(stat->dev);
++      tmp.st_rdev = huge_encode_dev(stat->rdev);
++#endif
+       tmp.st_ino = stat->ino;
+ #ifdef STAT64_HAS_BROKEN_ST_INO
+       tmp.__st_ino = stat->ino;
+@@ -272,7 +297,6 @@
+       tmp.st_nlink = stat->nlink;
+       tmp.st_uid = stat->uid;
+       tmp.st_gid = stat->gid;
+-      tmp.st_rdev = stat->rdev;
+       tmp.st_atime = stat->atime.tv_sec;
+       tmp.st_atime_nsec = stat->atime.tv_nsec;
+       tmp.st_mtime = stat->mtime.tv_sec;
+Index: linux-2.6.0-test5/fs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/super.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/super.c       2003-09-27 11:38:39.364544064 +0800
+@@ -405,14 +405,14 @@
+       return NULL;
+ }
+-asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf)
++asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
+ {
+         struct super_block *s;
+         struct ustat tmp;
+         struct kstatfs sbuf;
+       int err = -EINVAL;
+-        s = user_get_super(dev);
++        s = user_get_super(new_decode_dev(dev));
+         if (s == NULL)
+                 goto out;
+       err = vfs_statfs(s, &sbuf);
+Index: linux-2.6.0-test5/fs/sysfs/dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/dir.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/dir.c   2003-09-27 11:38:39.366543760 +0800
+@@ -21,32 +21,32 @@
+ }
+-static struct dentry * 
+-create_dir(struct kobject * k, struct dentry * p, const char * n)
++static int create_dir(struct kobject * k, struct dentry * p,
++                    const char * n, struct dentry ** d)
+ {
+-      struct dentry * dentry;
++      int error;
+       down(&p->d_inode->i_sem);
+-      dentry = sysfs_get_dentry(p,n);
+-      if (!IS_ERR(dentry)) {
+-              int error = sysfs_create(dentry,
++      *d = sysfs_get_dentry(p,n);
++      if (!IS_ERR(*d)) {
++              error = sysfs_create(*d,
+                                        S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO,
+                                        init_dir);
+               if (!error) {
+-                      dentry->d_fsdata = k;
++                      (*d)->d_fsdata = k;
+                       p->d_inode->i_nlink++;
+-              } else
+-                      dentry = ERR_PTR(error);
+-              dput(dentry);
+-      }
++              }
++              dput(*d);
++      } else
++              error = PTR_ERR(*d);
+       up(&p->d_inode->i_sem);
+-      return dentry;
++      return error;
+ }
+-struct dentry * sysfs_create_subdir(struct kobject * k, const char * n)
++int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
+ {
+-      return create_dir(k,k->dentry,n);
++      return create_dir(k,k->dentry,n,d);
+ }
+ /**
+@@ -71,11 +71,9 @@
+       else
+               return -EFAULT;
+-      dentry = create_dir(kobj,parent,kobject_name(kobj));
+-      if (!IS_ERR(dentry))
++      error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
++      if (!error)
+               kobj->dentry = dentry;
+-      else
+-              error = PTR_ERR(dentry);
+       return error;
+ }
+@@ -84,8 +82,16 @@
+ {
+       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));
+Index: linux-2.6.0-test5/fs/sysfs/file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/file.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/file.c  2003-09-27 11:38:39.369543304 +0800
+@@ -353,11 +353,11 @@
+       down(&dir->d_inode->i_sem);
+       dentry = sysfs_get_dentry(dir,attr->name);
+       if (!IS_ERR(dentry)) {
+-              error = sysfs_create(dentry,(attr->mode & S_IALLUGO) | S_IFREG,init_file);
++              error = sysfs_create(dentry,
++                                   (attr->mode & S_IALLUGO) | S_IFREG,
++                                   init_file);
+               if (!error)
+                       dentry->d_fsdata = (void *)attr;
+-              else
+-                      dentry = ERR_PTR(error);
+               dput(dentry);
+       } else
+               error = PTR_ERR(dentry);
+Index: linux-2.6.0-test5/fs/sysfs/group.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/group.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/group.c 2003-09-27 11:38:39.371543000 +0800
+@@ -46,9 +46,9 @@
+       int error;
+       if (grp->name) {
+-              dir = sysfs_create_subdir(kobj,grp->name);
+-              if (IS_ERR(dir))
+-                      return PTR_ERR(dir);
++              error = sysfs_create_subdir(kobj,grp->name,&dir);
++              if (error)
++                      return error;
+       } else
+               dir = kobj->dentry;
+       dir = dget(dir);
+Index: linux-2.6.0-test5/fs/sysfs/sysfs.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/sysfs/sysfs.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/sysfs/sysfs.h 2003-09-27 11:38:39.372542848 +0800
+@@ -9,5 +9,5 @@
+ extern int sysfs_add_file(struct dentry * dir, const struct attribute * attr);
+ extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
+-extern struct dentry * sysfs_create_subdir(struct kobject *, const char *);
++extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
+ extern void sysfs_remove_subdir(struct dentry *);
+Index: linux-2.6.0-test5/fs/udf/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/udf/super.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/udf/super.c   2003-09-27 11:38:39.386540720 +0800
+@@ -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>
+@@ -225,7 +226,7 @@
+  *    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 +260,53 @@
+  *    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 +322,106 @@
+       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;
+               }
+       }
+Index: linux-2.6.0-test5/fs/ufs/namei.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ufs/namei.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/ufs/namei.c   2003-09-27 11:38:39.389540264 +0800
+@@ -112,11 +112,13 @@
+ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
+ {
+-      struct inode * inode;
++      struct inode *inode;
++      int err;
++
+       if (!old_valid_dev(rdev))
+               return -EINVAL;
+       inode = ufs_new_inode(dir, mode);
+-      int err = PTR_ERR(inode);
++      err = PTR_ERR(inode);
+       if (!IS_ERR(inode)) {
+               init_special_inode(inode, mode, rdev);
+               /* NOTE: that'll go when we get wide dev_t */
+Index: linux-2.6.0-test5/fs/ufs/super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/ufs/super.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/ufs/super.c   2003-09-27 11:38:39.397539048 +0800
+@@ -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 @@
+               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;
+               }
+       }
+Index: linux-2.6.0-test5/fs/xattr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xattr.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xattr.c       2003-09-27 11:38:39.400538592 +0800
+@@ -53,7 +53,8 @@
+  * Extended attribute SET operations
+  */
+ static long
+-setxattr(struct dentry *d, char *name, void *value, size_t size, int flags)
++setxattr(struct dentry *d, char __user *name, void __user *value,
++       size_t size, int flags)
+ {
+       int error;
+       void *kvalue;
+@@ -94,7 +95,8 @@
+ }
+ asmlinkage long
+-sys_setxattr(char *path, char *name, void *value, size_t size, int flags)
++sys_setxattr(char __user *path, char __user *name, void __user *value,
++           size_t size, int flags)
+ {
+       struct nameidata nd;
+       int error;
+@@ -108,7 +110,8 @@
+ }
+ asmlinkage long
+-sys_lsetxattr(char *path, char *name, void *value, size_t size, int flags)
++sys_lsetxattr(char __user *path, char __user *name, void __user *value,
++            size_t size, int flags)
+ {
+       struct nameidata nd;
+       int error;
+@@ -122,7 +125,8 @@
+ }
+ asmlinkage long
+-sys_fsetxattr(int fd, char *name, void *value, size_t size, int flags)
++sys_fsetxattr(int fd, char __user *name, void __user *value,
++            size_t size, int flags)
+ {
+       struct file *f;
+       int error = -EBADF;
+@@ -139,7 +143,7 @@
+  * Extended attribute GET operations
+  */
+ static ssize_t
+-getxattr(struct dentry *d, char *name, void *value, size_t size)
++getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
+ {
+       ssize_t error;
+       void *kvalue;
+@@ -172,7 +176,8 @@
+ }
+ asmlinkage ssize_t
+-sys_getxattr(char *path, char *name, void *value, size_t size)
++sys_getxattr(char __user *path, char __user *name, void __user *value,
++           size_t size)
+ {
+       struct nameidata nd;
+       ssize_t error;
+@@ -186,7 +191,8 @@
+ }
+ asmlinkage ssize_t
+-sys_lgetxattr(char *path, char *name, void *value, size_t size)
++sys_lgetxattr(char __user *path, char __user *name, void __user *value,
++            size_t size)
+ {
+       struct nameidata nd;
+       ssize_t error;
+@@ -200,7 +206,7 @@
+ }
+ asmlinkage ssize_t
+-sys_fgetxattr(int fd, char *name, void *value, size_t size)
++sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
+ {
+       struct file *f;
+       ssize_t error = -EBADF;
+@@ -217,7 +223,7 @@
+  * Extended attribute LIST operations
+  */
+ static ssize_t
+-listxattr(struct dentry *d, char *list, size_t size)
++listxattr(struct dentry *d, char __user *list, size_t size)
+ {
+       ssize_t error;
+       char *klist;
+@@ -243,7 +249,7 @@
+ }
+ asmlinkage ssize_t
+-sys_listxattr(char *path, char *list, size_t size)
++sys_listxattr(char __user *path, char __user *list, size_t size)
+ {
+       struct nameidata nd;
+       ssize_t error;
+@@ -257,7 +263,7 @@
+ }
+ asmlinkage ssize_t
+-sys_llistxattr(char *path, char *list, size_t size)
++sys_llistxattr(char __user *path, char __user *list, size_t size)
+ {
+       struct nameidata nd;
+       ssize_t error;
+@@ -271,7 +277,7 @@
+ }
+ asmlinkage ssize_t
+-sys_flistxattr(int fd, char *list, size_t size)
++sys_flistxattr(int fd, char __user *list, size_t size)
+ {
+       struct file *f;
+       ssize_t error = -EBADF;
+@@ -288,7 +294,7 @@
+  * Extended attribute REMOVE operations
+  */
+ static long
+-removexattr(struct dentry *d, char *name)
++removexattr(struct dentry *d, char __user *name)
+ {
+       int error;
+       char kname[XATTR_NAME_MAX + 1];
+@@ -313,7 +319,7 @@
+ }
+ asmlinkage long
+-sys_removexattr(char *path, char *name)
++sys_removexattr(char __user *path, char __user *name)
+ {
+       struct nameidata nd;
+       int error;
+@@ -327,7 +333,7 @@
+ }
+ asmlinkage long
+-sys_lremovexattr(char *path, char *name)
++sys_lremovexattr(char __user *path, char __user *name)
+ {
+       struct nameidata nd;
+       int error;
+@@ -341,7 +347,7 @@
+ }
+ asmlinkage long
+-sys_fremovexattr(int fd, char *name)
++sys_fremovexattr(int fd, char __user *name)
+ {
+       struct file *f;
+       int error = -EBADF;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_aops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_aops.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_aops.c  2003-09-27 11:38:39.409537224 +0800
+@@ -225,7 +225,8 @@
+       page_buf_bmap_t         *mp,
+       page_buf_t              *pb,
+       unsigned long           max_offset,
+-      unsigned long           *fsbs)
++      unsigned long           *fsbs,
++      unsigned int            bbits)
+ {
+       struct page             *page;
+@@ -248,6 +249,7 @@
+                               break;
+                       if (p_offset >= max_offset)
+                               break;
++                      map_buffer_at_offset(page, bh, p_offset, bbits, mp);
+                       set_buffer_unwritten_io(bh);
+                       bh->b_private = pb;
+                       p_offset += bh->b_size;
+@@ -455,13 +457,14 @@
+       if (bh == head) {
+               struct address_space    *mapping = inode->i_mapping;
+               unsigned long           tindex, tloff, tlast, bs;
++              unsigned int            bbits = inode->i_blkbits;
+               struct page             *page;
+               tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
+               tloff = min(tlast, start_page->index + pb->pb_page_count - 1);
+               for (tindex = start_page->index + 1; tindex < tloff; tindex++) {
+                       page = probe_unwritten_page(mapping, tindex, mp, pb,
+-                                                      PAGE_CACHE_SIZE, &bs);
++                                              PAGE_CACHE_SIZE, &bs, bbits);
+                       if (!page)
+                               break;
+                       nblocks += bs;
+@@ -472,7 +475,7 @@
+               if (tindex == tlast &&
+                   (tloff = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)))) {
+                       page = probe_unwritten_page(mapping, tindex, mp, pb,
+-                                                      tloff, &bs);
++                                                      tloff, &bs, bbits);
+                       if (page) {
+                               nblocks += bs;
+                               atomic_add(bs, &pb->pb_io_remaining);
+@@ -560,7 +563,8 @@
+               offset = i << bbits;
+               if (!(PageUptodate(page) || buffer_uptodate(bh)))
+                       continue;
+-              if (buffer_mapped(bh) && !buffer_delay(bh) && all_bh) {
++              if (buffer_mapped(bh) && all_bh &&
++                  !buffer_unwritten(bh) && !buffer_delay(bh)) {
+                       if (startio && (offset < end)) {
+                               lock_buffer(bh);
+                               bh_arr[index++] = bh;
+@@ -581,7 +585,7 @@
+                       ASSERT(tmp->pbm_flags & PBMF_UNWRITTEN);
+                       map_unwritten(inode, page, head, bh,
+                                               offset, bbits, tmp, all_bh);
+-              } else {
++              } else if (! (buffer_unwritten(bh) && buffer_locked(bh))) {
+                       map_buffer_at_offset(page, bh, offset, bbits, tmp);
+                       if (buffer_unwritten(bh)) {
+                               set_buffer_unwritten_io(bh);
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_file.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_file.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_file.c  2003-09-27 11:38:39.412536768 +0800
+@@ -94,6 +94,8 @@
+       BUG_ON(iocb->ki_pos != pos);
+       if (direct) {
++              down_read(&inode->i_alloc_sem);
++              down(&inode->i_sem);
+               VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, NULL, error);
+       } else {
+               down(&inode->i_sem);
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_globals.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_globals.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_globals.c       2003-09-27 11:38:39.413536616 +0800
+@@ -59,6 +59,9 @@
+       .error_level    = {     0,      3,      11      },
+       .sync_interval  = {     HZ,     30*HZ,  60*HZ   },
+       .stats_clear    = {     0,      0,      1       },
++      .inherit_sync   = {     0,      1,      1       },
++      .inherit_nodump = {     0,      1,      1       },
++      .inherit_noatim = {     0,      1,      1       },
+ };
+ /*
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_ioctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_ioctl.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_ioctl.c 2003-09-27 11:38:39.420535552 +0800
+@@ -72,6 +72,13 @@
+ #include <linux/namei.h>
+ #include <linux/pagemap.h>
++/*
++ * ioctl commands that are used by Linux filesystems
++ */
++#define XFS_IOC_GETXFLAGS     _IOR('f', 1, long)
++#define XFS_IOC_SETXFLAGS     _IOW('f', 2, long)
++#define XFS_IOC_GETVERSION    _IOR('v', 1, long)
++
+ /*
+  * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
+@@ -328,6 +335,17 @@
+       if (permflag & O_TRUNC)
+               permflag |= 2;
++      if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
++          (permflag & FMODE_WRITE) && IS_APPEND(inode)) {
++              iput(inode);
++              return -XFS_ERROR(EPERM);
++      }
++
++      if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
++              iput(inode);
++              return -XFS_ERROR(EACCES);
++      }
++
+       /* Can't write directories. */
+       if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
+               iput(inode);
+@@ -429,6 +447,11 @@
+       if (error)
+               return -error;
++      if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
++              VN_RELE(vp);
++              return -XFS_ERROR(EPERM);
++      }
++
+       if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
+               VN_RELE(vp);
+               return -XFS_ERROR(EFAULT);
+@@ -514,11 +537,19 @@
+                                       NULL, ops[i].am_error);
+                       break;
+               case ATTR_OP_SET:
++                      if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
++                              ops[i].am_error = EPERM;
++                              break;
++                      }
+                       VOP_ATTR_SET(vp,ops[i].am_attrname, ops[i].am_attrvalue,
+                                       ops[i].am_length, ops[i].am_flags,
+                                       NULL, ops[i].am_error);
+                       break;
+               case ATTR_OP_REMOVE:
++                      if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
++                              ops[i].am_error = EPERM;
++                              break;
++                      }
+                       VOP_ATTR_REMOVE(vp, ops[i].am_attrname, ops[i].am_flags,
+                                       NULL, ops[i].am_error);
+                       break;
+@@ -566,6 +597,7 @@
+ STATIC int
+ xfs_ioc_xattr(
+       vnode_t                 *vp,
++      xfs_inode_t             *ip,
+       struct file             *filp,
+       unsigned int            cmd,
+       unsigned long           arg);
+@@ -648,10 +680,13 @@
+       case XFS_IOC_FSGEOMETRY:
+               return xfs_ioc_fsgeometry(mp, arg);
++      case XFS_IOC_GETVERSION:
++      case XFS_IOC_GETXFLAGS:
++      case XFS_IOC_SETXFLAGS:
+       case XFS_IOC_FSGETXATTR:
+       case XFS_IOC_FSSETXATTR:
+       case XFS_IOC_FSGETXATTRA:
+-              return xfs_ioc_xattr(vp, filp, cmd, arg);
++              return xfs_ioc_xattr(vp, ip, filp, cmd, arg);
+       case XFS_IOC_FSSETDM: {
+               struct fsdmidata        dmi;
+@@ -837,6 +872,9 @@
+       int                     attr_flags = 0;
+       int                     error;
++      if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
++              return -XFS_ERROR(EPERM);
++
+       if (filp->f_flags & O_RDONLY)
+               return -XFS_ERROR(EBADF);
+@@ -957,9 +995,50 @@
+       return 0;
+ }
++/*
++ * Linux extended inode flags interface.
++ */
++#define LINUX_XFLAG_SYNC      0x00000008 /* Synchronous updates */
++#define LINUX_XFLAG_IMMUTABLE 0x00000010 /* Immutable file */
++#define LINUX_XFLAG_APPEND    0x00000020 /* writes to file may only append */
++#define LINUX_XFLAG_NODUMP    0x00000040 /* do not dump file */
++#define LINUX_XFLAG_NOATIME   0x00000080 /* do not update atime */
++
++STATIC unsigned int
++xfs_merge_ioc_xflags(
++      unsigned int    flags,
++      unsigned int    start)
++{
++      unsigned int    xflags = start;
++
++      if (flags & LINUX_XFLAG_IMMUTABLE)
++              xflags |= XFS_XFLAG_IMMUTABLE;
++      else
++              xflags &= ~XFS_XFLAG_IMMUTABLE;
++      if (flags & LINUX_XFLAG_APPEND)
++              xflags |= XFS_XFLAG_APPEND;
++      else
++              xflags &= ~XFS_XFLAG_APPEND;
++      if (flags & LINUX_XFLAG_SYNC)
++              xflags |= XFS_XFLAG_SYNC;
++      else
++              xflags &= ~XFS_XFLAG_SYNC;
++      if (flags & LINUX_XFLAG_NOATIME)
++              xflags |= XFS_XFLAG_NOATIME;
++      else
++              xflags &= ~XFS_XFLAG_NOATIME;
++      if (flags & LINUX_XFLAG_NODUMP)
++              xflags |= XFS_XFLAG_NODUMP;
++      else
++              xflags &= ~XFS_XFLAG_NODUMP;
++
++      return xflags;
++}
++
+ STATIC int
+ xfs_ioc_xattr(
+       vnode_t                 *vp,
++      xfs_inode_t             *ip,
+       struct file             *filp,
+       unsigned int            cmd,
+       unsigned long           arg)
+@@ -967,6 +1046,8 @@
+       struct fsxattr          fa;
+       vattr_t                 va;
+       int                     error;
++      int                     attr_flags;
++      unsigned int            flags;
+       switch (cmd) {
+       case XFS_IOC_FSGETXATTR: {
+@@ -985,24 +1066,24 @@
+       }
+       case XFS_IOC_FSSETXATTR: {
+-              int             attr_flags = 0;
+-
+               if (copy_from_user(&fa, (struct fsxattr *)arg, sizeof(fa)))
+                       return -XFS_ERROR(EFAULT);
++              attr_flags = 0;
++              if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
++                      attr_flags |= ATTR_NONBLOCK;
++
+               va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE;
+               va.va_xflags  = fa.fsx_xflags;
+               va.va_extsize = fa.fsx_extsize;
+-              if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
+-                      attr_flags |= ATTR_NONBLOCK;
+-
+               VOP_SETATTR(vp, &va, attr_flags, NULL, error);
++              if (!error)
++                      vn_revalidate(vp);      /* update Linux inode flags */
+               return -error;
+       }
+       case XFS_IOC_FSGETXATTRA: {
+-
+               va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS;
+               VOP_GETATTR(vp, &va, 0, NULL, error);
+               if (error)
+@@ -1017,9 +1098,54 @@
+               return 0;
+       }
++      case XFS_IOC_GETXFLAGS: {
++              flags = 0;
++              if (ip->i_d.di_flags & XFS_XFLAG_IMMUTABLE)
++                      flags |= LINUX_XFLAG_IMMUTABLE;
++              if (ip->i_d.di_flags & XFS_XFLAG_APPEND)
++                      flags |= LINUX_XFLAG_APPEND;
++              if (ip->i_d.di_flags & XFS_XFLAG_SYNC)
++                      flags |= LINUX_XFLAG_SYNC;
++              if (ip->i_d.di_flags & XFS_XFLAG_NOATIME)
++                      flags |= LINUX_XFLAG_NOATIME;
++              if (ip->i_d.di_flags & XFS_XFLAG_NODUMP)
++                      flags |= LINUX_XFLAG_NODUMP;
++              if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
++                      return -XFS_ERROR(EFAULT);
++              return 0;
++      }
++
++      case XFS_IOC_SETXFLAGS: {
++              if (copy_from_user(&flags, (unsigned int *)arg, sizeof(flags)))
++                      return -XFS_ERROR(EFAULT);
++
++              if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \
++                            LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \
++                            LINUX_XFLAG_SYNC))
++                      return -XFS_ERROR(EOPNOTSUPP);
++
++              attr_flags = 0;
++              if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
++                      attr_flags |= ATTR_NONBLOCK;
++
++              va.va_mask = XFS_AT_XFLAGS;
++              va.va_xflags = xfs_merge_ioc_xflags(flags, ip->i_d.di_flags);
++
++              VOP_SETATTR(vp, &va, attr_flags, NULL, error);
++              if (!error)
++                      vn_revalidate(vp);      /* update Linux inode flags */
++              return -error;
++      }
++
++      case XFS_IOC_GETVERSION: {
++              flags = LINVFS_GET_IP(vp)->i_generation;
++              if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
++                      return -XFS_ERROR(EFAULT);
++              return 0;
++      }
++
+       default:
+               return -ENOTTY;
+-
+       }
+ }
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_iomap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_iomap.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_iomap.c 2003-09-27 11:38:39.426534640 +0800
+@@ -156,7 +156,7 @@
+               if (flags & BMAP_IGNSTATE)
+                       bmap_flags |= XFS_BMAPI_IGSTATE;
+               break;
+-      case PBF_WRITE:
++      case BMAP_WRITE:
+               lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR;
+               bmap_flags = 0;
+               XFS_ILOCK(mp, io, lockmode);
+@@ -598,7 +598,7 @@
+       count_fsb = map->br_blockcount;
+       map_start_fsb = offset_fsb;
+-      XFS_STATS_ADD(xfsstats.xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
++      XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
+       while (count_fsb != 0) {
+               /*
+@@ -689,7 +689,7 @@
+                                                imap[i].br_blockcount))) {
+                               *map = imap[i];
+                               *retmap = 1;
+-                              XFS_STATS_INC(xfsstats.xs_xstrat_quick);
++                              XFS_STATS_INC(xs_xstrat_quick);
+                               return 0;
+                       }
+                       count_fsb -= imap[i].br_blockcount;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_iops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_iops.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_iops.c  2003-09-27 11:38:39.431533880 +0800
+@@ -113,7 +113,11 @@
+       xattr_exists_t  test_default_acl = _ACL_DEFAULT_EXISTS;
+       int             error;
+-      if (!old_valid_dev(rdev))
++      /*
++       * Irix uses Missed'em'V split, but doesn't want to see
++       * the upper 5 bits of (14bit) major.
++       */
++      if (!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)
+               return -EINVAL;
+       if (test_default_acl && test_default_acl(dvp)) {
+@@ -135,7 +139,7 @@
+       switch (mode & S_IFMT) {
+       case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
+-              va.va_rdev = XFS_MKDEV(MAJOR(rdev), MINOR(rdev));
++              va.va_rdev = sysv_encode_dev(rdev);
+               va.va_mask |= XFS_AT_RDEV;
+               /*FALLTHROUGH*/
+       case S_IFREG:
+@@ -638,6 +642,9 @@
+               return error;
+       }
++      if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++              return -EPERM;
++
+       /* Convert Linux syscall to XFS internal ATTR flags */
+       if (flags & XATTR_CREATE)
+               xflags |= ATTR_CREATE;
+@@ -787,6 +794,9 @@
+               return error;
+       }
++        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++              return -EPERM;
++
+       if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
+                       xfs_namespaces[ROOT_NAMES].namelen) == 0) {
+               if (!capable(CAP_SYS_ADMIN))
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_linux.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_linux.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_linux.h 2003-09-27 11:38:39.435533272 +0800
+@@ -96,6 +96,9 @@
+ #define xfs_error_level               xfs_params.error_level.val
+ #define xfs_syncd_interval    xfs_params.sync_interval.val
+ #define xfs_stats_clear               xfs_params.stats_clear.val
++#define xfs_inherit_sync      xfs_params.inherit_sync.val
++#define xfs_inherit_nodump    xfs_params.inherit_nodump.val
++#define xfs_inherit_noatime   xfs_params.inherit_noatim.val
+ #define NBPP          PAGE_SIZE
+ #define DPPSHFT               (PAGE_SHIFT - 9)
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_lrw.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_lrw.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_lrw.c   2003-09-27 11:38:39.441532360 +0800
+@@ -167,7 +167,7 @@
+       mp = ip->i_mount;
+       vn_trace_entry(vp, "xfs_read", (inst_t *)__return_address);
+-      XFS_STATS_INC(xfsstats.xs_read_calls);
++      XFS_STATS_INC(xs_read_calls);
+       /* START copy & waste from filemap.c */
+       for (seg = 0; seg < segs; seg++) {
+@@ -231,7 +231,7 @@
+       xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+       if (ret > 0)
+-              XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
++              XFS_STATS_ADD(xs_read_bytes, ret);
+       if (!invisible)
+               xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
+@@ -261,7 +261,7 @@
+       mp = ip->i_mount;
+       vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
+-      XFS_STATS_INC(xfsstats.xs_read_calls);
++      XFS_STATS_INC(xs_read_calls);
+       n = XFS_MAXIOFFSET(mp) - *offset;
+       if ((n <= 0) || (count == 0))
+@@ -288,7 +288,7 @@
+       ret = generic_file_sendfile(filp, offset, count, actor, target);
+       xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+-      XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
++      XFS_STATS_ADD(xs_read_bytes, ret);
+       if (!invisible)
+               xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
+       return ret;
+@@ -537,7 +537,7 @@
+       int                     eventsent = 0;
+       vrwlock_t               locktype;
+-      XFS_STATS_INC(xfsstats.xs_write_calls);
++      XFS_STATS_INC(xs_write_calls);
+       vp = BHV_TO_VNODE(bdp);
+       vn_trace_entry(vp, "xfs_write", (inst_t *)__return_address);
+@@ -693,8 +693,8 @@
+           DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) && !invisible) {
+               xfs_rwunlock(bdp, locktype);
+-              error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, bdp,
+-                              DM_RIGHT_NULL, bdp, DM_RIGHT_NULL, NULL, NULL,
++              error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
++                              DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
+                               0, 0, 0); /* Delay flag intentionally  unused */
+               if (error)
+                       return -error;
+@@ -722,7 +722,7 @@
+               return ret;
+       }
+-      XFS_STATS_ADD(xfsstats.xs_write_bytes, ret);
++      XFS_STATS_ADD(xs_write_bytes, ret);
+       /* Handle various SYNC-type writes */
+       if ((file->f_flags & O_SYNC) || IS_SYNC(file->f_dentry->d_inode)) {
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_stats.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_stats.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_stats.c 2003-09-27 11:38:39.442532208 +0800
+@@ -80,6 +80,12 @@
+                       xfsstats.xs_xstrat_bytes,
+                       xfsstats.xs_write_bytes,
+                       xfsstats.xs_read_bytes);
++      len += sprintf(buffer + len, "debug %u\n",
++#if defined(XFSDEBUG)
++              1);
++#else
++              0);
++#endif
+       if (offset >= len) {
+               *start = buffer;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_stats.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_stats.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_stats.h 2003-09-27 11:38:39.445531752 +0800
+@@ -128,9 +128,9 @@
+ extern struct xfsstats xfsstats;
+-# define XFS_STATS_INC(count)         ( (count)++ )
+-# define XFS_STATS_DEC(count)         ( (count)-- )
+-# define XFS_STATS_ADD(count, inc)    ( (count) += (inc) )
++# define XFS_STATS_INC(count)         ( xfsstats.count++ )
++# define XFS_STATS_DEC(count)         ( xfsstats.count-- )
++# define XFS_STATS_ADD(count, inc)    ( xfsstats.count += (inc) )
+ extern void xfs_init_procfs(void);
+ extern void xfs_cleanup_procfs(void);
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_super.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_super.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_super.c 2003-09-27 11:38:39.450530992 +0800
+@@ -174,7 +174,7 @@
+               inode->i_rdev = 0;
+       } else {
+               xfs_dev_t dev = ip->i_df.if_u2.if_rdev;
+-              inode->i_rdev = XFS_DEV_TO_KDEVT(dev);
++              inode->i_rdev = MKDEV(sysv_major(dev) & 0x1ff, sysv_minor(dev));
+       }
+       inode->i_blksize = PAGE_CACHE_SIZE;
+       inode->i_generation = ip->i_d.di_gen;
+@@ -187,7 +187,22 @@
+       inode->i_mtime.tv_nsec  = ip->i_d.di_mtime.t_nsec;
+       inode->i_ctime.tv_sec   = ip->i_d.di_ctime.t_sec;
+       inode->i_ctime.tv_nsec  = ip->i_d.di_ctime.t_nsec;
+-
++      if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
++              inode->i_flags |= S_IMMUTABLE;
++      else
++              inode->i_flags &= ~S_IMMUTABLE;
++      if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
++              inode->i_flags |= S_APPEND;
++      else
++              inode->i_flags &= ~S_APPEND;
++      if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
++              inode->i_flags |= S_SYNC;
++      else
++              inode->i_flags &= ~S_SYNC;
++      if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
++              inode->i_flags |= S_NOATIME;
++      else
++              inode->i_flags &= ~S_NOATIME;
+       vp->v_flag &= ~VMODIFIED;
+ }
+@@ -300,8 +315,8 @@
+       if (set_blocksize(btp->pbr_bdev, sectorsize)) {
+               printk(KERN_WARNING
+-                      "XFS: Cannot set_blocksize to %u on device 0x%lx\n",
+-                      sectorsize, (unsigned long)btp->pbr_dev);
++                      "XFS: Cannot set_blocksize to %u on device %u:%u\n",
++                      sectorsize, MAJOR(btp->pbr_dev), MINOR(btp->pbr_dev));
+       }
+ }
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_super.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_super.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_super.h 2003-09-27 11:38:39.452530688 +0800
+@@ -66,8 +66,12 @@
+ # define XFS_REALTIME_STRING
+ #endif
+-#if XFS_BIG_FILESYSTEMS
+-# define XFS_BIGFS_STRING     "big filesystems, "
++#if XFS_BIG_BLKNOS
++# if XFS_BIG_INUMS
++#  define XFS_BIGFS_STRING    "large block/inode numbers, "
++# else
++#  define XFS_BIGFS_STRING    "large block numbers, "
++# endif
+ #else
+ # define XFS_BIGFS_STRING
+ #endif
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_sysctl.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.c        2003-09-27 11:38:39.454530384 +0800
+@@ -68,39 +68,54 @@
+ STATIC ctl_table xfs_table[] = {
+       {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL, 
+       &xfs_params.restrict_chown.min, &xfs_params.restrict_chown.max},
+       {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL,
+       &xfs_params.sgid_inherit.min, &xfs_params.sgid_inherit.max},
+       {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL, 
+       &xfs_params.symlink_mode.min, &xfs_params.symlink_mode.max},
+       {XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL, 
+       &xfs_params.panic_mask.min, &xfs_params.panic_mask.max},
+       {XFS_ERRLEVEL, "error_level", &xfs_params.error_level.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL, 
+       &xfs_params.error_level.min, &xfs_params.error_level.max},
+       {XFS_SYNC_INTERVAL, "sync_interval", &xfs_params.sync_interval.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL, 
+       &xfs_params.sync_interval.min, &xfs_params.sync_interval.max},
++      {XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
++      &sysctl_intvec, NULL,
++      &xfs_params.inherit_sync.min, &xfs_params.inherit_sync.max},
++
++      {XFS_INHERIT_NODUMP, "inherit_nodump", &xfs_params.inherit_nodump.val,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
++      &sysctl_intvec, NULL,
++      &xfs_params.inherit_nodump.min, &xfs_params.inherit_nodump.max},
++
++      {XFS_INHERIT_NOATIME, "inherit_noatime", &xfs_params.inherit_noatim.val,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
++      &sysctl_intvec, NULL,
++      &xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max},
++
+       /* please keep this the last entry */
+ #ifdef CONFIG_PROC_FS
+       {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
+-      sizeof(ulong), 0644, NULL, &xfs_stats_clear_proc_handler,
++      sizeof(int), 0644, NULL, &xfs_stats_clear_proc_handler,
+       &sysctl_intvec, NULL, 
+       &xfs_params.stats_clear.min, &xfs_params.stats_clear.max},
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_sysctl.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_sysctl.h        2003-09-27 11:38:39.455530232 +0800
+@@ -40,9 +40,9 @@
+  */
+ typedef struct xfs_sysctl_val {
+-      ulong min;
+-      ulong val;
+-      ulong max;
++      int min;
++      int val;
++      int max;
+ } xfs_sysctl_val_t;
+ typedef struct xfs_param {
+@@ -55,6 +55,9 @@
+       xfs_sysctl_val_t error_level;   /* Degree of reporting for problems  */
+       xfs_sysctl_val_t sync_interval; /* time between sync calls           */
+       xfs_sysctl_val_t stats_clear;   /* Reset all XFS statistics to zero. */
++      xfs_sysctl_val_t inherit_sync;  /* Inherit the "sync" inode flag. */
++      xfs_sysctl_val_t inherit_nodump;/* Inherit the "nodump" inode flag. */
++      xfs_sysctl_val_t inherit_noatim;/* Inherit the "noatime" inode flag. */
+ } xfs_param_t;
+ /*
+@@ -73,13 +76,16 @@
+  */
+ enum {
+-      XFS_RESTRICT_CHOWN = 1,
+-      XFS_SGID_INHERIT = 2,
+-      XFS_SYMLINK_MODE = 3,
+-      XFS_PANIC_MASK = 4,
+-      XFS_ERRLEVEL = 5,
+-      XFS_SYNC_INTERVAL = 6,
+-      XFS_STATS_CLEAR = 7,
++      XFS_RESTRICT_CHOWN = 3,
++      XFS_SGID_INHERIT = 4,
++      XFS_SYMLINK_MODE = 5,
++      XFS_PANIC_MASK = 6,
++      XFS_ERRLEVEL = 7,
++      XFS_SYNC_INTERVAL = 8,
++      XFS_STATS_CLEAR = 12,
++      XFS_INHERIT_SYNC = 13,
++      XFS_INHERIT_NODUMP = 14,
++      XFS_INHERIT_NOATIME = 15,
+ };
+ extern xfs_param_t    xfs_params;
+Index: linux-2.6.0-test5/fs/xfs/linux/xfs_vnode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/linux/xfs_vnode.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/linux/xfs_vnode.c 2003-09-27 11:38:39.459529624 +0800
+@@ -77,7 +77,7 @@
+ {
+       int             error;
+-      XFS_STATS_INC(xfsstats.vn_reclaim);
++      XFS_STATS_INC(vn_reclaim);
+       vn_trace_entry(vp, "vn_reclaim", (inst_t *)__return_address);
+       /*
+@@ -137,8 +137,8 @@
+ {
+       struct vnode    *vp = LINVFS_GET_VP(inode);
+-      XFS_STATS_INC(xfsstats.vn_active);
+-      XFS_STATS_INC(xfsstats.vn_alloc);
++      XFS_STATS_INC(vn_active);
++      XFS_STATS_INC(vn_alloc);
+       vp->v_flag = VMODIFIED;
+       spinlock_init(&vp->v_lock, "v_lock");
+@@ -172,7 +172,7 @@
+ {
+       struct inode    *inode;
+-      XFS_STATS_INC(xfsstats.vn_get);
++      XFS_STATS_INC(vn_get);
+       inode = LINVFS_GET_IP(vp);
+       if (inode->i_state & I_FREEING)
+               return NULL;
+@@ -200,7 +200,7 @@
+       vn_trace_entry(vp, "vn_revalidate", (inst_t *)__return_address);
+       ASSERT(vp->v_fbhv != NULL);
+-      va.va_mask = XFS_AT_STAT;
++      va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT;
+       VOP_GETATTR(vp, &va, 0, NULL, error);
+       if (!error) {
+               inode = LINVFS_GET_IP(vp);
+@@ -213,6 +213,22 @@
+               inode->i_ctime      = va.va_ctime;
+               inode->i_atime      = va.va_atime;
+               i_size_write(inode, va.va_size);
++              if (va.va_xflags & XFS_XFLAG_IMMUTABLE)
++                      inode->i_flags |= S_IMMUTABLE;
++              else
++                      inode->i_flags &= ~S_IMMUTABLE;
++              if (va.va_xflags & XFS_XFLAG_APPEND)
++                      inode->i_flags |= S_APPEND;
++              else
++                      inode->i_flags &= ~S_APPEND;
++              if (va.va_xflags & XFS_XFLAG_SYNC)
++                      inode->i_flags |= S_SYNC;
++              else
++                      inode->i_flags &= ~S_SYNC;
++              if (va.va_xflags & XFS_XFLAG_NOATIME)
++                      inode->i_flags |= S_NOATIME;
++              else
++                      inode->i_flags &= ~S_NOATIME;
+               VUNMODIFY(vp);
+       }
+       return -error;
+@@ -264,7 +280,7 @@
+               return;
+       }
+-      XFS_STATS_DEC(xfsstats.vn_active);
++      XFS_STATS_DEC(vn_active);
+       vp->v_flag |= VRECLM;
+       VN_UNLOCK(vp, 0);
+@@ -292,7 +308,7 @@
+ {
+       struct inode    *inode;
+-      XFS_STATS_INC(xfsstats.vn_hold);
++      XFS_STATS_INC(vn_hold);
+       VN_LOCK(vp);
+       inode = igrab(LINVFS_GET_IP(vp));
+@@ -312,7 +328,7 @@
+       int             vcnt;
+       int             cache;
+-      XFS_STATS_INC(xfsstats.vn_rele);
++      XFS_STATS_INC(vn_rele);
+       VN_LOCK(vp);
+@@ -364,7 +380,7 @@
+       if (!(vp->v_fbhv))
+               return;
+-      XFS_STATS_INC(xfsstats.vn_remove);
++      XFS_STATS_INC(vn_remove);
+       vn_trace_exit(vp, "vn_remove", (inst_t *)__return_address);
+       /*
+Index: linux-2.6.0-test5/fs/xfs/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/Makefile     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/Makefile  2003-09-27 11:38:39.461529320 +0800
+@@ -65,7 +65,6 @@
+ xfs-y                         += xfs_alloc.o \
+                                  xfs_alloc_btree.o \
+                                  xfs_attr.o \
+-                                 xfs_attr_fetch.o \
+                                  xfs_attr_leaf.o \
+                                  xfs_bit.o \
+                                  xfs_bmap.o \
+Index: linux-2.6.0-test5/fs/xfs/pagebuf/page_buf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/pagebuf/page_buf.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/pagebuf/page_buf.c        2003-09-27 11:38:39.473527496 +0800
+@@ -174,16 +174,13 @@
+ STATIC int
+ _bhash(
+-      dev_t           dev,
++      struct block_device *bdev,
+       loff_t          base)
+ {
+       int             bit, hval;
+       base >>= 9;
+-      /*
+-       * dev_t is 16 bits, loff_t is always 64 bits
+-       */
+-      base ^= dev;
++      base ^= (unsigned long)bdev / L1_CACHE_BYTES;
+       for (bit = hval = 0; base && bit < sizeof(base) * 8; bit += NBITS) {
+               hval ^= (int)base & (NHASH-1);
+               base >>= NBITS;
+@@ -619,7 +616,7 @@
+       /* Ensure we never do IOs that are not sector aligned */
+       BUG_ON(range_base & (loff_t)target->pbr_smask);
+-      hval = _bhash(target->pbr_bdev->bd_dev, range_base);
++      hval = _bhash(target->pbr_bdev, range_base);
+       h = &pbhash[hval];
+       spin_lock(&h->pb_hash_lock);
+@@ -1867,23 +1864,23 @@
+ STATIC ctl_table pagebuf_table[] = {
+       {PB_FLUSH_INT, "flush_int", &pb_params.flush_interval.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_ms_jiffies_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL,
+       &pb_params.flush_interval.min, &pb_params.flush_interval.max},
+       {PB_FLUSH_AGE, "flush_age", &pb_params.age_buffer.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_ms_jiffies_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL, 
+       &pb_params.age_buffer.min, &pb_params.age_buffer.max},
+       {PB_STATS_CLEAR, "stats_clear", &pb_params.stats_clear.val,
+-      sizeof(ulong), 0644, NULL, &pb_stats_clear_handler,
++      sizeof(int), 0644, NULL, &pb_stats_clear_handler,
+       &sysctl_intvec, NULL, 
+       &pb_params.stats_clear.min, &pb_params.stats_clear.max},
+ #ifdef PAGEBUF_TRACE
+       {PB_DEBUG, "debug", &pb_params.debug.val,
+-      sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
++      sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL, 
+       &pb_params.debug.min, &pb_params.debug.max},
+ #endif
+Index: linux-2.6.0-test5/fs/xfs/pagebuf/page_buf_internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/pagebuf/page_buf_internal.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/pagebuf/page_buf_internal.h       2003-09-27 11:38:39.475527192 +0800
+@@ -81,9 +81,9 @@
+  */
+ typedef struct pb_sysctl_val {
+-      ulong min;
+-      ulong val;
+-      ulong max;
++      int min;
++      int val;
++      int max;
+ } pb_sysctl_val_t;
+ typedef struct pagebuf_param {
+Index: linux-2.6.0-test5/fs/xfs/xfs_acl.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_acl.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_acl.c 2003-09-27 11:38:39.481526280 +0800
+@@ -388,6 +388,8 @@
+       vattr_t         va;
+       int             error;
++      if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
++              return EPERM;
+       if (kind == _ACL_TYPE_DEFAULT && vp->v_type != VDIR)
+               return ENOTDIR;
+       if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+Index: linux-2.6.0-test5/fs/xfs/xfs_alloc_btree.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_alloc_btree.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_alloc_btree.c 2003-09-27 11:38:39.499523544 +0800
+@@ -133,7 +133,7 @@
+               *stat = 0;
+               return 0;
+       }
+-      XFS_STATS_INC(xfsstats.xs_abt_delrec);
++      XFS_STATS_INC(xs_abt_delrec);
+       /*
+        * It's a nonleaf.  Excise the key and ptr being deleted, by
+        * sliding the entries past them down one.
+@@ -631,7 +631,7 @@
+        * and we're done.
+        */
+       if (level >= cur->bc_nlevels) {
+-              XFS_STATS_INC(xfsstats.xs_abt_insrec);
++              XFS_STATS_INC(xs_abt_insrec);
+               if ((error = xfs_alloc_newroot(cur, &i)))
+                       return error;
+               *bnop = NULLAGBLOCK;
+@@ -651,7 +651,7 @@
+               *stat = 0;
+               return 0;
+       }
+-      XFS_STATS_INC(xfsstats.xs_abt_insrec);
++      XFS_STATS_INC(xs_abt_insrec);
+       /*
+        * Get pointers to the btree buffer and block.
+        */
+@@ -951,7 +951,7 @@
+       int                     level;  /* level in the btree */
+       xfs_mount_t             *mp;    /* file system mount point */
+-      XFS_STATS_INC(xfsstats.xs_abt_lookup);
++      XFS_STATS_INC(xs_abt_lookup);
+       /*
+        * Get the allocation group header, and the root block number.
+        */
+@@ -1046,7 +1046,7 @@
+                               xfs_extlen_t    blockcount;     /* key value */
+                               xfs_agblock_t   startblock;     /* key value */
+-                              XFS_STATS_INC(xfsstats.xs_abt_compare);
++                              XFS_STATS_INC(xs_abt_compare);
+                               /*
+                                * keyno is average of low and high.
+                                */
+Index: linux-2.6.0-test5/fs/xfs/xfs_alloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_alloc.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_alloc.c       2003-09-27 11:38:39.518520656 +0800
+@@ -636,8 +636,8 @@
+                       xfs_trans_mod_sb(args->tp,
+                               args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS :
+                                       XFS_TRANS_SB_FDBLOCKS, -slen);
+-              XFS_STATS_INC(xfsstats.xs_allocx);
+-              XFS_STATS_ADD(xfsstats.xs_allocb, args->len);
++              XFS_STATS_INC(xs_allocx);
++              XFS_STATS_ADD(xs_allocb, args->len);
+       }
+       return 0;
+ }
+@@ -1781,8 +1781,8 @@
+               xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
+               if (!isfl)
+                       xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
+-              XFS_STATS_INC(xfsstats.xs_freex);
+-              XFS_STATS_ADD(xfsstats.xs_freeb, len);
++              XFS_STATS_INC(xs_freex);
++              XFS_STATS_ADD(xs_freeb, len);
+       }
+       TRACE_FREE(haveleft ?
+                       (haveright ? "both" : "left") :
+Index: linux-2.6.0-test5/fs/xfs/xfs_arch.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_arch.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_arch.h        2003-09-27 11:38:39.522520048 +0800
+@@ -32,8 +32,8 @@
+ #ifndef __XFS_ARCH_H__
+ #define __XFS_ARCH_H__
+-#ifndef XFS_BIG_FILESYSTEMS
+-#error XFS_BIG_FILESYSTEMS must be defined true or false
++#ifndef XFS_BIG_INUMS
++# error XFS_BIG_INUMS must be defined true or false
+ #endif
+ #ifdef __KERNEL__
+@@ -239,7 +239,7 @@
+           (INT_GET_UNALIGNED_32_BE(pointer)) \
+     )
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ #define DIRINO_GET_ARCH(pointer,arch) \
+     ( ((arch) == ARCH_NOCONVERT) \
+       ? \
+Index: linux-2.6.0-test5/fs/xfs/xfs_attr.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_attr.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_attr.c        2003-09-27 11:38:39.539517464 +0800
+@@ -116,37 +116,37 @@
+  *========================================================================*/
+ /*ARGSUSED*/
+-int                                                           /* error */
+-xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp,
+-           int flags, struct cred *cred)
++STATIC int
++xfs_attr_get_int(xfs_inode_t *ip, char *name, char *value, int *valuelenp,
++           int flags, int lock, struct cred *cred)
+ {
+       xfs_da_args_t   args;
+       int             error;
+       int             namelen;
+-      xfs_inode_t     *ip = XFS_BHVTOI(bdp);
+-      if (!name)
+-              return EINVAL;
+       ASSERT(MAXNAMELEN-1 <= 0xff);   /* length is stored in uint8 */
+       namelen = strlen(name);
+       if (namelen >= MAXNAMELEN)
+-              return EFAULT;          /* match IRIX behaviour */
+-      XFS_STATS_INC(xfsstats.xs_attr_get);
+-
+-      if (XFS_IFORK_Q(ip) == 0)
+-              return ENOATTR;
+-
++              return(EFAULT);         /* match IRIX behaviour */
++      XFS_STATS_INC(xs_attr_get);
+       if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+-              return (EIO);
++              return(EIO);
+-      /*
+-       * Do we answer them, or ignore them?
+-       */
+-      xfs_ilock(ip, XFS_ILOCK_SHARED);
+-      if ((error = xfs_iaccess(XFS_BHVTOI(bdp), IREAD, cred))) {
+-              xfs_iunlock(ip, XFS_ILOCK_SHARED);
+-              return(XFS_ERROR(error));
++      if ((XFS_IFORK_Q(ip) == 0) ||
++          (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
++           ip->i_d.di_anextents == 0))
++              return(ENOATTR);
++
++      if (lock) {
++              xfs_ilock(ip, XFS_ILOCK_SHARED);
++              /*
++               * Do we answer them, or ignore them?
++               */
++              if ((error = xfs_iaccess(ip, IREAD, cred))) {
++                      xfs_iunlock(ip, XFS_ILOCK_SHARED);
++                      return(XFS_ERROR(error));
++              }
+       }
+       /*
+@@ -177,7 +177,9 @@
+       } else {
+               error = xfs_attr_node_get(&args);
+       }
+-      xfs_iunlock(ip, XFS_ILOCK_SHARED);
++
++      if (lock)
++              xfs_iunlock(ip, XFS_ILOCK_SHARED);
+       /*
+        * Return the number of bytes in the value to the caller.
+@@ -189,6 +191,23 @@
+       return(error);
+ }
++int
++xfs_attr_fetch(xfs_inode_t *ip, char *name, char *value, int valuelen)
++{
++      return xfs_attr_get_int(ip, name, value, &valuelen, ATTR_ROOT, 0, NULL);
++}
++
++int
++xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp,
++           int flags, struct cred *cred)
++{
++      xfs_inode_t     *ip = XFS_BHVTOI(bdp);
++
++      if (!name)
++              return(EINVAL);
++      return xfs_attr_get_int(ip, name, value, valuelenp, flags, 1, cred);
++}
++
+ /*ARGSUSED*/
+ int                                                           /* error */
+ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
+@@ -210,7 +229,7 @@
+       if (namelen >= MAXNAMELEN)
+               return EFAULT; /* match irix behaviour */
+-      XFS_STATS_INC(xfsstats.xs_attr_set);
++      XFS_STATS_INC(xs_attr_set);
+       /*
+        * Do we answer them, or ignore them?
+        */
+@@ -468,7 +487,7 @@
+       if (namelen>=MAXNAMELEN)
+               return EFAULT; /* match irix behaviour */
+-      XFS_STATS_INC(xfsstats.xs_attr_remove);
++      XFS_STATS_INC(xs_attr_remove);
+       /*
+        * Do we answer them, or ignore them?
+@@ -620,7 +639,7 @@
+       xfs_inode_t *dp;
+       int error;
+-      XFS_STATS_INC(xfsstats.xs_attr_list);
++      XFS_STATS_INC(xs_attr_list);
+       /*
+        * Validate the cursor.
+@@ -1718,7 +1737,6 @@
+       int i;
+       state = xfs_da_state_alloc();
+-      state->holeok = 1;
+       state->args = args;
+       state->mp = args->dp->i_mount;
+       state->blocksize = state->mp->m_sb.sb_blocksize;
+Index: linux-2.6.0-test5/fs/xfs/xfs_bit.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bit.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bit.c 2003-09-27 11:38:39.542517008 +0800
+@@ -156,12 +156,12 @@
+ {
+       int n;
+       n = ffs((unsigned)v);
+-      if (n == 0) {
++      if (n <= 0) {
+               n = ffs(v >> 32);
+               if (n >= 0)
+                       n+=32;
+       }
+-      return n-1;
++      return (n <= 0) ? n : n-1;
+ }
+ /*
+Index: linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bmap_btree.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.c  2003-09-27 11:38:39.564513664 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2001 Silicon Graphics, Inc.  All Rights Reserved.
++ * Copyright (c) 2000-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
+@@ -392,7 +392,7 @@
+               *stat = 0;
+               return 0;
+       }
+-      XFS_STATS_INC(xfsstats.xs_bmbt_delrec);
++      XFS_STATS_INC(xs_bmbt_delrec);
+       if (level > 0) {
+               kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
+               pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
+@@ -784,7 +784,7 @@
+               *stat = 0;
+               return 0;
+       }
+-      XFS_STATS_INC(xfsstats.xs_bmbt_insrec);
++      XFS_STATS_INC(xs_bmbt_insrec);
+       block = xfs_bmbt_get_block(cur, level, &bp);
+       numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ #ifdef DEBUG
+@@ -1137,7 +1137,7 @@
+       xfs_fileoff_t           startoff;
+       xfs_trans_t             *tp;
+-      XFS_STATS_INC(xfsstats.xs_bmbt_lookup);
++      XFS_STATS_INC(xs_bmbt_lookup);
+       XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
+       XFS_BMBT_TRACE_ARGI(cur, (int)dir);
+       tp = cur->bc_tp;
+@@ -1182,7 +1182,7 @@
+                               return 0;
+                       }
+                       while (low <= high) {
+-                              XFS_STATS_INC(xfsstats.xs_bmbt_compare);
++                              XFS_STATS_INC(xs_bmbt_compare);
+                               keyno = (low + high) >> 1;
+                               if (level > 0) {
+                                       kkp = kkbase + keyno - 1;
+@@ -1899,7 +1899,7 @@
+       ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN));
+       s->br_startoff = ((xfs_fileoff_t)l0 &
+                          XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       s->br_startblock = (((xfs_fsblock_t)l0 & XFS_MASK64LO(9)) << 43) |
+                          (((xfs_fsblock_t)l1) >> 21);
+ #else
+@@ -1915,7 +1915,7 @@
+ #else /* !DEBUG */
+       s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21);
+ #endif        /* DEBUG */
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+       s->br_blockcount = (xfs_filblks_t)(l1 & XFS_MASK64LO(21));
+       /* This is xfs_extent_state() in-line */
+       if (ext_flag) {
+@@ -1976,7 +1976,7 @@
+ xfs_bmbt_get_startblock(
+       xfs_bmbt_rec_t  *r)
+ {
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) |
+              (((xfs_fsblock_t)r->l1) >> 21);
+ #else
+@@ -1990,7 +1990,7 @@
+ #else /* !DEBUG */
+       return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21);
+ #endif        /* DEBUG */
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+ }
+ /*
+@@ -2047,7 +2047,7 @@
+ xfs_bmbt_disk_get_startblock(
+       xfs_bmbt_rec_t  *r)
+ {
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       return (((xfs_fsblock_t)INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(9)) << 43) |
+              (((xfs_fsblock_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21);
+ #else
+@@ -2061,7 +2061,7 @@
+ #else /* !DEBUG */
+       return (xfs_fsblock_t)(((xfs_dfsbno_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21);
+ #endif        /* DEBUG */
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+ }
+ /*
+@@ -2472,17 +2472,15 @@
+       extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
+       ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
+       ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
+-#endif        /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+       r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+                ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+                ((xfs_bmbt_rec_base_t)s->br_startblock >> 43);
+       r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
+                ((xfs_bmbt_rec_base_t)s->br_blockcount &
+                (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+       if (ISNULLSTARTBLOCK(s->br_startblock)) {
+               r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+                       ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+@@ -2498,7 +2496,7 @@
+                         ((xfs_bmbt_rec_base_t)s->br_blockcount &
+                          (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+       }
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+ }
+ /*
+@@ -2518,17 +2516,15 @@
+       extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
+       ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
+       ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
+-#endif        /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+       r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+               ((xfs_bmbt_rec_base_t)o << 9) |
+               ((xfs_bmbt_rec_base_t)b >> 43);
+       r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
+               ((xfs_bmbt_rec_base_t)c &
+               (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+       if (ISNULLSTARTBLOCK(b)) {
+               r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+                       ((xfs_bmbt_rec_base_t)o << 9) |
+@@ -2544,7 +2540,7 @@
+                        ((xfs_bmbt_rec_base_t)c &
+                        (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+       }
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+ }
+ #if ARCH_CONVERT != ARCH_NOCONVERT
+@@ -2563,17 +2559,15 @@
+       extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
+       ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
+       ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
+-#endif        /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+       INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+                 ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+                 ((xfs_bmbt_rec_base_t)s->br_startblock >> 43));
+       INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
+                 ((xfs_bmbt_rec_base_t)s->br_blockcount &
+                  (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+       if (ISNULLSTARTBLOCK(s->br_startblock)) {
+               INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+                       ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
+@@ -2589,7 +2583,7 @@
+                         ((xfs_bmbt_rec_base_t)s->br_blockcount &
+                          (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+       }
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+ }
+ /*
+@@ -2609,17 +2603,15 @@
+       extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
+       ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
+       ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
+-#endif        /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+       INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+               ((xfs_bmbt_rec_base_t)o << 9) |
+               ((xfs_bmbt_rec_base_t)b >> 43));
+       INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
+                 ((xfs_bmbt_rec_base_t)c &
+                  (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+       if (ISNULLSTARTBLOCK(b)) {
+               INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+                       ((xfs_bmbt_rec_base_t)o << 9) |
+@@ -2635,7 +2627,7 @@
+                         ((xfs_bmbt_rec_base_t)c &
+                          (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+       }
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+ }
+ #endif
+@@ -2660,15 +2652,13 @@
+       xfs_bmbt_rec_t  *r,
+       xfs_fsblock_t   v)
+ {
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+       ASSERT((v & XFS_MASK64HI(12)) == 0);
+-#endif        /* XFS_BIG_FILESYSTEMS */
+-#if XFS_BIG_FILESYSTEMS
+       r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) |
+                 (xfs_bmbt_rec_base_t)(v >> 43);
+       r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) |
+                 (xfs_bmbt_rec_base_t)(v << 21);
+-#else /* !XFS_BIG_FILESYSTEMS */
++#else /* !XFS_BIG_BLKNOS */
+       if (ISNULLSTARTBLOCK(v)) {
+               r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
+               r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) |
+@@ -2679,7 +2669,7 @@
+               r->l1 = ((xfs_bmbt_rec_base_t)v << 21) |
+                         (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
+       }
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_BLKNOS */
+ }
+ /*
+Index: linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bmap_btree.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bmap_btree.h  2003-09-27 11:38:39.570512752 +0800
+@@ -108,7 +108,7 @@
+  * Values and macros for delayed-allocation startblock fields.
+  */
+ #define STARTBLOCKVALBITS     17
+-#define STARTBLOCKMASKBITS    (15 + XFS_BIG_FILESYSTEMS * 20)
++#define STARTBLOCKMASKBITS    (15 + XFS_BIG_BLKNOS * 20)
+ #define DSTARTBLOCKMASKBITS   (15 + 20)
+ #define STARTBLOCKMASK                \
+       (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
+Index: linux-2.6.0-test5/fs/xfs/xfs_bmap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_bmap.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_bmap.c        2003-09-27 11:38:39.617505608 +0800
+@@ -52,7 +52,6 @@
+ #include "xfs_dir_sf.h"
+ #include "xfs_dir2_sf.h"
+ #include "xfs_dinode.h"
+-#include "xfs_dmapi.h"
+ #include "xfs_inode_item.h"
+ #include "xfs_inode.h"
+ #include "xfs_itable.h"
+@@ -565,7 +564,7 @@
+       int                     logflags; /* returned value */
+       xfs_extnum_t            nextents; /* number of extents in file now */
+-      XFS_STATS_INC(xfsstats.xs_add_exlist);
++      XFS_STATS_INC(xs_add_exlist);
+       cur = *curp;
+       ifp = XFS_IFORK_PTR(ip, whichfork);
+       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+@@ -2837,7 +2836,7 @@
+       xfs_filblks_t           temp;   /* for indirect length calculations */
+       xfs_filblks_t           temp2;  /* for indirect length calculations */
+-      XFS_STATS_INC(xfsstats.xs_del_exlist);
++      XFS_STATS_INC(xs_del_exlist);
+       mp = ip->i_mount;
+       ifp = XFS_IFORK_PTR(ip, whichfork);
+       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+@@ -3462,7 +3461,7 @@
+               low = 0;
+               high = nextents - 1;
+               while (low <= high) {
+-                      XFS_STATS_INC(xfsstats.xs_cmp_exlist);
++                      XFS_STATS_INC(xs_cmp_exlist);
+                       lastx = (low + high) >> 1;
+                       ep = base + lastx;
+                       got.br_startoff = xfs_bmbt_get_startoff(ep);
+@@ -3532,7 +3531,7 @@
+       xfs_extnum_t    lastx;          /* last extent index used */
+       xfs_extnum_t    nextents;       /* extent list size */
+-      XFS_STATS_INC(xfsstats.xs_look_exlist);
++      XFS_STATS_INC(xs_look_exlist);
+       ifp = XFS_IFORK_PTR(ip, whichfork);
+       lastx = ifp->if_lastex;
+       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+@@ -4630,9 +4629,9 @@
+       ASSERT(ifp->if_ext_max ==
+              XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
+       if ((wr = (flags & XFS_BMAPI_WRITE)) != 0)
+-              XFS_STATS_INC(xfsstats.xs_blk_mapw);
++              XFS_STATS_INC(xs_blk_mapw);
+       else
+-              XFS_STATS_INC(xfsstats.xs_blk_mapr);
++              XFS_STATS_INC(xs_blk_mapr);
+       delay = (flags & XFS_BMAPI_DELAY) != 0;
+       trim = (flags & XFS_BMAPI_ENTIRE) == 0;
+       userdata = (flags & XFS_BMAPI_METADATA) == 0;
+@@ -5116,7 +5115,7 @@
+       }
+       if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+               return XFS_ERROR(EIO);
+-      XFS_STATS_INC(xfsstats.xs_blk_mapr);
++      XFS_STATS_INC(xs_blk_mapr);
+       if (!(ifp->if_flags & XFS_IFEXTENTS) &&
+           (error = xfs_iread_extents(tp, ip, whichfork)))
+               return error;
+@@ -5205,7 +5204,7 @@
+               *done = 1;
+               return 0;
+       }
+-      XFS_STATS_INC(xfsstats.xs_blk_unmap);
++      XFS_STATS_INC(xs_blk_unmap);
+       isrt = (whichfork == XFS_DATA_FORK) &&
+              (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);
+       start = bno;
+Index: linux-2.6.0-test5/fs/xfs/xfs_cap.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_cap.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_cap.c 2003-09-27 11:38:39.622504848 +0800
+@@ -192,6 +192,8 @@
+       if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+               return EROFS;
++      if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
++              return EPERM;
+       if ((error = _MAC_VACCESS(vp, NULL, VWRITE)))
+               return error;
+       va.va_mask = XFS_AT_UID;
+Index: linux-2.6.0-test5/fs/xfs/xfs_da_btree.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_da_btree.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_da_btree.c    2003-09-27 11:38:39.642501808 +0800
+@@ -1141,12 +1141,10 @@
+       xfs_da_node_entry_t *btree;
+       xfs_dablk_t blkno;
+       int probe, span, max, error, retval;
+-      xfs_daddr_t mappedbno;
+       xfs_dahash_t hashval;
+       xfs_da_args_t *args;
+       args = state->args;
+-      mappedbno = state->holeok ? -2 : -1;
+       /*
+        * Descend thru the B-tree searching each level for the right
+@@ -1164,9 +1162,7 @@
+                */
+               blk->blkno = blkno;
+               error = xfs_da_read_buf(args->trans, args->dp, blkno,
+-                                      mappedbno, &blk->bp, args->whichfork);
+-              if (!error && unlikely(state->holeok && !blk->bp))
+-                      error = XFS_ERROR(ENOATTR);     /* always attr here */
++                                      -1, &blk->bp, args->whichfork);
+               if (error) {
+                       blk->blkno = 0;
+                       state->path.active--;
+@@ -2170,9 +2166,9 @@
+                       if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
+                               int     i;
+                               cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n",
+-                                      bno);
++                                      (long long)bno);
+                               cmn_err(CE_ALERT, "dir: inode %lld\n",
+-                                      dp->i_ino);
++                                      (long long)dp->i_ino);
+                               for (i = 0; i < nmap; i++) {
+                                       cmn_err(CE_ALERT,
+                                               "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n",
+Index: linux-2.6.0-test5/fs/xfs/xfs_da_btree.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_da_btree.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_da_btree.h    2003-09-27 11:38:39.653500136 +0800
+@@ -189,10 +189,10 @@
+       int             index2;         /* index of 2nd attr in blk */
+       xfs_dablk_t     rmtblkno2;      /* remote attr value starting blkno */
+       int             rmtblkcnt2;     /* remote attr value block count */
+-      int             justcheck  : 1; /* T/F: check for ok with no space */
+-      int             rename     : 1; /* T/F: this is an atomic rename op */
+-      int             addname    : 1; /* T/F: this is an add operation */
+-      int             oknoent    : 1; /* T/F: ok to return ENOENT, else die */
++      unsigned char   justcheck;      /* T/F: check for ok with no space */
++      unsigned char   rename;         /* T/F: this is an atomic rename op */
++      unsigned char   addname;        /* T/F: this is an add operation */
++      unsigned char   oknoent;        /* T/F: ok to return ENOENT, else die */
+ } xfs_da_args_t;
+ /*
+@@ -252,10 +252,9 @@
+       unsigned int            node_ents;      /* how many entries in danode */
+       xfs_da_state_path_t     path;           /* search/split paths */
+       xfs_da_state_path_t     altpath;        /* alternate path for join */
+-      unsigned int            inleaf     : 1; /* insert into 1->lf, 0->splf */
+-      unsigned int            holeok     : 1; /* T/F: can deal with a hole */
+-      unsigned int            extravalid : 1; /* T/F: extrablk is in use */
+-      unsigned int            extraafter : 1; /* T/F: extrablk is after new */
++      unsigned char           inleaf;         /* insert into 1->lf, 0->splf */
++      unsigned char           extravalid;     /* T/F: extrablk is in use */
++      unsigned char           extraafter;     /* T/F: extrablk is after new */
+       xfs_da_state_blk_t      extrablk;       /* for double-splits on leafs */
+                                               /* for dirv2 extrablk is data */
+ } xfs_da_state_t;
+Index: linux-2.6.0-test5/fs/xfs/xfs_dinode.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dinode.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dinode.h      2003-09-27 11:38:39.658499376 +0800
+@@ -471,13 +471,21 @@
+  * There should be a one-to-one correspondence between these flags and the
+  * XFS_XFLAG_s.
+  */
+-#define XFS_DIFLAG_REALTIME_BIT       0       /* file's blocks come from rt area */
+-#define XFS_DIFLAG_PREALLOC_BIT       1       /* file space has been preallocated */
+-#define       XFS_DIFLAG_NEWRTBM_BIT  2       /* for rtbitmap inode, new format */
+-#define XFS_DIFLAG_REALTIME     (1 << XFS_DIFLAG_REALTIME_BIT)
+-#define XFS_DIFLAG_PREALLOC   (1 << XFS_DIFLAG_PREALLOC_BIT)
+-#define       XFS_DIFLAG_NEWRTBM      (1 << XFS_DIFLAG_NEWRTBM_BIT)
+-#define XFS_DIFLAG_ALL  \
+-      (XFS_DIFLAG_REALTIME|XFS_DIFLAG_PREALLOC|XFS_DIFLAG_NEWRTBM)
++#define XFS_DIFLAG_REALTIME_BIT  0    /* file's blocks come from rt area */
++#define XFS_DIFLAG_PREALLOC_BIT  1    /* file space has been preallocated */
++#define XFS_DIFLAG_NEWRTBM_BIT   2    /* for rtbitmap inode, new format */
++#define XFS_DIFLAG_IMMUTABLE_BIT 3    /* inode is immutable */
++#define XFS_DIFLAG_APPEND_BIT    4    /* inode is append-only */
++#define XFS_DIFLAG_SYNC_BIT      5    /* inode is written synchronously */
++#define XFS_DIFLAG_NOATIME_BIT   6    /* do not update atime */
++#define XFS_DIFLAG_NODUMP_BIT    7    /* do not dump */
++#define XFS_DIFLAG_REALTIME      (1 << XFS_DIFLAG_REALTIME_BIT)
++#define XFS_DIFLAG_PREALLOC      (1 << XFS_DIFLAG_PREALLOC_BIT)
++#define XFS_DIFLAG_NEWRTBM       (1 << XFS_DIFLAG_NEWRTBM_BIT)
++#define XFS_DIFLAG_IMMUTABLE     (1 << XFS_DIFLAG_IMMUTABLE_BIT)
++#define XFS_DIFLAG_APPEND        (1 << XFS_DIFLAG_APPEND_BIT)
++#define XFS_DIFLAG_SYNC          (1 << XFS_DIFLAG_SYNC_BIT)
++#define XFS_DIFLAG_NOATIME       (1 << XFS_DIFLAG_NOATIME_BIT)
++#define XFS_DIFLAG_NODUMP        (1 << XFS_DIFLAG_NODUMP_BIT)
+ #endif        /* __XFS_DINODE_H__ */
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_block.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_block.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_block.c  2003-09-27 11:38:39.668497856 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
++ * Copyright (c) 2000-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
+@@ -530,10 +530,9 @@
+               p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
+                                                   ptr - (char *)block);
+-#if XFS_BIG_FILESYSTEMS
+-              p.ino = INT_GET(dep->inumber, ARCH_CONVERT) + mp->m_inoadd;
+-#else
+               p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
++#if XFS_BIG_INUMS
++              p.ino += mp->m_inoadd;
+ #endif
+               p.name = (char *)dep->name;
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2.c        2003-09-27 11:38:39.674496944 +0800
+@@ -63,7 +63,6 @@
+ #include "xfs_dir2_leaf.h"
+ #include "xfs_dir2_block.h"
+ #include "xfs_dir2_node.h"
+-#include "xfs_dir2_sf.h"
+ #include "xfs_dir2_trace.h"
+ #include "xfs_error.h"
+ #include "xfs_bit.h"
+@@ -213,7 +212,7 @@
+       if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
+               return rval;
+       }
+-      XFS_STATS_INC(xfsstats.xs_dir_create);
++      XFS_STATS_INC(xs_dir_create);
+       /*
+        * Fill in the arg structure for this request.
+        */
+@@ -263,7 +262,7 @@
+       int             v;              /* type-checking value */
+       ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+-      XFS_STATS_INC(xfsstats.xs_dir_lookup);
++      XFS_STATS_INC(xs_dir_lookup);
+       /*
+        * Fill in the arg structure for this request.
+@@ -321,7 +320,7 @@
+       int             v;              /* type-checking value */
+       ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+-      XFS_STATS_INC(xfsstats.xs_dir_remove);
++      XFS_STATS_INC(xs_dir_remove);
+       /*
+        * Fill in the arg structure for this request.
+        */
+@@ -371,7 +370,7 @@
+       int             v;              /* type-checking value */
+       ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+-      XFS_STATS_INC(xfsstats.xs_dir_getdents);
++      XFS_STATS_INC(xs_dir_getdents);
+       /*
+        * If our caller has given us a single contiguous aligned memory buffer,
+        * just work directly within that buffer.  If it's in user memory,
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_leaf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_leaf.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_leaf.c   2003-09-27 11:38:39.689494664 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
++ * Copyright (c) 2000-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
+@@ -1118,10 +1118,9 @@
+               p.cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
+-#if XFS_BIG_FILESYSTEMS
+-              p.ino = INT_GET(dep->inumber, ARCH_CONVERT) + mp->m_inoadd;
+-#else
+               p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
++#if XFS_BIG_INUMS
++              p.ino += mp->m_inoadd;
+ #endif
+               p.name = (char *)dep->name;
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_node.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_node.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_node.c   2003-09-27 11:38:39.705492232 +0800
+@@ -1612,7 +1612,8 @@
+                       if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno) {
+                               cmn_err(CE_ALERT,
+               "xfs_dir2_node_addname_int: needed block %lld, got %lld\n",
+-                                      XFS_DIR2_DB_TO_FDB(mp, dbno), fbno);
++                                      (long long)XFS_DIR2_DB_TO_FDB(mp, dbno),
++                                      (long long)fbno);
+                               XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
+                                                XFS_ERRLEVEL_LOW, mp);
+                               return XFS_ERROR(EFSCORRUPTED);
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir2_sf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir2_sf.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir2_sf.c     2003-09-27 11:38:39.716490560 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
++ * Copyright (c) 2000-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
+@@ -79,10 +79,10 @@
+ #else
+ #define       xfs_dir2_sf_check(args)
+ #endif /* DEBUG */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ static void xfs_dir2_sf_toino4(xfs_da_args_t *args);
+ static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
+-#endif /* XFS_BIG_FILESYSTEMS */
++#endif /* XFS_BIG_INUMS */
+ /*
+  * Given a block directory (dp/block), calculate its size as a shortform (sf)
+@@ -136,7 +136,7 @@
+               isdotdot =
+                       dep->namelen == 2 &&
+                       dep->name[0] == '.' && dep->name[1] == '.';
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+               if (!isdot)
+                       i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM;
+ #endif
+@@ -324,7 +324,8 @@
+        */
+       add_entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen);
+       incr_isize = add_entsize;
+-#if XFS_BIG_FILESYSTEMS
++      objchange = 0;
++#if XFS_BIG_INUMS
+       /*
+        * Do we have to change to 8 byte inodes?
+        */
+@@ -340,10 +341,7 @@
+                       ((uint)sizeof(xfs_dir2_ino8_t) -
+                        (uint)sizeof(xfs_dir2_ino4_t));
+               objchange = 1;
+-      } else
+-              objchange = 0;
+-#else
+-      objchange = 0;
++      }
+ #endif
+       old_isize = (int)dp->i_d.di_size;
+       new_isize = old_isize + incr_isize;
+@@ -383,7 +381,7 @@
+        */
+       else {
+               ASSERT(pick == 2);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+               if (objchange)
+                       xfs_dir2_sf_toino8(args);
+ #endif
+@@ -437,7 +435,7 @@
+        * Update the header and inode.
+        */
+       sfp->hdr.count++;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       if (args->inumber > XFS_DIR2_MAX_SHORT_INUM)
+               sfp->hdr.i8count++;
+ #endif
+@@ -526,7 +524,7 @@
+       XFS_DIR2_SF_PUT_INUMBER_ARCH(sfp, &args->inumber,
+               XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT);
+       sfp->hdr.count++;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
+               sfp->hdr.i8count++;
+ #endif
+@@ -603,7 +601,7 @@
+       /*
+        * If changing the inode number size, do it the hard way.
+        */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       if (objchange) {
+               return 2;
+       }
+@@ -657,9 +655,7 @@
+                       XFS_DIR2_DATA_ENTSIZE(sfep->namelen);
+       }
+       ASSERT(i8count == sfp->hdr.i8count);
+-#if !XFS_BIG_FILESYSTEMS
+-      ASSERT(i8count == 0);
+-#endif
++      ASSERT(XFS_BIG_INUMS || i8count == 0);
+       ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
+       ASSERT(offset +
+              (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
+@@ -779,10 +775,9 @@
+                                              XFS_DIR2_DATA_DOT_OFFSET)) {
+               p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, 0,
+                                               XFS_DIR2_DATA_DOTDOT_OFFSET);
+-#if XFS_BIG_FILESYSTEMS
+-              p.ino = dp->i_ino + mp->m_inoadd;
+-#else
+               p.ino = dp->i_ino;
++#if XFS_BIG_INUMS
++              p.ino += mp->m_inoadd;
+ #endif
+               p.name = ".";
+               p.namelen = 1;
+@@ -805,11 +800,10 @@
+                                              XFS_DIR2_DATA_DOTDOT_OFFSET)) {
+               p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
+                                               XFS_DIR2_DATA_FIRST_OFFSET);
+-#if XFS_BIG_FILESYSTEMS
+-              p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent, ARCH_CONVERT) +
+-                      mp->m_inoadd;
+-#else
+-              p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent, ARCH_CONVERT);
++              p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent,
++                                              ARCH_CONVERT);
++#if XFS_BIG_INUMS
++              p.ino += mp->m_inoadd;
+ #endif
+               p.name = "..";
+               p.namelen = 2;
+@@ -843,13 +837,10 @@
+                       XFS_DIR2_SF_GET_OFFSET_ARCH(sfep, ARCH_CONVERT) +
+                       XFS_DIR2_DATA_ENTSIZE(p.namelen));
+-#if XFS_BIG_FILESYSTEMS
+-              p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp,
+-                              XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT) +
+-                      mp->m_inoadd;
+-#else
+               p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp,
+                               XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT);
++#if XFS_BIG_INUMS
++              p.ino += mp->m_inoadd;
+ #endif
+               p.name = (char *)sfep->name;
+@@ -1014,7 +1005,7 @@
+        */
+       xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK);
+       sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       /*
+        * Are we changing inode number size?
+        */
+@@ -1039,10 +1030,10 @@
+ {
+       xfs_inode_t             *dp;            /* incore directory inode */
+       int                     i;              /* entry index */
+-#if XFS_BIG_FILESYSTEMS || defined(DEBUG)
++#if XFS_BIG_INUMS || defined(DEBUG)
+       xfs_ino_t               ino=0;          /* entry old inode number */
+ #endif
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       int                     i8elevated;     /* sf_toino8 set i8count=1 */
+ #endif
+       xfs_dir2_sf_entry_t     *sfep;          /* shortform directory entry */
+@@ -1063,7 +1054,7 @@
+       ASSERT(dp->i_df.if_u1.if_data != NULL);
+       sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
+       ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count));
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       /*
+        * New inode number is large, and need to convert to 8-byte inodes.
+        */
+@@ -1101,7 +1092,7 @@
+        */
+       if (args->namelen == 2 &&
+           args->name[0] == '.' && args->name[1] == '.') {
+-#if XFS_BIG_FILESYSTEMS || defined(DEBUG)
++#if XFS_BIG_INUMS || defined(DEBUG)
+               ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent, ARCH_CONVERT);
+               ASSERT(args->inumber != ino);
+ #endif
+@@ -1117,7 +1108,7 @@
+                       if (sfep->namelen == args->namelen &&
+                           sfep->name[0] == args->name[0] &&
+                           memcmp(args->name, sfep->name, args->namelen) == 0) {
+-#if XFS_BIG_FILESYSTEMS || defined(DEBUG)
++#if XFS_BIG_INUMS || defined(DEBUG)
+                               ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp,
+                                       XFS_DIR2_SF_INUMBERP(sfep), ARCH_CONVERT);
+                               ASSERT(args->inumber != ino);
+@@ -1132,14 +1123,14 @@
+                */
+               if (i == sfp->hdr.count) {
+                       ASSERT(args->oknoent);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+                       if (i8elevated)
+                               xfs_dir2_sf_toino4(args);
+ #endif
+                       return XFS_ERROR(ENOENT);
+               }
+       }
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       /*
+        * See if the old number was large, the new number is small.
+        */
+@@ -1172,7 +1163,7 @@
+       return 0;
+ }
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ /*
+  * Convert from 8-byte inode numbers to 4-byte inode numbers.
+  * The last 8-byte inode number is gone, but the count is still 1.
+@@ -1325,4 +1316,4 @@
+       dp->i_d.di_size = newsize;
+       xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
+ }
+-#endif        /* XFS_BIG_FILESYSTEMS */
++#endif        /* XFS_BIG_INUMS */
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir.c 2003-09-27 11:38:39.725489192 +0800
+@@ -262,7 +262,7 @@
+       if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
+               return (retval);
+-      XFS_STATS_INC(xfsstats.xs_dir_create);
++      XFS_STATS_INC(xs_dir_create);
+       /*
+        * Fill in the arg structure for this request.
+        */
+@@ -367,7 +367,7 @@
+       int count, totallen, newsize, retval;
+       ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+-      XFS_STATS_INC(xfsstats.xs_dir_remove);
++      XFS_STATS_INC(xs_dir_remove);
+       /*
+        * Fill in the arg structure for this request.
+        */
+@@ -411,7 +411,7 @@
+       ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+-      XFS_STATS_INC(xfsstats.xs_dir_lookup);
++      XFS_STATS_INC(xs_dir_lookup);
+       /*
+        * Fill in the arg structure for this request.
+        */
+@@ -454,7 +454,7 @@
+       int  alignment, retval;
+       xfs_dir_put_t put;
+-      XFS_STATS_INC(xfsstats.xs_dir_getdents);
++      XFS_STATS_INC(xs_dir_getdents);
+       ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
+       /*
+Index: linux-2.6.0-test5/fs/xfs/xfs_dir_leaf.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_dir_leaf.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_dir_leaf.c    2003-09-27 11:38:39.743486456 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
++ * Copyright (c) 2000-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
+@@ -561,10 +561,9 @@
+               if (sbp->seqno == 0 || sbp == sbuf)
+                       lastresid = uio->uio_resid;
+               XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash);
+-#if XFS_BIG_FILESYSTEMS
+-              p.ino = sbp->ino + mp->m_inoadd;
+-#else
+               p.ino = sbp->ino;
++#if XFS_BIG_INUMS
++              p.ino += mp->m_inoadd;
+ #endif
+               p.name = sbp->name;
+               p.namelen = sbp->namelen;
+@@ -1835,7 +1834,6 @@
+       entry_d = &leaf_d->entries[start_d];
+       for (i = 0; i < count; entry_s++, entry_d++, i++) {
+               ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT));
+-              ASSERT(entry_s->namelen < MAXNAMELEN);
+               tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s);
+               INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp));
+               entry_d->hashval = entry_s->hashval; /* INT_: direct copy */
+@@ -2142,10 +2140,9 @@
+                * then restore the UIO to the first entry in the current
+                * run of equal-hashval entries (probably one 1 entry long).
+                */
+-#if XFS_BIG_FILESYSTEMS
+-              p.ino = XFS_GET_DIR_INO_ARCH(mp, namest->inumber, ARCH_CONVERT) + mp->m_inoadd;
+-#else
+               p.ino = XFS_GET_DIR_INO_ARCH(mp, namest->inumber, ARCH_CONVERT);
++#if XFS_BIG_INUMS
++              p.ino += mp->m_inoadd;
+ #endif
+               p.name = (char *)namest->name;
+               p.namelen = entry->namelen;
+Index: linux-2.6.0-test5/fs/xfs/xfs_error.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_error.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_error.c       2003-09-27 11:38:39.745486152 +0800
+@@ -238,7 +238,7 @@
+ }
+ void
+-xfs_cmn_err(uint64_t panic_tag, int level, xfs_mount_t *mp, char *fmt, ...)
++xfs_cmn_err(int panic_tag, int level, xfs_mount_t *mp, char *fmt, ...)
+ {
+       va_list ap;
+Index: linux-2.6.0-test5/fs/xfs/xfs_error.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_error.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_error.h       2003-09-27 11:38:39.748485696 +0800
+@@ -33,7 +33,7 @@
+ #define       __XFS_ERROR_H__
+ #define prdev(fmt,dev,args...) \
+-      printk("XFS: device 0x%x- " fmt "\n", (unsigned)dev, ## args)
++      printk("XFS: device %u:%u- " fmt "\n", MAJOR(dev), MINOR(dev), ## args)
+ #define XFS_ERECOVER  1       /* Failure to recover log */
+ #define XFS_ELOGSTAT  2       /* Failure to stat log in user space */
+@@ -177,18 +177,18 @@
+  *                    sysctl.  update xfs_max[XFS_PARAM] if
+  *                    more are added.
+  */
+-#define               XFS_NO_PTAG                     0LL
+-#define               XFS_PTAG_IFLUSH                 0x0000000000000001LL
+-#define               XFS_PTAG_LOGRES                 0x0000000000000002LL
+-#define               XFS_PTAG_AILDELETE              0x0000000000000004LL
+-#define               XFS_PTAG_ERROR_REPORT           0x0000000000000008LL
+-#define               XFS_PTAG_SHUTDOWN_CORRUPT       0x0000000000000010LL
+-#define               XFS_PTAG_SHUTDOWN_IOERROR       0x0000000000000020LL
+-#define               XFS_PTAG_SHUTDOWN_LOGERROR      0x0000000000000040LL
++#define               XFS_NO_PTAG                     0
++#define               XFS_PTAG_IFLUSH                 0x00000001
++#define               XFS_PTAG_LOGRES                 0x00000002
++#define               XFS_PTAG_AILDELETE              0x00000004
++#define               XFS_PTAG_ERROR_REPORT           0x00000008
++#define               XFS_PTAG_SHUTDOWN_CORRUPT       0x00000010
++#define               XFS_PTAG_SHUTDOWN_IOERROR       0x00000020
++#define               XFS_PTAG_SHUTDOWN_LOGERROR      0x00000040
+ struct xfs_mount;
+ /* PRINTFLIKE4 */
+-void          xfs_cmn_err(uint64_t panic_tag, int level, struct xfs_mount *mp,
++void          xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp,
+                           char *fmt, ...);
+ /* PRINTFLIKE3 */
+ void          xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
+Index: linux-2.6.0-test5/fs/xfs/xfs_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_fs.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_fs.h  2003-09-27 11:38:39.753484936 +0800
+@@ -69,12 +69,14 @@
+  * There should be a one-to-one correspondence between these flags and the
+  * XFS_DIFLAG_s.
+  */
+-#define XFS_XFLAG_REALTIME    0x00000001
+-#define XFS_XFLAG_PREALLOC    0x00000002
++#define XFS_XFLAG_REALTIME    0x00000001      /* data in realtime volume */
++#define XFS_XFLAG_PREALLOC    0x00000002      /* preallocated file extents */
++#define XFS_XFLAG_IMMUTABLE   0x00000008      /* file cannot be modified */
++#define XFS_XFLAG_APPEND      0x00000010      /* all writes append */
++#define XFS_XFLAG_SYNC                0x00000020      /* all writes synchronous */
++#define XFS_XFLAG_NOATIME     0x00000040      /* do not update access time */
++#define XFS_XFLAG_NODUMP      0x00000080      /* do not include in backups */
+ #define XFS_XFLAG_HASATTR     0x80000000      /* no DIFLAG for this   */
+-#define XFS_XFLAG_ALL         \
+-      ( XFS_XFLAG_REALTIME|XFS_XFLAG_PREALLOC|XFS_XFLAG_HASATTR )
+-
+ /*
+  * Structure for XFS_IOC_GETBMAP.
+Index: linux-2.6.0-test5/fs/xfs/xfs_fsops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_fsops.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_fsops.c       2003-09-27 11:38:39.758484176 +0800
+@@ -53,7 +53,6 @@
+ #include "xfs_rw.h"
+ #include "xfs_trans_space.h"
+ #include "xfs_rtalloc.h"
+-#include "xfs_dir.h"
+ #include "xfs_dir2.h"
+ #include "xfs_attr_sf.h"
+ #include "xfs_dir_sf.h"
+@@ -172,7 +171,7 @@
+               if (nb < mp->m_sb.sb_dblocks)
+                       return XFS_ERROR(EINVAL);
+       }
+-      new = in->newblocks - mp->m_sb.sb_dblocks;
++      new = nb - mp->m_sb.sb_dblocks;
+       oagcount = mp->m_sb.sb_agcount;
+       if (nagcount > oagcount) {
+               down_write(&mp->m_peraglock);
+Index: linux-2.6.0-test5/fs/xfs/xfs_ialloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_ialloc.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_ialloc.c      2003-09-27 11:38:39.768482656 +0800
+@@ -1114,7 +1114,7 @@
+       agbno = XFS_AGINO_TO_AGBNO(mp, agino);
+       if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
+           ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
+-#ifdef DEBUG
++#if 0
+               if (agno >= mp->m_sb.sb_agcount) {
+                       xfs_fs_cmn_err(CE_ALERT, mp,
+                                       "xfs_dilocate: agno (%d) >= "
+Index: linux-2.6.0-test5/fs/xfs/xfsidbg.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfsidbg.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfsidbg.c 2003-09-27 11:38:39.804477184 +0800
+@@ -78,7 +78,6 @@
+ #include "xfs_rw.h"
+ #include "xfs_bit.h"
+ #include "xfs_quota.h"
+-#include "xfs_log_recover.h"
+ #include "quota/xfs_qm.h"
+ MODULE_AUTHOR("Silicon Graphics, Inc.");
+@@ -1685,9 +1684,11 @@
+                                       ip->i_size);
+       kdb_printf(
+-              " i_mode = 0x%x  i_nlink = %d  i_rdev = 0x%x i_state = 0x%lx\n",
++              " i_mode = 0x%x  i_nlink = %d  i_rdev = %u:%u i_state = 0x%lx\n",
+                                       ip->i_mode, ip->i_nlink,
+-                                      ip->i_rdev, ip->i_state);
++                                      MAJOR(ip->i_rdev),
++                                      MINOR(ip->i_rdev),
++                                      ip->i_state);
+       kdb_printf(" i_hash.nxt = 0x%p i_hash.prv = 0x%p\n",
+                                       ip->i_hash.next, ip->i_hash.prev);
+@@ -3022,6 +3023,12 @@
+       static char *diflags[] = {
+               "realtime",             /* XFS_DIFLAG_REALTIME */
+               "prealloc",             /* XFS_DIFLAG_PREALLOC */
++              "newrtbm",              /* XFS_DIFLAG_NEWRTBM */
++              "immutable",            /* XFS_DIFLAG_IMMUTABLE */
++              "append",               /* XFS_DIFLAG_APPEND */
++              "sync",                 /* XFS_DIFLAG_SYNC */
++              "noatime",              /* XFS_DIFLAG_NOATIME */
++              "nodump",               /* XFS_DIFLAG_NODUMP */
+               NULL
+       };
+@@ -3732,8 +3739,9 @@
+               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 0x%x blkno 0x%x\n",
+-              dabuf->ra, dabuf->prev, dabuf->next, dabuf->dev, dabuf->blkno);
++      kdb_printf(" ra 0x%x prev 0x%x next 0x%x dev %u:%u blkno 0x%x\n",
++              dabuf->ra, dabuf->prev, dabuf->next,
++              MAJOR(dabuf->dev), MINOR(dabuf->dev), dabuf->blkno);
+ #endif
+ }
+@@ -4261,8 +4269,9 @@
+                       xfsidbg_get_cstate(log->l_covered_state));
+       kdb_printf("flags: ");
+       printflags(log->l_flags, t_flags,"log");
+-      kdb_printf("  dev: 0x%x logBBstart: %lld logsize: %d logBBsize: %d\n",
+-              log->l_dev, (long long) log->l_logBBstart,
++      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,
+               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,
+@@ -4637,11 +4646,14 @@
+               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 0x%x logdev 0x%x rtdev 0x%x\n",
++      kdb_printf("sb_lock 0x%p sb_bp 0x%p dev %u:%u logdev %u:%u rtdev %u:%u\n",
+               &mp->m_sb_lock, mp->m_sb_bp,
+-              mp->m_ddev_targp ? mp->m_ddev_targp->pbr_dev : 0,
+-              mp->m_logdev_targp ? mp->m_logdev_targp->pbr_dev : 0,
+-              mp->m_rtdev_targp ? mp->m_rtdev_targp->pbr_dev : 0);
++              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);
+       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);
+@@ -4687,7 +4699,7 @@
+               mp->m_attroffset, mp->m_maxicount, mp->m_inoalign_mask);
+       kdb_printf("resblks %Ld resblks_avail %Ld\n", mp->m_resblks,
+               mp->m_resblks_avail);
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       kdb_printf(" inoadd %llx\n", (unsigned long long) mp->m_inoadd);
+ #else
+       kdb_printf("\n");
+@@ -4812,8 +4824,9 @@
+               ip->i_mnext,
+               ip->i_mprev,
+               XFS_ITOV_NULL(ip));
+-      kdb_printf("dev %x ino %s\n",
+-              ip->i_mount->m_dev,
++      kdb_printf("dev %u:%u ino %s\n",
++              MAJOR(ip->i_mount->m_dev),
++              MINOR(ip->i_mount->m_dev),
+               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,
+Index: linux-2.6.0-test5/fs/xfs/xfs_iget.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_iget.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_iget.c        2003-09-27 11:38:39.811476120 +0800
+@@ -204,7 +204,7 @@
+                               if (ip->i_flags & XFS_IRECLAIM) {
+                                       read_unlock(&ih->ih_lock);
+                                       delay(1);
+-                                      XFS_STATS_INC(xfsstats.xs_ig_frecycle);
++                                      XFS_STATS_INC(xs_ig_frecycle);
+                                       goto again;
+                               }
+@@ -212,7 +212,7 @@
+                               vn_trace_exit(vp, "xfs_iget.alloc",
+                                       (inst_t *)__return_address);
+-                              XFS_STATS_INC(xfsstats.xs_ig_found);
++                              XFS_STATS_INC(xs_ig_found);
+                               ip->i_flags &= ~XFS_IRECLAIMABLE;
+                               read_unlock(&ih->ih_lock);
+@@ -232,7 +232,7 @@
+                               if (inode->i_state & (I_FREEING | I_CLEAR)) {
+                                       read_unlock(&ih->ih_lock);
+                                       delay(1);
+-                                      XFS_STATS_INC(xfsstats.xs_ig_frecycle);
++                                      XFS_STATS_INC(xs_ig_frecycle);
+                                       goto again;
+                               }
+@@ -247,7 +247,7 @@
+                       read_unlock(&ih->ih_lock);
+-                      XFS_STATS_INC(xfsstats.xs_ig_found);
++                      XFS_STATS_INC(xs_ig_found);
+ finish_inode:
+                       if (lock_flags != 0) {
+@@ -269,7 +269,7 @@
+        * Inode cache miss: save the hash chain version stamp and unlock
+        * the chain, so we don't deadlock in vn_alloc.
+        */
+-      XFS_STATS_INC(xfsstats.xs_ig_missed);
++      XFS_STATS_INC(xs_ig_missed);
+       version = ih->ih_version;
+@@ -305,7 +305,7 @@
+                               write_unlock(&ih->ih_lock);
+                               xfs_idestroy(ip);
+-                              XFS_STATS_INC(xfsstats.xs_ig_dup);
++                              XFS_STATS_INC(xs_ig_dup);
+                               goto again;
+                       }
+               }
+@@ -442,7 +442,7 @@
+       int             error;
+ retry:
+-      XFS_STATS_INC(xfsstats.xs_ig_attempts);
++      XFS_STATS_INC(xs_ig_attempts);
+       if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) {
+               bhv_desc_t      *bdp;
+@@ -475,7 +475,7 @@
+                       bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);
+                       if (bdp == NULL) {
+-                              XFS_STATS_INC(xfsstats.xs_ig_dup);
++                              XFS_STATS_INC(xs_ig_dup);
+                               goto inode_allocate;
+                       }
+                       ip = XFS_BHVTOI(bdp);
+@@ -484,7 +484,7 @@
+                       newnode = (ip->i_d.di_mode == 0);
+                       if (newnode)
+                               xfs_iocore_inode_reinit(ip);
+-                      XFS_STATS_INC(xfsstats.xs_ig_found);
++                      XFS_STATS_INC(xs_ig_found);
+                       *ipp = ip;
+                       error = 0;
+               }
+@@ -604,7 +604,7 @@
+       /*
+        * Remove from old hash list and mount list.
+        */
+-      XFS_STATS_INC(xfsstats.xs_ig_reclaims);
++      XFS_STATS_INC(xs_ig_reclaims);
+       xfs_iextract(ip);
+Index: linux-2.6.0-test5/fs/xfs/xfs_inode.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_inode.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_inode.c       2003-09-27 11:38:39.838472016 +0800
+@@ -1210,6 +1210,18 @@
+               break;
+       case IFREG:
+       case IFDIR:
++              if (pip->i_d.di_flags &
++                  (XFS_DIFLAG_NOATIME|XFS_DIFLAG_NODUMP|XFS_DIFLAG_SYNC)) {
++                      if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
++                          xfs_inherit_noatime)
++                              ip->i_d.di_flags |= XFS_DIFLAG_NOATIME;
++                      if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
++                          xfs_inherit_nodump)
++                              ip->i_d.di_flags |= XFS_DIFLAG_NODUMP;
++                      if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
++                          xfs_inherit_sync)
++                              ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
++              }
+       case IFLNK:
+               ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
+               ip->i_df.if_flags = XFS_IFEXTENTS;
+@@ -2884,7 +2896,7 @@
+       enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) };
+       SPLDECL(s);
+-      XFS_STATS_INC(xfsstats.xs_iflush_count);
++      XFS_STATS_INC(xs_iflush_count);
+       ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
+       ASSERT(valusema(&ip->i_flock) <= 0);
+@@ -3057,8 +3069,8 @@
+       mutex_spinunlock(&ch->ch_lock, s);
+       if (clcount) {
+-              XFS_STATS_INC(xfsstats.xs_icluster_flushcnt);
+-              XFS_STATS_ADD(xfsstats.xs_icluster_flushinode, clcount);
++              XFS_STATS_INC(xs_icluster_flushcnt);
++              XFS_STATS_ADD(xs_icluster_flushinode, clcount);
+       }
+       /*
+@@ -3500,6 +3512,9 @@
+               if (IS_RDONLY(inode) &&
+                   (S_ISREG(imode) || S_ISDIR(imode) || S_ISLNK(imode)))
+                       return XFS_ERROR(EROFS);
++
++              if (IS_IMMUTABLE(inode))
++                      return XFS_ERROR(EACCES);
+       }
+       /*
+@@ -3623,7 +3638,7 @@
+        * Don't update access timestamps on reads if mounted "noatime"
+        * Throw it away if anyone asks us.
+        */
+-      if (ip->i_mount->m_flags & XFS_MOUNT_NOATIME &&
++      if ((ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
+           ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG))
+                       == XFS_ICHGTIME_ACC))
+               return;
+@@ -3657,7 +3672,7 @@
+       SYNCHRONIZE();
+       ip->i_update_core = 1;
+       if (!(inode->i_state & I_LOCK))
+-              mark_inode_dirty(inode);
++              mark_inode_dirty_sync(inode);
+ }
+ #ifdef XFS_ILOCK_TRACE
+Index: linux-2.6.0-test5/fs/xfs/xfs_inum.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_inum.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_inum.h        2003-09-27 11:38:39.841471560 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
++ * Copyright (c) 2000-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
+@@ -47,7 +47,7 @@
+  * Used in some places where having 64-bits in the 32-bit kernels
+  * costs too much.
+  */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ typedef       xfs_ino_t       xfs_intino_t;
+ #else
+ typedef       __uint32_t      xfs_intino_t;
+@@ -162,7 +162,7 @@
+       ((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o)))
+ #endif
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+ #define       XFS_MAXINUMBER          ((xfs_ino_t)((1ULL << 56) - 1ULL))
+ #define       XFS_INO64_OFFSET        ((xfs_ino_t)(1ULL << 32))
+ #else
+Index: linux-2.6.0-test5/fs/xfs/xfs_iocore.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_iocore.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_iocore.c      2003-09-27 11:38:39.843471256 +0800
+@@ -61,7 +61,6 @@
+ #include "xfs_rw.h"
+ #include "xfs_quota.h"
+ #include "xfs_trans_space.h"
+-#include "xfs_dmapi.h"
+ STATIC xfs_fsize_t
+Index: linux-2.6.0-test5/fs/xfs/xfs_itable.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_itable.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_itable.c      2003-09-27 11:38:39.849470344 +0800
+@@ -156,13 +156,23 @@
+       /*
+        * convert di_flags to bs_xflags.
+        */
+-      di_flags=INT_GET(dic->di_flags, arch);
++      di_flags = INT_GET(dic->di_flags, arch);
+       buf->bs_xflags =
+               ((di_flags & XFS_DIFLAG_REALTIME) ?
+                       XFS_XFLAG_REALTIME : 0) |
+               ((di_flags & XFS_DIFLAG_PREALLOC) ?
+                       XFS_XFLAG_PREALLOC : 0) |
++              ((di_flags & XFS_DIFLAG_IMMUTABLE) ?
++                      XFS_XFLAG_IMMUTABLE : 0) |
++              ((di_flags & XFS_DIFLAG_APPEND) ?
++                      XFS_XFLAG_APPEND : 0) |
++              ((di_flags & XFS_DIFLAG_SYNC) ?
++                      XFS_XFLAG_SYNC : 0) |
++              ((di_flags & XFS_DIFLAG_NOATIME) ?
++                      XFS_XFLAG_NOATIME : 0) |
++              ((di_flags & XFS_DIFLAG_NODUMP) ?
++                      XFS_XFLAG_NODUMP : 0) |
+               (XFS_CFORK_Q_ARCH(dic, arch) ?
+                       XFS_XFLAG_HASATTR : 0);
+Index: linux-2.6.0-test5/fs/xfs/xfs_log.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_log.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_log.c 2003-09-27 11:38:39.876466240 +0800
+@@ -345,7 +345,7 @@
+       ASSERT(flags & XFS_LOG_FORCE);
+-      XFS_STATS_INC(xfsstats.xs_log_force);
++      XFS_STATS_INC(xs_log_force);
+       if ((log->l_flags & XLOG_IO_ERROR) == 0) {
+               if (lsn == 0)
+@@ -446,7 +446,7 @@
+       if (XLOG_FORCED_SHUTDOWN(log))
+               return XFS_ERROR(EIO);
+-      XFS_STATS_INC(xfsstats.xs_try_logspace);
++      XFS_STATS_INC(xs_try_logspace);
+       if (*ticket != NULL) {
+               ASSERT(flags & XFS_LOG_PERM_RESERV);
+@@ -497,7 +497,8 @@
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+       if (! xlog_debug) {
+-              cmn_err(CE_NOTE, "log dev: 0x%x", log_dev);
++              cmn_err(CE_NOTE, "log dev: %u:%u",
++                      MAJOR(log_dev), MINOR(log_dev));
+               return 0;
+       }
+ #endif
+@@ -1428,7 +1429,7 @@
+       int             split = 0;      /* split write into two regions */
+       int             error;
+-      XFS_STATS_INC(xfsstats.xs_log_writes);
++      XFS_STATS_INC(xs_log_writes);
+       ASSERT(iclog->ic_refcnt == 0);
+       /* Round out the log write size */
+@@ -1477,7 +1478,7 @@
+       /* Add for LR header */
+       count += log->l_iclog_hsize;
+-      XFS_STATS_ADD(xfsstats.xs_log_blocks, BTOBB(count));
++      XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
+       /* Do we need to split this write into 2 parts? */
+       if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) {
+@@ -2308,7 +2309,7 @@
+               log->l_flushcnt++;
+               LOG_UNLOCK(log, s);
+               xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
+-              XFS_STATS_INC(xfsstats.xs_log_noiclogs);
++              XFS_STATS_INC(xs_log_noiclogs);
+               /* Ensure that log writes happen */
+               psema(&log->l_flushsema, PINOD);
+               goto restart;
+@@ -2421,7 +2422,7 @@
+               if (XLOG_FORCED_SHUTDOWN(log))
+                       goto error_return;
+-              XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++              XFS_STATS_INC(xs_sleep_logspace);
+               sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
+               /*
+                * If we got an error, and the filesystem is shutting down,
+@@ -2447,7 +2448,7 @@
+                       XLOG_INS_TICKETQ(log->l_reserve_headq, tic);
+               xlog_trace_loggrant(log, tic,
+                                   "xlog_grant_log_space: sleep 2");
+-              XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++              XFS_STATS_INC(xs_sleep_logspace);
+               sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
+               if (XLOG_FORCED_SHUTDOWN(log)) {
+@@ -2558,7 +2559,7 @@
+                       xlog_trace_loggrant(log, tic,
+                                   "xlog_regrant_write_log_space: sleep 1");
+-                      XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++                      XFS_STATS_INC(xs_sleep_logspace);
+                       sv_wait(&tic->t_sema, PINOD|PLTWAIT,
+                               &log->l_grant_lock, s);
+@@ -2587,7 +2588,7 @@
+       if (free_bytes < need_bytes) {
+               if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
+                       XLOG_INS_TICKETQ(log->l_write_headq, tic);
+-              XFS_STATS_INC(xfsstats.xs_sleep_logspace);
++              XFS_STATS_INC(xs_sleep_logspace);
+               sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
+               /* If we're shutting down, this tic is already off the queue */
+@@ -2952,7 +2953,7 @@
+                       LOG_UNLOCK(log, s);
+                       return XFS_ERROR(EIO);
+               }
+-              XFS_STATS_INC(xfsstats.xs_log_force_sleep);
++              XFS_STATS_INC(xs_log_force_sleep);
+               sv_wait(&iclog->ic_forcesema, PINOD, &log->l_icloglock, s);
+               /*
+                * No need to grab the log lock here since we're
+@@ -3035,7 +3036,7 @@
+                   (iclog->ic_prev->ic_state & (XLOG_STATE_WANT_SYNC |
+                                                XLOG_STATE_SYNCING))) {
+                       ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR));
+-                      XFS_STATS_INC(xfsstats.xs_log_force_sleep);
++                      XFS_STATS_INC(xs_log_force_sleep);
+                       sv_wait(&iclog->ic_prev->ic_writesema, PSWP,
+                               &log->l_icloglock, s);
+                       already_slept = 1;
+@@ -3061,7 +3062,7 @@
+                       LOG_UNLOCK(log, s);
+                       return XFS_ERROR(EIO);
+               }
+-              XFS_STATS_INC(xfsstats.xs_log_force_sleep);
++              XFS_STATS_INC(xs_log_force_sleep);
+               sv_wait(&iclog->ic_forcesema, PSWP, &log->l_icloglock, s);
+               /*
+                * No need to grab the log lock here since we're
+@@ -3128,7 +3129,7 @@
+        * The kmem_zalloc may sleep, so we shouldn't be holding the
+        * global lock.  XXXmiken: may want to use zone allocator.
+        */
+-      buf = (xfs_caddr_t) kmem_zalloc(NBPP, 0);
++      buf = (xfs_caddr_t) kmem_zalloc(NBPP, KM_SLEEP);
+       s = LOG_LOCK(log);
+@@ -3427,8 +3428,8 @@
+               if (syncing == B_FALSE || (field_offset & 0x1ff)) {
+                       clientid = ophead->oh_clientid;
+               } else {
+-                      idx = BTOBB((xfs_caddr_t)&(ophead->oh_clientid) - iclog->ic_datap);
+-                      if (idx > (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
++                      idx = BTOBBT((xfs_caddr_t)&(ophead->oh_clientid) - iclog->ic_datap);
++                      if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
+                               j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+                               k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+                               clientid = GET_CLIENT_ID(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
+@@ -3445,9 +3446,9 @@
+               if (syncing == B_FALSE || (field_offset & 0x1ff)) {
+                       op_len = INT_GET(ophead->oh_len, ARCH_CONVERT);
+               } else {
+-                      idx = BTOBB((__psint_t)&ophead->oh_len -
++                      idx = BTOBBT((__psint_t)&ophead->oh_len -
+                                   (__psint_t)iclog->ic_datap);
+-                      if (idx > (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
++                      if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
+                               j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+                               k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+                               op_len = INT_GET(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
+Index: linux-2.6.0-test5/fs/xfs/xfs_log_recover.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_log_recover.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_log_recover.c 2003-09-27 11:38:39.905461832 +0800
+@@ -54,7 +54,6 @@
+ #include "xfs_inode.h"
+ #include "xfs_ialloc_btree.h"
+ #include "xfs_ialloc.h"
+-#include "xfs_error.h"
+ #include "xfs_log_priv.h"
+ #include "xfs_buf_item.h"
+ #include "xfs_alloc_btree.h"
+@@ -1360,7 +1359,7 @@
+ {
+       xlog_recover_item_t     *item;
+-      item = kmem_zalloc(sizeof(xlog_recover_item_t), 0);
++      item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP);
+       xlog_recover_insert_item_backq(itemq, item);
+ }
+@@ -1444,7 +1443,7 @@
+               item->ri_total  = in_f->ilf_size;
+               ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM);
+               item->ri_buf = kmem_zalloc((item->ri_total *
+-                                          sizeof(xfs_log_iovec_t)), 0);
++                                          sizeof(xfs_log_iovec_t)), KM_SLEEP);
+       }
+       ASSERT(item->ri_total > item->ri_cnt);
+       /* Description region is ri_buf[0] */
+@@ -2180,8 +2179,8 @@
+               break;
+       default:
+               xfs_fs_cmn_err(CE_ALERT, log->l_mp,
+-                      "xfs_log_recover: unknown buffer type 0x%x, dev 0x%x",
+-                      buf_f->blf_type, log->l_dev);
++                      "xfs_log_recover: unknown buffer type 0x%x, dev %u:%u",
++                      buf_f->blf_type, MAJOR(log->l_dev), MINOR(log->l_dev));
+               XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
+                                XFS_ERRLEVEL_LOW, log->l_mp);
+               return XFS_ERROR(EFSCORRUPTED);
+Index: linux-2.6.0-test5/fs/xfs/xfs_mount.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_mount.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_mount.c       2003-09-27 11:38:39.941456360 +0800
+@@ -222,15 +222,21 @@
+               return XFS_ERROR(EWRONGFS);
+       }
+-      if (unlikely(sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
+-              cmn_err(CE_WARN, "XFS: filesystem is marked as having an external log; specify logdev on the\nmount command line.");
++      if (unlikely(
++          sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
++              cmn_err(CE_WARN,
++      "XFS: filesystem is marked as having an external log; "
++      "specify logdev on the\nmount command line.");
+               XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(1)",
+                                    XFS_ERRLEVEL_HIGH, mp, sbp);
+               return XFS_ERROR(EFSCORRUPTED);
+       }
+-      if (unlikely(sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
+-              cmn_err(CE_WARN, "XFS: filesystem is marked as having an internal log; don't specify logdev on\nthe mount command line.");
++      if (unlikely(
++          sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
++              cmn_err(CE_WARN,
++      "XFS: filesystem is marked as having an internal log; "
++      "don't specify logdev on\nthe mount command line.");
+               XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(2)",
+                                    XFS_ERRLEVEL_HIGH, mp, sbp);
+               return XFS_ERROR(EFSCORRUPTED);
+@@ -276,10 +282,14 @@
+               return XFS_ERROR(EFSCORRUPTED);
+       }
+-#if !XFS_BIG_FILESYSTEMS
+-      if (sbp->sb_dblocks > INT_MAX || sbp->sb_rblocks > INT_MAX)  {
++#if !XFS_BIG_BLKNOS
++      if (unlikely(
++          (sbp->sb_dblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT))
++              > INT_MAX ||
++          (sbp->sb_rblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT))
++              > INT_MAX)) {
+               cmn_err(CE_WARN,
+-"XFS:  File systems greater than 1TB not supported on this system.");
++      "XFS: File system is too large to be mounted on this system.");
+               return XFS_ERROR(E2BIG);
+       }
+ #endif
+@@ -294,7 +304,7 @@
+       /*
+        * Until this is fixed only page-sized or smaller data blocks work.
+        */
+-      if (sbp->sb_blocksize > PAGE_SIZE) {
++      if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
+               cmn_err(CE_WARN,
+               "XFS: Attempted to mount file system with blocksize %d bytes",
+                       sbp->sb_blocksize);
+@@ -322,9 +332,11 @@
+       ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
+       /* Clear the mount flag if no inode can overflow 32 bits
+-       * on this filesystem.
++       * on this filesystem, or if specifically requested..
+        */
+-      if (ino <= max_inum) {
++      if ((mp->m_flags & XFS_MOUNT_32BITINOOPT) && ino > max_inum) {
++              mp->m_flags |= XFS_MOUNT_32BITINODES;
++      } else {
+               mp->m_flags &= ~XFS_MOUNT_32BITINODES;
+       }
+Index: linux-2.6.0-test5/fs/xfs/xfs_mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_mount.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_mount.h       2003-09-27 11:38:39.951454840 +0800
+@@ -95,8 +95,8 @@
+                       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_namesp_t)(dm_eventtype_t, struct bhv_desc *,
+-                      dm_right_t, struct bhv_desc *, 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);
+ typedef void  (*xfs_send_unmount_t)(struct vfs *, struct vnode *,
+                       dm_right_t, mode_t, int, int);
+@@ -354,7 +354,7 @@
+       __uint64_t              m_maxioffset;   /* maximum inode offset */
+       __uint64_t              m_resblks;      /* total reserved blocks */
+       __uint64_t              m_resblks_avail;/* available reserved blocks */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       xfs_ino_t               m_inoadd;       /* add value for ino64_offset */
+ #endif
+       int                     m_dalign;       /* stripe unit */
+@@ -392,9 +392,7 @@
+ #define       XFS_MOUNT_WSYNC         0x00000001      /* for nfs - all metadata ops
+                                                  must be synchronous except
+                                                  for space allocations */
+-#if XFS_BIG_FILESYSTEMS
+ #define       XFS_MOUNT_INO64         0x00000002
+-#endif
+                            /* 0x00000004      -- currently unused */
+                            /* 0x00000008      -- currently unused */
+ #define XFS_MOUNT_FS_SHUTDOWN 0x00000010      /* atomic stop of all filesystem
+@@ -413,10 +411,11 @@
+ #define XFS_MOUNT_DFLT_IOSIZE 0x00001000      /* set default i/o size */
+ #define XFS_MOUNT_OSYNCISOSYNC        0x00002000      /* o_sync is REALLY o_sync */
+                                               /* osyncisdsync is now default*/
+-#define XFS_MOUNT_NOUUID      0x00004000      /* ignore uuid during mount */
+-#define XFS_MOUNT_32BITINODES 0x00008000      /* do not create inodes above
++#define XFS_MOUNT_32BITINODES 0x00004000      /* do not create inodes above
+                                                * 32 bits in size */
+-#define XFS_MOUNT_NOLOGFLUSH  0x00010000
++#define XFS_MOUNT_32BITINOOPT 0x00008000      /* saved mount option state */
++#define XFS_MOUNT_NOUUID      0x00010000      /* ignore uuid during mount */
++#define XFS_MOUNT_NOLOGFLUSH  0x00020000
+ /*
+  * Default minimum read and write sizes.
+Index: linux-2.6.0-test5/fs/xfs/xfs_rename.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_rename.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_rename.c      2003-09-27 11:38:39.966452560 +0800
+@@ -56,7 +56,6 @@
+ #include "xfs_trans_space.h"
+ #include "xfs_da_btree.h"
+ #include "xfs_dir_leaf.h"
+-#include "xfs_dmapi.h"
+ /*
+@@ -293,8 +292,8 @@
+           DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
+                               target_dp, DM_EVENT_RENAME)) {
+               error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
+-                                      src_dir_bdp, DM_RIGHT_NULL,
+-                                      target_dir_bdp, DM_RIGHT_NULL,
++                                      src_dir_vp, DM_RIGHT_NULL,
++                                      target_dir_vp, DM_RIGHT_NULL,
+                                       src_name, target_name,
+                                       0, 0, 0);
+               if (error) {
+@@ -650,8 +649,8 @@
+           DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
+                               target_dp, DM_EVENT_POSTRENAME)) {
+               (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
+-                                      src_dir_bdp, DM_RIGHT_NULL,
+-                                      target_dir_bdp, DM_RIGHT_NULL,
++                                      src_dir_vp, DM_RIGHT_NULL,
++                                      target_dir_vp, DM_RIGHT_NULL,
+                                       src_name, target_name,
+                                       0, error, 0);
+       }
+Index: linux-2.6.0-test5/fs/xfs/xfs_rtalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_rtalloc.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_rtalloc.h     2003-09-27 11:38:39.968452256 +0800
+@@ -77,7 +77,7 @@
+ #define       XFS_RTLOBIT(w)  xfs_lowbit32(w)
+ #define       XFS_RTHIBIT(w)  xfs_highbit32(w)
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ #define       XFS_RTBLOCKLOG(b)       xfs_highbit64(b)
+ #else
+ #define       XFS_RTBLOCKLOG(b)       xfs_highbit32(b)
+Index: linux-2.6.0-test5/fs/xfs/xfs_rw.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_rw.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_rw.c  2003-09-27 11:38:39.971451800 +0800
+@@ -59,7 +59,6 @@
+ #include "xfs_bmap.h"
+ #include "xfs_acl.h"
+ #include "xfs_mac.h"
+-#include "xfs_attr.h"
+ #include "xfs_error.h"
+ #include "xfs_buf_item.h"
+ #include "xfs_rw.h"
+@@ -261,10 +260,11 @@
+       xfs_daddr_t             blkno)
+ {
+       cmn_err(CE_ALERT,
+- "I/O error in filesystem (\"%s\") meta-data dev 0x%x block 0x%llx"
++ "I/O error in filesystem (\"%s\") meta-data dev %u:%u block 0x%llx"
+  "       (\"%s\") error %d buf count %u",
+               (!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,
+-              XFS_BUF_TARGET_DEV(bp),
++              MAJOR(XFS_BUF_TARGET_DEV(bp)),
++              MINOR(XFS_BUF_TARGET_DEV(bp)),
+               (__uint64_t)blkno,
+               func,
+               XFS_BUF_GETERROR(bp),
+Index: linux-2.6.0-test5/fs/xfs/xfs_trans_ail.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_trans_ail.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_trans_ail.c   2003-09-27 11:38:39.976451040 +0800
+@@ -40,7 +40,6 @@
+ #include "xfs_dir.h"
+ #include "xfs_dmapi.h"
+ #include "xfs_mount.h"
+-#include "xfs_log.h"
+ #include "xfs_trans_priv.h"
+ #include "xfs_error.h"
+@@ -119,7 +118,7 @@
+               return (xfs_lsn_t)0;
+       }
+-      XFS_STATS_INC(xfsstats.xs_push_ail);
++      XFS_STATS_INC(xs_push_ail);
+       /*
+        * While the item we are looking at is below the given threshold
+@@ -153,14 +152,14 @@
+               switch (lock_result) {
+                     case XFS_ITEM_SUCCESS:
+                       AIL_UNLOCK(mp, s);
+-                      XFS_STATS_INC(xfsstats.xs_push_ail_success);
++                      XFS_STATS_INC(xs_push_ail_success);
+                       IOP_PUSH(lip);
+                       AIL_LOCK(mp,s);
+                       break;
+                     case XFS_ITEM_PUSHBUF:
+                       AIL_UNLOCK(mp, s);
+-                      XFS_STATS_INC(xfsstats.xs_push_ail_pushbuf);
++                      XFS_STATS_INC(xs_push_ail_pushbuf);
+ #ifdef XFSRACEDEBUG
+                       delay_for_intr();
+                       delay(300);
+@@ -172,16 +171,16 @@
+                       break;
+                     case XFS_ITEM_PINNED:
+-                      XFS_STATS_INC(xfsstats.xs_push_ail_pinned);
++                      XFS_STATS_INC(xs_push_ail_pinned);
+                       flush_log = 1;
+                       break;
+                     case XFS_ITEM_LOCKED:
+-                      XFS_STATS_INC(xfsstats.xs_push_ail_locked);
++                      XFS_STATS_INC(xs_push_ail_locked);
+                       break;
+                     case XFS_ITEM_FLUSHING:
+-                      XFS_STATS_INC(xfsstats.xs_push_ail_flushing);
++                      XFS_STATS_INC(xs_push_ail_flushing);
+                       break;
+                     default:
+@@ -210,7 +209,7 @@
+                * move forward in the AIL.
+                */
+               AIL_UNLOCK(mp, s);
+-              XFS_STATS_INC(xfsstats.xs_push_ail_flush);
++              XFS_STATS_INC(xs_push_ail_flush);
+               xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
+               AIL_LOCK(mp, s);
+       }
+@@ -429,7 +428,7 @@
+               nlip = xfs_ail_min(&(mp->m_ail));
+               *gen = (int)mp->m_ail_gen;
+               if (restarts != NULL) {
+-                      XFS_STATS_INC(xfsstats.xs_push_ail_restarts);
++                      XFS_STATS_INC(xs_push_ail_restarts);
+                       (*restarts)++;
+               }
+       }
+Index: linux-2.6.0-test5/fs/xfs/xfs_trans.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_trans.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_trans.c       2003-09-27 11:38:39.985449672 +0800
+@@ -739,7 +739,7 @@
+               xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
+               xfs_trans_free_busy(tp);
+               xfs_trans_free(tp);
+-              XFS_STATS_INC(xfsstats.xs_trans_empty);
++              XFS_STATS_INC(xs_trans_empty);
+               if (commit_lsn_p)
+                       *commit_lsn_p = commit_lsn;
+               return (shutdown);
+@@ -895,9 +895,9 @@
+               if (!error)
+                       error = xfs_log_force(mp, commit_lsn,
+                                     XFS_LOG_FORCE | XFS_LOG_SYNC);
+-              XFS_STATS_INC(xfsstats.xs_trans_sync);
++              XFS_STATS_INC(xs_trans_sync);
+       } else {
+-              XFS_STATS_INC(xfsstats.xs_trans_async);
++              XFS_STATS_INC(xs_trans_async);
+       }
+       return (error);
+Index: linux-2.6.0-test5/fs/xfs/xfs_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_types.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_types.h       2003-09-27 11:38:39.988449216 +0800
+@@ -78,20 +78,21 @@
+ #endif        /* __KERNEL__ */
+ /*
+- * Some types are conditional based on the selected configuration.
+- * Set XFS_BIG_FILESYSTEMS=1 or 0 depending on the desired configuration.
+- * XFS_BIG_FILESYSTEMS needs daddr_t to be 64 bits
+- *
+- * On linux right now we are limited to 2^32 512 byte blocks in a
+- * filesystem, Once this limit is changed, setting this to 1
+- * will allow XFS to go larger. With BIG_FILESYSTEMS set to 0
+- * a 4K block filesystem could still theoretically be 16Gbytes
+- * long, so on an ia32 box the 32 bit page index will then be
+- * the limiting factor.
+- */
+-
+-#ifndef XFS_BIG_FILESYSTEMS
+-#define XFS_BIG_FILESYSTEMS   0
++ * Some types are conditional depending on the target system.
++ * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
++ * 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))
++# define XFS_BIG_BLKNOS       1
++# if BITS_PER_LONG == 64
++#  define XFS_BIG_INUMS       1
++# else
++#  define XFS_BIG_INUMS       0
++# endif
++#else
++# define XFS_BIG_BLKNOS       0
++# define XFS_BIG_INUMS        0
+ #endif
+ typedef __uint32_t    xfs_agblock_t;  /* blockno in alloc. group */
+@@ -126,7 +127,7 @@
+ /*
+  * Memory based types are conditional.
+  */
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_BLKNOS
+ typedef       __uint64_t      xfs_fsblock_t;  /* blockno in filesystem (agno|agbno) */
+ typedef __uint64_t    xfs_rfsblock_t; /* blockno in filesystem (raw) */
+ typedef __uint64_t    xfs_rtblock_t;  /* extent (block) in realtime area */
+@@ -196,20 +197,4 @@
+       XFS_BTNUM_MAX
+ } xfs_btnum_t;
+-
+-/*
+- * Juggle IRIX device numbers - still used in ondisk structures
+- */
+-#define XFS_DEV_BITSMAJOR     14
+-#define XFS_DEV_BITSMINOR     18
+-#define XFS_DEV_MAXMAJ                0x1ff
+-#define XFS_DEV_MAXMIN                0x3ffff
+-#define XFS_DEV_MAJOR(dev)    ((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \
+-                                  & XFS_DEV_MAXMAJ))
+-#define XFS_DEV_MINOR(dev)    ((int)((dev)&XFS_DEV_MAXMIN))
+-#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \
+-                                  | (minor&XFS_DEV_MAXMIN)))
+-
+-#define XFS_DEV_TO_KDEVT(dev) MKDEV(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
+-
+ #endif        /* !__XFS_TYPES_H */
+Index: linux-2.6.0-test5/fs/xfs/xfs_vfsops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_vfsops.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_vfsops.c      2003-09-27 11:38:40.000447392 +0800
+@@ -49,7 +49,6 @@
+ #include "xfs_btree.h"
+ #include "xfs_alloc.h"
+ #include "xfs_ialloc.h"
+-#include "xfs_alloc.h"
+ #include "xfs_attr_sf.h"
+ #include "xfs_dir_sf.h"
+ #include "xfs_dir2_sf.h"
+@@ -64,7 +63,6 @@
+ #include "xfs_buf_item.h"
+ #include "xfs_extfree_item.h"
+ #include "xfs_quota.h"
+-#include "xfs_dmapi.h"
+ #include "xfs_dir2_trace.h"
+ #include "xfs_acl.h"
+ #include "xfs_attr.h"
+@@ -266,7 +264,7 @@
+        */
+       if (ap->flags & XFSMNT_WSYNC)
+               mp->m_flags |= XFS_MOUNT_WSYNC;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       if (ap->flags & XFSMNT_INO64) {
+               mp->m_flags |= XFS_MOUNT_INO64;
+               mp->m_inoadd = XFS_INO64_OFFSET;
+@@ -285,7 +283,7 @@
+               mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
+       if (ap->flags & XFSMNT_32BITINODES)
+-              mp->m_flags |= XFS_MOUNT_32BITINODES;
++              mp->m_flags |= (XFS_MOUNT_32BITINODES | XFS_MOUNT_32BITINOOPT);
+       if (ap->flags & XFSMNT_IOSIZE) {
+               if (ap->iosizelog > XFS_MAX_IO_LOG ||
+@@ -333,9 +331,10 @@
+ {
+       /* Fail a mount where the logbuf is smaller then the log stripe */
+       if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
+-              if (((ap->logbufsize == -1) &&
+-                   (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) ||
+-                  (ap->logbufsize < mp->m_sb.sb_logsunit)) {
++              if ((ap->logbufsize == -1) &&
++                  (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) {
++                      mp->m_logbsize = mp->m_sb.sb_logsunit;
++              } else if (ap->logbufsize < mp->m_sb.sb_logsunit) {
+                       cmn_err(CE_WARN,
+       "XFS: logbuf size must be greater than or equal to log stripe size");
+                       return XFS_ERROR(EINVAL);
+@@ -534,11 +533,8 @@
+       rvp = XFS_ITOV(rip);
+       if (vfsp->vfs_flag & VFS_DMI) {
+-              bhv_desc_t      *rbdp;
+-
+-              rbdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(rvp), &xfs_vnodeops);
+               error = XFS_SEND_NAMESP(mp, DM_EVENT_PREUNMOUNT,
+-                              rbdp, DM_RIGHT_NULL, rbdp, DM_RIGHT_NULL,
++                              rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
+                               NULL, NULL, 0, 0,
+                               (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
+                                       0:DM_FLAGS_UNWANTED);
+@@ -759,6 +755,7 @@
+       xfs_mount_t     *mp;
+       xfs_sb_t        *sbp;
+       unsigned long   s;
++      u64 id;
+       mp = XFS_BHVTOM(bdp);
+       sbp = &(mp->m_sb);
+@@ -771,13 +768,13 @@
+       statp->f_blocks = sbp->sb_dblocks - lsize;
+       statp->f_bfree = statp->f_bavail = sbp->sb_fdblocks;
+       fakeinos = statp->f_bfree << sbp->sb_inopblog;
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+       fakeinos += mp->m_inoadd;
+ #endif
+       statp->f_files =
+           MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
+       if (mp->m_maxicount)
+-#if XFS_BIG_FILESYSTEMS
++#if XFS_BIG_INUMS
+               if (!mp->m_inoadd)
+ #endif
+                       statp->f_files =
+@@ -785,8 +782,9 @@
+       statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
+       XFS_SB_UNLOCK(mp, s);
+-      statp->f_fsid.val[0] = mp->m_dev;
+-      statp->f_fsid.val[1] = 0;
++      id = huge_encode_dev(mp->m_dev);
++      statp->f_fsid.val[0] = (u32)id;
++      statp->f_fsid.val[1] = (u32)(id >> 32);
+       statp->f_namelen = MAXNAMELEN - 1;
+       return 0;
+@@ -1589,6 +1587,7 @@
+ #define MNTOPT_NORECOVERY   "norecovery"   /* don't run XFS recovery */
+ #define MNTOPT_NOLOGFLUSH   "nologflush"   /* don't hard flush on log writes */
+ #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
++#define MNTOPT_64BITINODE   "inode64"  /* inodes can be allocated anywhere */
+ int
+@@ -1675,7 +1674,7 @@
+                       args->flags |= XFSMNT_NORECOVERY;
+               } else if (!strcmp(this_char, MNTOPT_INO64)) {
+                       args->flags |= XFSMNT_INO64;
+-#ifndef XFS_BIG_FILESYSTEMS
++#if !XFS_BIG_INUMS
+                       printk("XFS: %s option not allowed on this system\n",
+                               MNTOPT_INO64);
+                       return EINVAL;
+@@ -1696,6 +1695,13 @@
+                               return EINVAL;
+                       }
+                       dswidth = simple_strtoul(value, &eov, 10);
++              } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
++                      args->flags &= ~XFSMNT_32BITINODES;
++#if !XFS_BIG_INUMS
++                      printk("XFS: %s option not allowed on this system\n",
++                              MNTOPT_64BITINODE);
++                      return EINVAL;
++#endif
+               } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
+                       args->flags |= XFSMNT_NOUUID;
+               } else if (!strcmp(this_char, MNTOPT_NOLOGFLUSH)) {
+Index: linux-2.6.0-test5/fs/xfs/xfs_vnodeops.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/xfs/xfs_vnodeops.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/fs/xfs/xfs_vnodeops.c    2003-09-27 11:38:40.030442832 +0800
+@@ -66,7 +66,6 @@
+ #include "xfs_utils.h"
+ #include "xfs_trans_space.h"
+ #include "xfs_dir_leaf.h"
+-#include "xfs_dmapi.h"
+ #include "xfs_mac.h"
+ #include "xfs_log_priv.h"
+@@ -153,10 +152,9 @@
+       vap->va_nblocks =
+               XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
+       vap->va_fsid = mp->m_dev;
+-#if XFS_BIG_FILESYSTEMS
+-      vap->va_nodeid = ip->i_ino + mp->m_inoadd;
+-#else
+       vap->va_nodeid = ip->i_ino;
++#if XFS_BIG_INUMS
++      vap->va_nodeid += mp->m_inoadd;
+ #endif
+       vap->va_nlink = ip->i_d.di_nlink;
+@@ -266,6 +264,16 @@
+                       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_extsize = ip->i_d.di_extsize << mp->m_sb.sb_blocklog;
+@@ -648,6 +656,20 @@
+                               goto error_return;
+                       }
+               }
++
++              /*
++               * Can't modify an immutable/append-only file unless
++               * we have appropriate permission.
++               */
++              if ((mask & XFS_AT_XFLAGS) &&
++                  (ip->i_d.di_flags &
++                              (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) ||
++                   (vap->va_xflags &
++                              (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
++                  !capable(CAP_LINUX_IMMUTABLE)) {
++                      code = XFS_ERROR(EPERM);
++                      goto error_return;
++              }
+       }
+       /*
+@@ -833,6 +855,16 @@
+                               ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
+                               ip->i_iocore.io_flags |= XFS_IOCORE_RT;
+                       }
++                      if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
++                              ip->i_d.di_flags |= XFS_DIFLAG_IMMUTABLE;
++                      if (vap->va_xflags & XFS_XFLAG_APPEND)
++                              ip->i_d.di_flags |= XFS_DIFLAG_APPEND;
++                      if (vap->va_xflags & XFS_XFLAG_SYNC)
++                              ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
++                      if (vap->va_xflags & XFS_XFLAG_NOATIME)
++                              ip->i_d.di_flags |= XFS_DIFLAG_NOATIME;
++                      if (vap->va_xflags & XFS_XFLAG_NODUMP)
++                              ip->i_d.di_flags |= XFS_DIFLAG_NODUMP;
+                       /* can't set PREALLOC this way, just ignore it */
+               }
+               xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+@@ -858,7 +890,7 @@
+       if (timeflags && !(flags & ATTR_DMI))
+               xfs_ichgtime(ip, timeflags);
+-      XFS_STATS_INC(xfsstats.xs_ig_attrchg);
++      XFS_STATS_INC(xs_ig_attrchg);
+       /*
+        * If this is a synchronous mount, make sure that the
+@@ -905,7 +937,7 @@
+       if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) &&
+           !(flags & ATTR_DMI)) {
+-              (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, bdp, DM_RIGHT_NULL,
++              (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL,
+                                       NULL, DM_RIGHT_NULL, NULL, NULL,
+                                       0, 0, AT_DELAY_FLAG(flags));
+       }
+@@ -1635,7 +1667,7 @@
+               if ((((ip->i_d.di_mode & IFMT) == IFREG) &&
+                    ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
+                    (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
+-                  (!(ip->i_d.di_flags & XFS_DIFLAG_PREALLOC))) {
++                  (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)))) {
+                       if ((error = xfs_inactive_free_eofblocks(mp, ip)))
+                               return (error);
+                       /* Update linux inode block count after free above */
+@@ -1710,7 +1742,7 @@
+               if ((((ip->i_d.di_mode & IFMT) == IFREG) &&
+                    ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0)) &&
+                    (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
+-                  (!(ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) ||
++                  (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)) ||
+                    (ip->i_delayed_blks != 0))) {
+                       if ((error = xfs_inactive_free_eofblocks(mp, ip)))
+                               return (VN_INACTIVE_CACHE);
+@@ -1948,7 +1980,7 @@
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+               error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
+-                              dir_bdp, DM_RIGHT_NULL, NULL,
++                              dir_vp, DM_RIGHT_NULL, NULL,
+                               DM_RIGHT_NULL, name, NULL,
+                               dm_di_mode, 0, 0);
+@@ -2114,8 +2146,8 @@
+                       DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
+                                                       DM_EVENT_POSTCREATE)) {
+               (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
+-                      dir_bdp, DM_RIGHT_NULL,
+-                      *vpp ? vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops):NULL,
++                      dir_vp, DM_RIGHT_NULL,
++                      *vpp ? vp:NULL,
+                       DM_RIGHT_NULL, name, NULL,
+                       dm_di_mode, error, 0);
+       }
+@@ -2428,7 +2460,7 @@
+       namelen = VNAMELEN(dentry);
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+-              error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_bdp,
++              error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
+                                       DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
+                                       name, NULL, 0, 0, 0);
+               if (error)
+@@ -2594,7 +2626,7 @@
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp,
+                                               DM_EVENT_POSTREMOVE)) {
+               (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
+-                              dir_bdp, DM_RIGHT_NULL,
++                              dir_vp, DM_RIGHT_NULL,
+                               NULL, DM_RIGHT_NULL,
+                               name, NULL, dm_di_mode, error, 0);
+       }
+@@ -2678,8 +2710,8 @@
+       if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) {
+               error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
+-                                      target_dir_bdp, DM_RIGHT_NULL,
+-                                      src_bdp, DM_RIGHT_NULL,
++                                      target_dir_vp, DM_RIGHT_NULL,
++                                      src_vp, DM_RIGHT_NULL,
+                                       target_name, NULL, 0, 0, 0);
+               if (error)
+                       return error;
+@@ -2782,8 +2814,8 @@
+       if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip,
+                                               DM_EVENT_POSTLINK)) {
+               (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
+-                              target_dir_bdp, DM_RIGHT_NULL,
+-                              src_bdp, DM_RIGHT_NULL,
++                              target_dir_vp, DM_RIGHT_NULL,
++                              src_vp, DM_RIGHT_NULL,
+                               target_name, NULL, 0, error, 0);
+       }
+       return error;
+@@ -2844,7 +2876,7 @@
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+               error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
+-                                      dir_bdp, DM_RIGHT_NULL, NULL,
++                                      dir_vp, DM_RIGHT_NULL, NULL,
+                                       DM_RIGHT_NULL, dir_name, NULL,
+                                       dm_di_mode, 0, 0);
+               if (error)
+@@ -3003,8 +3035,8 @@
+                       DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
+                                               DM_EVENT_POSTCREATE)) {
+               (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
+-                                      dir_bdp, DM_RIGHT_NULL,
+-                                      created ? XFS_ITOBHV(cdp):NULL,
++                                      dir_vp, DM_RIGHT_NULL,
++                                      created ? XFS_ITOV(cdp):NULL,
+                                       DM_RIGHT_NULL,
+                                       dir_name, NULL,
+                                       dm_di_mode, error, 0);
+@@ -3067,7 +3099,7 @@
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+               error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
+-                                      dir_bdp, DM_RIGHT_NULL,
++                                      dir_vp, DM_RIGHT_NULL,
+                                       NULL, DM_RIGHT_NULL,
+                                       name, NULL, 0, 0, 0);
+               if (error)
+@@ -3261,7 +3293,7 @@
+ std_return:
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) {
+               (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
+-                                      dir_bdp, DM_RIGHT_NULL,
++                                      dir_vp, DM_RIGHT_NULL,
+                                       NULL, DM_RIGHT_NULL,
+                                       name, NULL, dm_di_mode,
+                                       error, 0);
+@@ -3405,7 +3437,7 @@
+       }
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) {
+-              error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_bdp,
++              error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp,
+                                       DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
+                                       link_name, target_path, 0, 0, 0);
+               if (error)
+@@ -3597,8 +3629,8 @@
+       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
+                            DM_EVENT_POSTSYMLINK)) {
+               (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
+-                                      dir_bdp, DM_RIGHT_NULL,
+-                                      error ? NULL : XFS_ITOBHV(ip),
++                                      dir_vp, DM_RIGHT_NULL,
++                                      error ? NULL : XFS_ITOV(ip),
+                                       DM_RIGHT_NULL, link_name, target_path,
+                                       0, error, 0);
+       }
+@@ -4236,8 +4268,8 @@
+           DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) {
+               error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
+-                              XFS_ITOBHV(ip), DM_RIGHT_NULL,
+-                              XFS_ITOBHV(ip), DM_RIGHT_NULL,
++                              XFS_ITOV(ip), DM_RIGHT_NULL,
++                              XFS_ITOV(ip), DM_RIGHT_NULL,
+                               NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */
+               if (error == 0)
+                       goto retry;     /* Maybe DMAPI app. has made space */
+Index: linux-2.6.0-test5/include/acpi/acconfig.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/acpi/acconfig.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/acpi/acconfig.h  2003-09-27 11:38:40.032442528 +0800
+@@ -64,7 +64,7 @@
+ /* Version string */
+-#define ACPI_CA_VERSION                 0x20030813
++#define ACPI_CA_VERSION                 0x20030916
+ /* Maximum objects in the various object caches */
+Index: linux-2.6.0-test5/include/asm-alpha/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/cacheflush.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/cacheflush.h   2003-09-27 11:38:40.034442224 +0800
+@@ -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 @@
+ #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 */
+Index: linux-2.6.0-test5/include/asm-alpha/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/lockmeter.h       2003-09-27 11:38:18.474719800 +0800
++++ linux-2.6.0-test5/include/asm-alpha/lockmeter.h    2003-09-27 11:38:40.034442224 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-alpha/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/numnodes.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/numnodes.h     2003-09-27 11:38:40.036441920 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-alpha/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/pgtable.h      2003-09-27 11:38:40.040441312 +0800
+@@ -49,7 +49,6 @@
+ #else
+ #define VMALLOC_START         (-2*PGDIR_SIZE)
+ #endif
+-#define VMALLOC_VMADDR(x)     ((unsigned long)(x))
+ #define VMALLOC_END           (-PGDIR_SIZE)
+ /*
+Index: linux-2.6.0-test5/include/asm-alpha/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/posix_types.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/posix_types.h  2003-09-27 11:38:40.042441008 +0800
+@@ -7,7 +7,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned int  __kernel_dev_t;
+ typedef unsigned int  __kernel_ino_t;
+ typedef unsigned int  __kernel_mode_t;
+ typedef unsigned int  __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-alpha/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/processor.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/processor.h    2003-09-27 11:38:40.043440856 +0800
+@@ -29,7 +29,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 1
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-alpha/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/signal.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/signal.h       2003-09-27 11:38:40.045440552 +0800
+@@ -71,7 +71,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-alpha/smp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/smp.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/smp.h  2003-09-27 11:38:40.047440248 +0800
+@@ -46,7 +46,7 @@
+ #define smp_processor_id()    (current_thread_info()->cpu)
+ extern cpumask_t cpu_present_mask;
+-extern cpumask_t long cpu_online_map;
++extern cpumask_t cpu_online_map;
+ extern int smp_num_cpus;
+ #define cpu_possible(cpu)     cpu_isset(cpu, cpu_present_mask)
+Index: linux-2.6.0-test5/include/asm-alpha/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-alpha/spinlock.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-alpha/spinlock.h     2003-09-27 11:38:40.048440096 +0800
+@@ -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 @@
+ 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 @@
+       : "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 */
+Index: linux-2.6.0-test5/include/asm-arm26/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/cacheflush.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/cacheflush.h   2003-09-27 11:38:40.050439792 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm26/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/pgtable.h      2003-09-27 11:38:40.053439336 +0800
+@@ -173,7 +173,6 @@
+  * 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
+Index: linux-2.6.0-test5/include/asm-arm26/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/posix_types.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/posix_types.h  2003-09-27 11:38:40.055439032 +0800
+@@ -19,7 +19,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned short                __kernel_dev_t;
+ typedef unsigned long         __kernel_ino_t;
+ typedef unsigned short                __kernel_mode_t;
+ typedef unsigned short                __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-arm26/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/processor.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/processor.h    2003-09-27 11:38:40.056438880 +0800
+@@ -20,7 +20,6 @@
+ #ifdef __KERNEL__
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+Index: linux-2.6.0-test5/include/asm-arm26/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/signal.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/signal.h       2003-09-27 11:38:40.059438424 +0800
+@@ -68,7 +68,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ #define SIGSWI                32
+Index: linux-2.6.0-test5/include/asm-arm26/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm26/stat.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm26/stat.h 2003-09-27 11:38:40.060438272 +0800
+@@ -42,8 +42,7 @@
+  * insane amounts of padding around dev_t's.
+  */
+ struct stat64 {
+-      unsigned short  st_dev;
+-      unsigned char   __pad0b[6];
++      unsigned long long  st_dev;
+       unsigned char   __pad0[4];
+ #define STAT64_HAS_BROKEN_ST_INO      1
+@@ -54,8 +53,7 @@
+       unsigned long   st_uid;
+       unsigned long   st_gid;
+-      unsigned short  st_rdev;
+-      unsigned char   __pad3b[6];
++      unsigned long long  st_rdev;
+       unsigned char   __pad3[4];
+       long long       st_size;
+Index: linux-2.6.0-test5/include/asm-arm/arch-adifcc/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-adifcc/vmalloc.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-adifcc/vmalloc.h    2003-09-27 11:38:40.062437968 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-anakin/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-anakin/vmalloc.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-anakin/vmalloc.h    2003-09-27 11:38:40.063437816 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-cl7500/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-cl7500/vmalloc.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-cl7500/vmalloc.h    2003-09-27 11:38:40.064437664 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-clps711x/memory.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-clps711x/memory.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-clps711x/memory.h   2003-09-27 11:38:40.067437208 +0800
+@@ -109,8 +109,6 @@
+  *    node 3:  0xd8000000 - 0xdfffffff
+  */
+-#define NR_NODES      4
+-
+ /*
+  * Given a kernel address, find the home node of the underlying memory.
+  */
+Index: linux-2.6.0-test5/include/asm-arm/arch-clps711x/system.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-clps711x/system.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-clps711x/system.h   2003-09-27 11:38:40.068437056 +0800
+@@ -26,7 +26,7 @@
+ {
+       clps_writel(1, HALT);
+       __asm__ __volatile__(
+-      "mov    r0, r0
++      "mov    r0, r0\n\
+       mov     r0, r0");
+ }
+Index: linux-2.6.0-test5/include/asm-arm/arch-clps711x/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-clps711x/vmalloc.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-clps711x/vmalloc.h  2003-09-27 11:38:40.070436752 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-ebsa110/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-ebsa110/vmalloc.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-ebsa110/vmalloc.h   2003-09-27 11:38:40.071436600 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-ebsa285/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-ebsa285/vmalloc.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-ebsa285/vmalloc.h   2003-09-27 11:38:40.072436448 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-epxa10db/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-epxa10db/vmalloc.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-epxa10db/vmalloc.h  2003-09-27 11:38:40.074436144 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-integrator/lm.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-integrator/lm.h        2003-09-27 11:38:18.475719648 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-integrator/lm.h     2003-09-27 11:38:40.074436144 +0800
+@@ -0,0 +1,23 @@
++
++struct lm_device {
++      struct device           dev;
++      struct resource         resource;
++      unsigned int            irq;
++      unsigned int            id;
++};
++
++struct lm_driver {
++      struct device_driver    drv;
++      int                     (*probe)(struct lm_device *);
++      void                    (*remove)(struct lm_device *);
++      int                     (*suspend)(struct lm_device *, u32);
++      int                     (*resume)(struct lm_device *);
++};
++
++int lm_driver_register(struct lm_driver *drv);
++void lm_driver_unregister(struct lm_driver *drv);
++
++int lm_device_register(struct lm_device *dev);
++
++#define lm_get_drvdata(lm)    dev_get_drvdata(&(lm)->dev)
++#define lm_set_drvdata(lm,d)  dev_set_drvdata(&(lm)->dev, d)
+Index: linux-2.6.0-test5/include/asm-arm/arch-integrator/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-integrator/vmalloc.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-integrator/vmalloc.h        2003-09-27 11:38:40.076435840 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-iop3xx/iop321-irqs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-iop3xx/iop321-irqs.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-iop3xx/iop321-irqs.h        2003-09-27 11:38:40.077435688 +0800
+@@ -10,6 +10,7 @@
+  *
+  */
++#include <linux/config.h>
+ /*
+  * IOP80321 chipset interrupts
+Index: linux-2.6.0-test5/include/asm-arm/arch-iop3xx/irqs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-iop3xx/irqs.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-iop3xx/irqs.h       2003-09-27 11:38:40.079435384 +0800
+@@ -10,6 +10,8 @@
+  *
+  */
++#include <linux/config.h>
++
+ /*
+  * Whic iop3xx implementation is this?
+  */
+Index: linux-2.6.0-test5/include/asm-arm/arch-iop3xx/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-iop3xx/vmalloc.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-iop3xx/vmalloc.h    2003-09-27 11:38:40.080435232 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-l7200/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-l7200/vmalloc.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-l7200/vmalloc.h     2003-09-27 11:38:40.081435080 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-nexuspci/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-nexuspci/vmalloc.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-nexuspci/vmalloc.h  2003-09-27 11:38:40.083434776 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/hardware.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/hardware.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/hardware.h      2003-09-27 11:38:40.084434624 +0800
+@@ -13,7 +13,6 @@
+ #ifndef __ASM_ARCH_HARDWARE_H
+ #define __ASM_ARCH_HARDWARE_H
+-#include <linux/config.h>
+ #include <asm/mach-types.h>
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/ide.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/ide.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/ide.h   2003-09-27 11:38:40.086434320 +0800
+@@ -14,7 +14,6 @@
+  *
+  */
+-#include <linux/config.h>
+ #include <asm/irq.h>
+ #include <asm/hardware.h>
+ #include <asm/mach-types.h>
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/idp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/idp.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/idp.h   2003-09-27 11:38:40.090433712 +0800
+@@ -12,6 +12,7 @@
+  *
+  */
++#include <linux/config.h>
+ /*
+  * Note: this file must be safe to include in assembly files
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/irqs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/irqs.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/irqs.h  2003-09-27 11:38:40.092433408 +0800
+@@ -10,6 +10,8 @@
+  * published by the Free Software Foundation.
+  */
++#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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/keyboard.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/keyboard.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/keyboard.h      2003-09-27 11:38:40.094433104 +0800
+@@ -7,7 +7,6 @@
+ #ifndef _PXA_KEYBOARD_H
+ #define _PXA_KEYBOARD_H
+-#include <linux/config.h>
+ #include <asm/mach-types.h>
+ #include <asm/hardware.h>
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/pxa-regs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/pxa-regs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/pxa-regs.h      2003-09-27 11:38:40.111430520 +0800
+@@ -10,6 +10,7 @@
+  * published by the Free Software Foundation.
+  */
++#include <linux/config.h>
+ // FIXME hack so that SA-1111.h will work [cb]
+Index: linux-2.6.0-test5/include/asm-arm/arch-pxa/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-pxa/vmalloc.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-pxa/vmalloc.h       2003-09-27 11:38:40.113430216 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-rpc/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-rpc/vmalloc.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-rpc/vmalloc.h       2003-09-27 11:38:40.114430064 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/memory.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/memory.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/memory.h     2003-09-27 11:38:40.116429760 +0800
+@@ -74,8 +74,6 @@
+  *    node 3:  0xd8000000 - 0xdfffffff
+  */
+-#define NR_NODES      4
+-
+ /*
+  * Given a kernel address, find the home node of the underlying memory.
+  */
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/serial.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/serial.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/serial.h     2003-09-27 11:38:40.117429608 +0800
+@@ -7,6 +7,8 @@
+  * This is included by serial.c -- serial_sa1100.c makes no use of it.
+  */
++#include <linux/config.h>
++
+ /* Standard COM flags */
+ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/trizeps.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/trizeps.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/trizeps.h    2003-09-27 11:38:40.119429304 +0800
+@@ -13,6 +13,8 @@
+ #ifndef _ASM_ARCH_TRIZEPS_H_
+ #define _ASM_ARCH_TRIZEPS_H_
++#include <linux/config.h>
++
+ #ifdef CONFIG_TRIZEPS_MFTB2
+ #include "mftb2.h"
+ #endif
+Index: linux-2.6.0-test5/include/asm-arm/arch-sa1100/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-sa1100/vmalloc.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-sa1100/vmalloc.h    2003-09-27 11:38:40.120429152 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-shark/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-shark/vmalloc.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-shark/vmalloc.h     2003-09-27 11:38:40.121429000 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/arch-tbox/vmalloc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/arch-tbox/vmalloc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/arch-tbox/vmalloc.h      2003-09-27 11:38:40.123428696 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-arm/bugs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/bugs.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/bugs.h   2003-09-27 11:38:40.124428544 +0800
+@@ -10,6 +10,8 @@
+ #ifndef __ASM_BUGS_H
+ #define __ASM_BUGS_H
+-#define check_bugs() do { } while (0)
++extern void check_writebuffer_bugs(void);
++
++#define check_bugs() check_writebuffer_bugs()
+ #endif
+Index: linux-2.6.0-test5/include/asm-arm/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/cacheflush.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/cacheflush.h     2003-09-27 11:38:40.128427936 +0800
+@@ -10,6 +10,7 @@
+ #ifndef _ASMARM_CACHEFLUSH_H
+ #define _ASMARM_CACHEFLUSH_H
++#include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+@@ -206,6 +207,15 @@
+ 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
+ /*
+Index: linux-2.6.0-test5/include/asm-arm/glue.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/glue.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/glue.h   2003-09-27 11:38:40.129427784 +0800
+@@ -58,7 +58,7 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_ARM720T)
++#ifdef CONFIG_CPU_ABRT_LV4T
+ # ifdef CPU_ABORT_HANDLER
+ #  define MULTI_ABORT 1
+ # else
+@@ -66,7 +66,7 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
++#ifdef CONFIG_CPU_ABRT_EV4
+ # ifdef CPU_ABORT_HANDLER
+ #  define MULTI_ABORT 1
+ # else
+@@ -74,8 +74,7 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+-    defined(CONFIG_CPU_ARM1020)
++#ifdef CONFIG_CPU_ABRT_EV4T
+ # ifdef CPU_ABORT_HANDLER
+ #  define MULTI_ABORT 1
+ # else
+@@ -83,19 +82,19 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_ARM926T)
++#ifdef CONFIG_CPU_ABRT_EV5TJ
+ # ifdef CPU_ABORT_HANDLER
+ #  define MULTI_ABORT 1
+ # else
+-#  define CPU_ABORT_HANDLER v5tej_early_abort
++#  define CPU_ABORT_HANDLER v5tj_early_abort
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_XSCALE)
++#ifdef CONFIG_CPU_ABRT_EV5T
+ # ifdef CPU_ABORT_HANDLER
+ #  define MULTI_ABORT 1
+ # else
+-#  define CPU_ABORT_HANDLER xscale_abort
++#  define CPU_ABORT_HANDLER v5t_early_abort
+ # endif
+ #endif
+Index: linux-2.6.0-test5/include/asm-arm/hardware/sa1111.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/hardware/sa1111.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/hardware/sa1111.h        2003-09-27 11:38:40.135426872 +0800
+@@ -543,7 +543,7 @@
+ #define SA1111_DEV(_d)        container_of((_d), struct sa1111_dev, dev)
+ #define sa1111_get_drvdata(d) dev_get_drvdata(&(d)->dev)
+-#define sa1111_set_drvdata(d,p)       dev_get_drvdata(&(d)->dev, p)
++#define sa1111_set_drvdata(d,p)       dev_set_drvdata(&(d)->dev, p)
+ struct sa1111_driver {
+       struct device_driver    drv;
+@@ -559,11 +559,6 @@
+ #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
+ /*
+- * Probe for a SA1111 chip.
+- */
+-extern int sa1111_init(unsigned long phys, unsigned int irq);
+-
+-/*
+  * These frob the SKPCR register.
+  */
+ void sa1111_enable_device(struct sa1111_dev *);
+Index: linux-2.6.0-test5/include/asm-arm/memory.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/memory.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/memory.h 2003-09-27 11:38:40.136426720 +0800
+@@ -84,24 +84,24 @@
+ #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 @@
+  */
+ #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.
+Index: linux-2.6.0-test5/include/asm-arm/mmu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/mmu.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/mmu.h    2003-09-27 11:38:40.138426416 +0800
+@@ -1,8 +1,6 @@
+ #ifndef __ARM_MMU_H
+ #define __ARM_MMU_H
+-#include <linux/config.h>
+-
+ typedef struct {
+ #if __LINUX_ARM_ARCH__ >= 6
+       unsigned int id;
+Index: linux-2.6.0-test5/include/asm-arm/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/numnodes.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/numnodes.h       2003-09-27 11:38:40.139426264 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-arm/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/page.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/page.h   2003-09-27 11:38:40.141425960 +0800
+@@ -44,7 +44,7 @@
+ #undef _USER
+ #undef MULTI_USER
+-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
++#ifdef CONFIG_CPU_COPY_V3
+ # ifdef _USER
+ #  define MULTI_USER 1
+ # else
+@@ -52,7 +52,7 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_ARM720T)
++#ifdef CONFIG_CPU_COPY_V4WT
+ # ifdef _USER
+ #  define MULTI_USER 1
+ # else
+@@ -60,9 +60,7 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+-    defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_SA110)   || \
+-    defined(CONFIG_CPU_ARM1020)
++#ifdef CONFIG_CPU_COPY_V4WB
+ # ifdef _USER
+ #  define MULTI_USER 1
+ # else
+@@ -70,7 +68,7 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_SA1100)
++#ifdef CONFIG_CPU_SA1100
+ # ifdef _USER
+ #  define MULTI_USER 1
+ # else
+@@ -78,7 +76,7 @@
+ # endif
+ #endif
+-#if defined(CONFIG_CPU_XSCALE)
++#ifdef CONFIG_CPU_XSCALE
+ # ifdef _USER
+ #  define MULTI_USER 1
+ # else
+Index: linux-2.6.0-test5/include/asm-arm/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/pgtable.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/pgtable.h        2003-09-27 11:38:40.145425352 +0800
+@@ -10,7 +10,6 @@
+ #ifndef _ASMARM_PGTABLE_H
+ #define _ASMARM_PGTABLE_H
+-#include <linux/config.h>
+ #include <asm/memory.h>
+ #include <asm/proc-fns.h>
+ #include <asm/arch/vmalloc.h>
+@@ -106,6 +105,7 @@
+ /*
+  *   - extended small page/tiny page
+  */
++#define PTE_EXT_AP_MASK               (3 << 4)
+ #define PTE_EXT_AP_UNO_SRO    (0 << 4)
+ #define PTE_EXT_AP_UNO_SRW    (1 << 4)
+ #define PTE_EXT_AP_URO_SRW    (2 << 4)
+@@ -115,12 +115,11 @@
+ /*
+  *   - small page
+  */
++#define PTE_SMALL_AP_MASK     (0xff << 4)
+ #define PTE_SMALL_AP_UNO_SRO  (0x00 << 4)
+ #define PTE_SMALL_AP_UNO_SRW  (0x55 << 4)
+ #define PTE_SMALL_AP_URO_SRW  (0xaa << 4)
+ #define PTE_SMALL_AP_URW_SRW  (0xff << 4)
+-#define PTE_AP_READ           PTE_SMALL_AP_URO_SRW
+-#define PTE_AP_WRITE          PTE_SMALL_AP_UNO_SRW
+ /*
+  * "Linux" PTE definitions.
+Index: linux-2.6.0-test5/include/asm-arm/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/posix_types.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/posix_types.h    2003-09-27 11:38:40.146425200 +0800
+@@ -19,7 +19,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned short                __kernel_dev_t;
+ typedef unsigned long         __kernel_ino_t;
+ typedef unsigned short                __kernel_mode_t;
+ typedef unsigned short                __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-arm/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/processor.h      2003-09-27 11:38:40.148424896 +0800
+@@ -19,7 +19,6 @@
+ #ifdef __KERNEL__
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+Index: linux-2.6.0-test5/include/asm-arm/proc-fns.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/proc-fns.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/proc-fns.h       2003-09-27 11:38:40.150424592 +0800
+@@ -26,7 +26,6 @@
+  */
+ #ifdef CONFIG_CPU_32
+-# define CPU_INCLUDE_NAME "asm/cpu-multi32.h"
+ # ifdef CONFIG_CPU_ARM610
+ #  ifdef CPU_NAME
+ #   undef  MULTI_CPU
+@@ -99,6 +98,30 @@
+ #   define CPU_NAME cpu_arm1020
+ #  endif
+ # endif
++# ifdef CONFIG_CPU_ARM1020E
++#  ifdef CPU_NAME
++#   undef  MULTI_CPU
++#   define MULTI_CPU
++#  else
++#   define CPU_NAME cpu_arm1020e
++#  endif
++# endif
++# ifdef CONFIG_CPU_ARM1022
++#  ifdef CPU_NAME
++#   undef  MULTI_CPU
++#   define MULTI_CPU
++#  else
++#   define CPU_NAME cpu_arm1022
++#  endif
++# endif
++# ifdef CONFIG_CPU_ARM1026
++#  ifdef CPU_NAME
++#   undef  MULTI_CPU
++#   define MULTI_CPU
++#  else
++#   define CPU_NAME cpu_arm1026
++#  endif
++# endif
+ # ifdef CONFIG_CPU_XSCALE
+ #  ifdef CPU_NAME
+ #   undef  MULTI_CPU
+@@ -110,11 +133,10 @@
+ #endif
+ #ifndef MULTI_CPU
+-#undef CPU_INCLUDE_NAME
+-#define CPU_INCLUDE_NAME "asm/cpu-single.h"
++#include "asm/cpu-single.h"
++#else
++#include "asm/cpu-multi32.h"
+ #endif
+-#include CPU_INCLUDE_NAME
+-
+ #endif /* __KERNEL__ */
+ #endif /* __ASM_PROCFNS_H */
+Index: linux-2.6.0-test5/include/asm-arm/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/signal.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/signal.h 2003-09-27 11:38:40.152424288 +0800
+@@ -68,7 +68,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ #define SIGSWI                32
+Index: linux-2.6.0-test5/include/asm-arm/string.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/string.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/string.h 2003-09-27 11:38:40.153424136 +0800
+@@ -25,6 +25,8 @@
+ #define __HAVE_ARCH_MEMSET
+ extern void * memset(void *, int, __kernel_size_t);
++#define __HAVE_ARCH_BCOPY
++
+ extern void __memzero(void *ptr, __kernel_size_t n);
+ #define memset(p,v,n)                                                 \
+Index: linux-2.6.0-test5/include/asm-arm/system.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/system.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/system.h 2003-09-27 11:38:40.156423680 +0800
+@@ -36,7 +36,7 @@
+ #define CR_DT (1 << 16)
+ #define CR_IT (1 << 18)
+ #define CR_ST (1 << 19)
+-#define CR_FI (1 << 21)
++#define CR_FI (1 << 21)       /* Fast interrupt (lower latency mode)  */
+ #define CR_U  (1 << 22)       /* Unaligned access operation           */
+ #define CR_XP (1 << 23)       /* Extended page tables                 */
+ #define CR_VE (1 << 24)       /* Vectored interrupts                  */
+Index: linux-2.6.0-test5/include/asm-arm/tlbflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-arm/tlbflush.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-arm/tlbflush.h       2003-09-27 11:38:40.159423224 +0800
+@@ -52,7 +52,7 @@
+ #define v3_tlb_flags  (TLB_V3_FULL | TLB_V3_PAGE)
+-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
++#ifdef CONFIG_CPU_TLB_V3
+ # define v3_possible_flags    v3_tlb_flags
+ # define v3_always_flags      v3_tlb_flags
+ # ifdef _TLB
+@@ -67,7 +67,7 @@
+ #define v4_tlb_flags  (TLB_V4_U_FULL | TLB_V4_U_PAGE)
+-#if defined(CONFIG_CPU_ARM720T)
++#ifdef CONFIG_CPU_TLB_V4WT
+ # define v4_possible_flags    v4_tlb_flags
+ # define v4_always_flags      v4_tlb_flags
+ # ifdef _TLB
+@@ -84,9 +84,7 @@
+                        TLB_V4_I_FULL | TLB_V4_D_FULL | \
+                        TLB_V4_I_PAGE | TLB_V4_D_PAGE)
+-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+-    defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \
+-    defined(CONFIG_CPU_XSCALE)
++#ifdef CONFIG_CPU_TLB_V4WBI
+ # define v4wbi_possible_flags v4wbi_tlb_flags
+ # define v4wbi_always_flags   v4wbi_tlb_flags
+ # ifdef _TLB
+@@ -103,7 +101,7 @@
+                        TLB_V4_I_FULL | TLB_V4_D_FULL | \
+                        TLB_V4_D_PAGE)
+-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
++#ifdef CONFIG_CPU_TLB_V4WB
+ # define v4wb_possible_flags  v4wb_tlb_flags
+ # define v4wb_always_flags    v4wb_tlb_flags
+ # ifdef _TLB
+@@ -121,7 +119,7 @@
+                        TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
+                        TLB_V6_I_ASID | TLB_V6_D_ASID)
+-#if defined(CONFIG_CPU_V6)
++#ifdef CONFIG_CPU_TLB_V6
+ # define v6wbi_possible_flags v6wbi_tlb_flags
+ # define v6wbi_always_flags   v6wbi_tlb_flags
+ # ifdef _TLB
+Index: linux-2.6.0-test5/include/asm-cris/arch-v10/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/arch-v10/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/arch-v10/pgtable.h      2003-09-27 11:38:40.161422920 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-cris/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/cacheflush.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/cacheflush.h    2003-09-27 11:38:40.162422768 +0800
+@@ -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);
+Index: linux-2.6.0-test5/include/asm-cris/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/posix_types.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/posix_types.h   2003-09-27 11:38:40.164422464 +0800
+@@ -14,7 +14,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned short        __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short        __kernel_mode_t;
+ typedef unsigned short        __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-cris/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-cris/signal.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-cris/signal.h        2003-09-27 11:38:40.166422160 +0800
+@@ -68,7 +68,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN        32
+-#define SIGRTMAX        (_NSIG-1)
++#define SIGRTMAX        _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-generic/cpumask_arith.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-generic/cpumask_arith.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-generic/cpumask_arith.h      2003-09-27 11:38:40.168421856 +0800
+@@ -27,7 +27,12 @@
+ #define cpus_shift_right(dst, src, n) do { dst = (src) >> (n); } while (0)
+ #define cpus_shift_left(dst, src, n)  do { dst = (src) << (n); } while (0)
+-#define any_online_cpu(map)           ({ (map) ? first_cpu(map) : NR_CPUS; })
++#define any_online_cpu(map)                   \
++({                                            \
++      cpumask_t __tmp__;                      \
++      cpus_and(__tmp__, map, cpu_online_map); \
++      __tmp__ ? first_cpu(__tmp__) : NR_CPUS; \
++})
+ #define CPU_MASK_ALL  (~((cpumask_t)0) >> (8*sizeof(cpumask_t) - NR_CPUS))
+ #define CPU_MASK_NONE ((cpumask_t)0)
+Index: linux-2.6.0-test5/include/asm-generic/cpumask_array.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-generic/cpumask_array.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-generic/cpumask_array.h      2003-09-27 11:38:40.169421704 +0800
+@@ -36,7 +36,13 @@
+                                       cpu_set(cpu, __cpu_mask);       \
+                                       __cpu_mask;                     \
+                               })
+-#define any_online_cpu(map)   find_first_bit((map).mask, NR_CPUS)
++#define any_online_cpu(map)                   \
++({                                            \
++      cpumask_t __tmp__;                      \
++      cpus_and(__tmp__, map, cpu_online_map); \
++      find_first_bit(__tmp__.mask, NR_CPUS);  \
++})
++
+ /*
+  * um, these need to be usable as static initializers
+Index: linux-2.6.0-test5/include/asm-generic/cpumask_up.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-generic/cpumask_up.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-generic/cpumask_up.h 2003-09-27 11:38:40.170421552 +0800
+@@ -6,7 +6,7 @@
+ #define cpu_set(cpu, map)             do { (void)(cpu); cpus_coerce(map) = 1UL; } while (0)
+ #define cpu_clear(cpu, map)           do { (void)(cpu); cpus_coerce(map) = 0UL; } while (0)
+ #define cpu_isset(cpu, map)           ((void)(cpu), cpus_coerce(map) != 0UL)
+-#define cpu_test_and_set(cpu, map)    ((void)(cpu), test_and_set_bit(0, (map).mask))
++#define cpu_test_and_set(cpu, map)    ((void)(cpu), test_and_set_bit(0, &(map)))
+ #define cpus_and(dst, src1, src2)                                     \
+       do {                                                            \
+Index: linux-2.6.0-test5/include/asm-h8300/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/cacheflush.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/cacheflush.h   2003-09-27 11:38:40.172421248 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-h8300/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/posix_types.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/posix_types.h  2003-09-27 11:38:40.173421096 +0800
+@@ -7,7 +7,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned short        __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short        __kernel_mode_t;
+ typedef unsigned short        __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-h8300/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/processor.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/processor.h    2003-09-27 11:38:40.175420792 +0800
+@@ -48,7 +48,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ struct thread_struct {
+Index: linux-2.6.0-test5/include/asm-h8300/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/signal.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/signal.h       2003-09-27 11:38:40.177420488 +0800
+@@ -68,7 +68,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-h8300/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-h8300/stat.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-h8300/stat.h 2003-09-27 11:38:40.179420184 +0800
+@@ -42,8 +42,7 @@
+  * insane amounts of padding around dev_t's.
+  */
+ struct stat64 {
+-      unsigned char   __pad0[6];
+-      unsigned short  st_dev;
++      unsigned long long      st_dev;
+       unsigned char   __pad1[2];
+ #define STAT64_HAS_BROKEN_ST_INO      1
+@@ -55,8 +54,7 @@
+       unsigned long   st_uid;
+       unsigned long   st_gid;
+-      unsigned char   __pad2[6];
+-      unsigned short  st_rdev;
++      unsigned long long      st_rdev;
+       unsigned char   __pad3[2];
+       long long       st_size;
+Index: linux-2.6.0-test5/include/asm-i386/atomic_kmap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/atomic_kmap.h      2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/atomic_kmap.h   2003-09-27 11:38:40.179420184 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-i386/bugs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/bugs.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/bugs.h  2003-09-27 11:38:40.182419728 +0800
+@@ -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 @@
+         : "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
+ }
+Index: linux-2.6.0-test5/include/asm-i386/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/cacheflush.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/cacheflush.h    2003-09-27 11:38:40.183419576 +0800
+@@ -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);
+Index: linux-2.6.0-test5/include/asm-i386/checksum.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/checksum.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/checksum.h      2003-09-27 11:38:40.186419120 +0800
+@@ -25,7 +25,7 @@
+  * 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 @@
+ 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 @@
+  *    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;
+Index: linux-2.6.0-test5/include/asm-i386/cpufeature.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/cpufeature.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/cpufeature.h    2003-09-27 11:38:40.188418816 +0800
+@@ -71,6 +71,8 @@
+ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+ #define X86_FEATURE_EST               (4*32+ 7) /* Enhanced SpeedStep */
++#define X86_FEATURE_MWAIT     (4*32+ 3) /* Monitor/Mwait support */
++
+ /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+ #define X86_FEATURE_XSTORE    (5*32+ 2) /* on-CPU RNG present (xstore insn) */
+Index: linux-2.6.0-test5/include/asm-i386/desc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/desc.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/desc.h  2003-09-27 11:38:40.190418512 +0800
+@@ -21,6 +21,13 @@
+ 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 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 @@
+ #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 @@
+       put_cpu();
+ }
+-#endif /* !__ASSEMBLY__ */
++#endif /* !__ASSEMBLY__ */
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/fixmap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/fixmap.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/fixmap.h        2003-09-27 11:38:40.192418208 +0800
+@@ -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 @@
+       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 @@
+               __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)
+Index: linux-2.6.0-test5/include/asm-i386/genapic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/genapic.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/genapic.h       2003-09-27 11:38:40.194417904 +0800
+@@ -30,6 +30,7 @@
+       unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
+       unsigned long (*check_apicid_present)(int apicid); 
+       int no_balance_irq;
++      int no_ioapic_check;
+       void (*init_apic_ldr)(void);
+       physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
+@@ -77,6 +78,7 @@
+       .int_dest_mode = INT_DEST_MODE, \
+       .apic_broadcast_id = APIC_BROADCAST_ID, \
+       .no_balance_irq = NO_BALANCE_IRQ, \
++      .no_ioapic_check = NO_IOAPIC_CHECK, \
+       APICFUNC(apic_id_registered), \
+       APICFUNC(target_cpus), \
+       APICFUNC(check_apicid_used), \
+Index: linux-2.6.0-test5/include/asm-i386/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/highmem.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/highmem.h       2003-09-27 11:38:40.195417752 +0800
+@@ -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 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 */
+Index: linux-2.6.0-test5/include/asm-i386/ist.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/ist.h      2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/ist.h   2003-09-27 11:38:40.196417600 +0800
+@@ -0,0 +1,32 @@
++#ifndef _ASM_IST_H
++#define _ASM_IST_H
++
++/*
++ * Include file for the interface to IST BIOS
++ * Copyright 2002 Andy Grover <andrew.grover@intel.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.
++ */
++
++
++#ifdef __KERNEL__
++
++struct ist_info {
++      unsigned long   signature;
++      unsigned long   command;
++      unsigned long   event;
++      unsigned long   perf_level;
++};
++
++extern struct ist_info ist_info;
++
++#endif        /* __KERNEL__ */
++#endif        /* _ASM_IST_H */
+Index: linux-2.6.0-test5/include/asm-i386/kgdb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kgdb.h     2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/kgdb.h  2003-09-27 11:38:40.196417600 +0800
+@@ -0,0 +1,74 @@
++#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;
++
++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 */
+Index: linux-2.6.0-test5/include/asm-i386/kgdb_local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kgdb_local.h       2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/kgdb_local.h    2003-09-27 11:38:40.196417600 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-i386/kmap_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kmap_types.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/kmap_types.h    2003-09-27 11:38:40.198417296 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-i386/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/lockmeter.h        2003-09-27 11:38:18.477719344 +0800
++++ linux-2.6.0-test5/include/asm-i386/lockmeter.h     2003-09-27 11:38:40.199417144 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-i386/mach-bigsmp/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-bigsmp/mach_apic.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-bigsmp/mach_apic.h 2003-09-27 11:38:40.200416992 +0800
+@@ -14,6 +14,8 @@
+ #define NO_BALANCE_IRQ (1)
+ #define esr_disable (1)
++#define NO_IOAPIC_CHECK (0)
++
+ static inline int apic_id_registered(void)
+ {
+       return (1);
+Index: linux-2.6.0-test5/include/asm-i386/mach-default/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-default/mach_apic.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-default/mach_apic.h        2003-09-27 11:38:40.202416688 +0800
+@@ -18,6 +18,8 @@
+ #define NO_BALANCE_IRQ (0)
+ #define esr_disable (0)
++#define NO_IOAPIC_CHECK (0)
++
+ #define INT_DELIVERY_MODE dest_LowestPrio
+ #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
+Index: linux-2.6.0-test5/include/asm-i386/mach-generic/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-generic/mach_apic.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-generic/mach_apic.h        2003-09-27 11:38:40.203416536 +0800
+@@ -5,6 +5,7 @@
+ #define esr_disable (genapic->esr_disable)
+ #define NO_BALANCE_IRQ (genapic->no_balance_irq)
++#define NO_IOAPIC_CHECK       (genapic->no_ioapic_check)
+ #define APIC_BROADCAST_ID (genapic->apic_broadcast_id)
+ #define INT_DELIVERY_MODE (genapic->int_delivery_mode)
+ #define INT_DEST_MODE (genapic->int_dest_mode)
+Index: linux-2.6.0-test5/include/asm-i386/mach-numaq/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-numaq/mach_apic.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-numaq/mach_apic.h  2003-09-27 11:38:40.205416232 +0800
+@@ -17,6 +17,8 @@
+ #define NO_BALANCE_IRQ (1)
+ #define esr_disable (1)
++#define NO_IOAPIC_CHECK (0)
++
+ #define INT_DELIVERY_MODE dest_LowestPrio
+ #define INT_DEST_MODE 0     /* physical delivery on LOCAL quad */
+  
+Index: linux-2.6.0-test5/include/asm-i386/mach-summit/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-summit/mach_apic.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-summit/mach_apic.h 2003-09-27 11:38:40.206416080 +0800
+@@ -7,14 +7,13 @@
+ #define esr_disable (1)
+ #define NO_BALANCE_IRQ (0)
+-#define XAPIC_DEST_CPUS_MASK    0x0Fu
+-#define XAPIC_DEST_CLUSTER_MASK 0xF0u
++#define NO_IOAPIC_CHECK (1)   /* Don't check I/O APIC ID for xAPIC */
+-static inline unsigned long xapic_phys_to_log_apicid(int phys_apic) 
+-{
+-      return ( (1ul << ((phys_apic) & 0x3)) |
+-               ((phys_apic) & XAPIC_DEST_CLUSTER_MASK) );
+-}
++/* In clustered mode, the high nibble of APIC ID is a cluster number.
++ * The low nibble is a 4-bit bitmap. */
++#define XAPIC_DEST_CPUS_SHIFT 4
++#define XAPIC_DEST_CPUS_MASK  ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
++#define XAPIC_DEST_CLUSTER_MASK       (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
+ #define APIC_DFR_VALUE        (APIC_DFR_CLUSTER)
+@@ -40,15 +39,29 @@
+       return 1;
+ }
+-#define apicid_cluster(apicid) (apicid & 0xF0)
++#define apicid_cluster(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK)
+ extern u8 bios_cpu_apicid[];
++extern u8 cpu_2_logical_apicid[];
+ static inline void init_apic_ldr(void)
+ {
+       unsigned long val, id;
+-
+-      id = xapic_phys_to_log_apicid(hard_smp_processor_id());
++      int i, count;
++      u8 lid;
++      u8 my_id = (u8)hard_smp_processor_id();
++      u8 my_cluster = (u8)apicid_cluster(my_id);
++
++      /* Create logical APIC IDs by counting CPUs already in cluster. */
++      for (count = 0, i = NR_CPUS; --i >= 0; ) {
++              lid = cpu_2_logical_apicid[i];
++              if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster)
++                      ++count;
++      }
++      /* We only have a 4 wide bitmap in cluster mode.  If a deranged
++       * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
++      BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
++      id = my_cluster | (1UL << count);
+       apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+       val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+       val |= SET_APIC_LOGICAL_ID(id);
+@@ -77,7 +90,6 @@
+ }
+ /* Mapping from cpu number to logical apicid */
+-extern u8 cpu_2_logical_apicid[];
+ static inline int cpu_to_logical_apicid(int cpu)
+ {
+        if (cpu >= NR_CPUS)
+Index: linux-2.6.0-test5/include/asm-i386/mach-visws/mach_apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-visws/mach_apic.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-visws/mach_apic.h  2003-09-27 11:38:40.208415776 +0800
+@@ -8,6 +8,8 @@
+ #define no_balance_irq (0)
+ #define esr_disable (0)
++#define NO_IOAPIC_CHECK (0)
++
+ #define INT_DELIVERY_MODE dest_LowestPrio
+ #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
+Index: linux-2.6.0-test5/include/asm-i386/mmu_context.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mmu_context.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mmu_context.h   2003-09-27 11:38:40.209415624 +0800
+@@ -29,6 +29,10 @@
+ {
+       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 @@
+               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 @@
+                       /* 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 @@
+       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
+Index: linux-2.6.0-test5/include/asm-i386/mmu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mmu.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mmu.h   2003-09-27 11:38:40.210415472 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-i386/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mmzone.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mmzone.h        2003-09-27 11:38:40.212415168 +0800
+@@ -119,14 +119,32 @@
+ #ifdef CONFIG_X86_NUMAQ
+ #include <asm/numaq.h>
+-#elif CONFIG_NUMA     /* summit or generic arch */
++#elif CONFIG_ACPI_SRAT
+ #include <asm/srat.h>
+ #elif CONFIG_X86_PC
+-#define get_memcfg_numa get_memcfg_numa_flat
+ #define get_zholes_size(n) (0)
+ #else
+ #define pfn_to_nid(pfn)               (0)
+ #endif /* CONFIG_X86_NUMAQ */
++extern int get_memcfg_numa_flat(void );
++/*
++ * This allows any one NUMA architecture to be compiled
++ * for, and still fall back to the flat function if it
++ * fails.
++ */
++static inline void get_memcfg_numa(void)
++{
++#ifdef CONFIG_X86_NUMAQ
++      if (get_memcfg_numaq())
++              return;
++#elif CONFIG_ACPI_SRAT
++      if (get_memcfg_from_srat())
++              return;
++#endif
++
++      get_memcfg_numa_flat();
++}
++
+ #endif /* CONFIG_DISCONTIGMEM */
+ #endif /* _ASM_MMZONE_H_ */
+Index: linux-2.6.0-test5/include/asm-i386/numaq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/numaq.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/numaq.h 2003-09-27 11:38:40.214414864 +0800
+@@ -28,9 +28,7 @@
+ #ifdef CONFIG_X86_NUMAQ
+-#define MAX_NUMNODES          16
+-extern void get_memcfg_numaq(void);
+-#define get_memcfg_numa() get_memcfg_numaq()
++extern int get_memcfg_numaq(void);
+ /*
+  * SYS_CFG_DATA_PRIV_ADDR, struct eachquadmem, and struct sys_cfg_data are the
+Index: linux-2.6.0-test5/include/asm-i386/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/numnodes.h      2003-09-27 11:38:40.215414712 +0800
+@@ -4,11 +4,15 @@
+ #include <linux/config.h>
+ #ifdef CONFIG_X86_NUMAQ
+-#include <asm/numaq.h>
+-#elif CONFIG_NUMA
+-#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 */
+Index: linux-2.6.0-test5/include/asm-i386/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/page.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/page.h  2003-09-27 11:38:40.217414408 +0800
+@@ -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 @@
+  *
+  * 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 @@
+ #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)
+Index: linux-2.6.0-test5/include/asm-i386/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/pgtable.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/pgtable.h       2003-09-27 11:38:40.220413952 +0800
+@@ -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 @@
+  * 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 @@
+ #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 @@
+ #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 @@
+ #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)
+ {
+Index: linux-2.6.0-test5/include/asm-i386/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/posix_types.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/posix_types.h   2003-09-27 11:38:40.222413648 +0800
+@@ -7,7 +7,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned short        __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short        __kernel_mode_t;
+ typedef unsigned short        __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-i386/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/processor.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/processor.h     2003-09-27 11:38:40.226413040 +0800
+@@ -260,11 +260,6 @@
+  * Bus types (default is ISA, but people can check others with these..)
+  * pc98 indicates PC98 systems (CBUS)
+  */
+-#ifdef CONFIG_EISA
+-extern int EISA_bus;
+-#else
+-#define EISA_bus (0)
+-#endif
+ extern int MCA_bus;
+ #ifdef CONFIG_X86_PC9800
+ #define pc98 1
+@@ -272,6 +267,22 @@
+ #define pc98 0
+ #endif
++static inline void __monitor(const void *eax, unsigned long ecx,
++              unsigned long edx)
++{
++      /* "monitor %eax,%ecx,%edx;" */
++      asm volatile(
++              ".byte 0x0f,0x01,0xc8;"
++              : :"a" (eax), "c" (ecx), "d"(edx));
++}
++
++static inline void __mwait(unsigned long eax, unsigned long ecx)
++{
++      /* "mwait %eax,%ecx;" */
++      asm volatile(
++              ".byte 0x0f,0x01,0xc9;"
++              : :"a" (eax), "c" (ecx));
++}
+ /* from system description table in BIOS.  Mostly for MCA use, but
+ others may find it useful. */
+@@ -280,11 +291,6 @@
+ 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.
+  */
+@@ -395,6 +401,7 @@
+ 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;
+@@ -480,6 +487,13 @@
+  */
+ 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);
+@@ -578,8 +592,6 @@
+ #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,
+@@ -601,4 +613,6 @@
+ }
+ #define spin_lock_prefetch(x) prefetchw(x)
++extern void select_idle_routine(const struct cpuinfo_x86 *c);
++
+ #endif /* __ASM_I386_PROCESSOR_H */
+Index: linux-2.6.0-test5/include/asm-i386/rwlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/rwlock.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/rwlock.h        2003-09-27 11:38:40.228412736 +0800
+@@ -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)) \
+Index: linux-2.6.0-test5/include/asm-i386/setup.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/setup.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/setup.h 2003-09-27 11:38:40.229412584 +0800
+@@ -26,6 +26,7 @@
+ #define E820_MAP_NR (*(char*) (PARAM+E820NR))
+ #define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
+ #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
++#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 MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
+Index: linux-2.6.0-test5/include/asm-i386/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/signal.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/signal.h        2003-09-27 11:38:40.232412128 +0800
+@@ -70,7 +70,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-i386/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/spinlock.h      2003-09-27 11:38:40.234411824 +0800
+@@ -43,18 +43,35 @@
+ #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 @@
+  */
+ 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 @@
+ #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 @@
+       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 */
+Index: linux-2.6.0-test5/include/asm-i386/srat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/srat.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/srat.h  2003-09-27 11:38:40.236411520 +0800
+@@ -27,9 +27,11 @@
+ #ifndef _ASM_SRAT_H_
+ #define _ASM_SRAT_H_
+-#define MAX_NUMNODES          8
+-extern void get_memcfg_from_srat(void);
++#ifndef CONFIG_ACPI_SRAT
++#error CONFIG_ACPI_SRAT not defined, and srat.h header has been included
++#endif
++
++extern int get_memcfg_from_srat(void);
+ extern unsigned long *get_zholes_size(int);
+-#define get_memcfg_numa() get_memcfg_from_srat()
+ #endif /* _ASM_SRAT_H_ */
+Index: linux-2.6.0-test5/include/asm-i386/string.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/string.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/string.h        2003-09-27 11:38:40.239411064 +0800
+@@ -56,6 +56,29 @@
+ 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)
+ {
+Index: linux-2.6.0-test5/include/asm-i386/suspend.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/suspend.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/suspend.h       2003-09-27 11:38:40.241410760 +0800
+@@ -6,11 +6,12 @@
+ #include <asm/desc.h>
+ #include <asm/i387.h>
+-static inline void
++static inline int
+ arch_prepare_suspend(void)
+ {
+       if (!cpu_has_pse)
+-              panic("pse required");
++              return -EPERM;
++      return 0;
+ }
+ /* image of the saved processor state */
+@@ -38,8 +39,6 @@
+ extern void save_processor_state(void);
+ extern void restore_processor_state(void);
+-extern int do_magic(int resume);
+-
+ #ifdef CONFIG_ACPI_SLEEP
+ extern unsigned long saved_eip;
+ extern unsigned long saved_esp;
+Index: linux-2.6.0-test5/include/asm-i386/thread_info.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/thread_info.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/thread_info.h   2003-09-27 11:38:40.243410456 +0800
+@@ -33,23 +33,12 @@
+                                                  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 @@
+  */
+ #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 @@
+       .restart_block = {                      \
+               .fn = do_no_restart_syscall,    \
+       },                                      \
++      .real_stack     = &thread_info,         \
+ }
+ #define init_thread_info      (init_thread_union.thread_info)
+@@ -113,6 +103,7 @@
+ #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 @@
+ #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 */
+Index: linux-2.6.0-test5/include/asm-i386/timer.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/timer.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/timer.h 2003-09-27 11:38:40.244410304 +0800
+@@ -38,8 +38,10 @@
+ extern struct timer_opts timer_cyclone;
+ #endif
++extern unsigned long calibrate_tsc(void);
+ #ifdef CONFIG_HPET_TIMER
+ extern struct timer_opts timer_hpet;
++extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr);
+ #endif
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/tlbflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/tlbflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/tlbflush.h      2003-09-27 11:38:40.246410000 +0800
+@@ -85,22 +85,28 @@
+ 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 @@
+       __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)
+ {
+Index: linux-2.6.0-test5/include/asm-i386/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/uaccess.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/uaccess.h       2003-09-27 11:38:40.251409240 +0800
+@@ -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)
+@@ -80,7 +80,7 @@
+  * checks that the pointer is in the user space range - after calling
+  * this function, memory access functions may still return -EFAULT.
+  */
+-#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
++#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
+ /**
+  * verify_area: - Obsolete, use access_ok()
+@@ -149,6 +149,45 @@
+               :"=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 @@
+  * 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 @@
+  *
+  * 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 @@
+  * 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 @@
+  *
+  * 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 @@
+  * 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 @@
+  * 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 @@
+  * 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 @@
+  * 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 @@
+  * 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 */
+Index: linux-2.6.0-test5/include/asm-ia64/acpi.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/acpi.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/acpi.h  2003-09-27 11:38:40.253408936 +0800
+@@ -30,6 +30,8 @@
+ #ifdef __KERNEL__
++#include <asm/system.h>
++
+ #define COMPILER_DEPENDENT_INT64      long
+ #define COMPILER_DEPENDENT_UINT64     unsigned long
+@@ -54,47 +56,35 @@
+ #define ACPI_ENABLE_IRQS()  local_irq_enable()
+ #define ACPI_FLUSH_CPU_CACHE()
+-#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+-      do { \
+-      __asm__ volatile ("1:  ld4      r29=[%1]\n"  \
+-              ";;\n"                  \
+-              "mov    ar.ccv=r29\n"   \
+-              "mov    r2=r29\n"       \
+-              "shr.u  r30=r29,1\n"    \
+-              "and    r29=-4,r29\n"   \
+-              ";;\n"                  \
+-              "add    r29=2,r29\n"    \
+-              "and    r30=1,r30\n"    \
+-              ";;\n"                  \
+-              "add    r29=r29,r30\n"  \
+-              ";;\n"                  \
+-              "cmpxchg4.acq   r30=[%1],r29,ar.ccv\n" \
+-              ";;\n"                  \
+-              "cmp.eq p6,p7=r2,r30\n" \
+-              "(p7) br.dpnt.few 1b\n" \
+-              "cmp.gt p8,p9=3,r29\n"  \
+-              ";;\n"                  \
+-              "(p8) mov %0=-1\n"      \
+-              "(p9) mov %0=r0\n"      \
+-              :"=r"(Acq):"r"(GLptr):"r2","r29","r30","memory"); \
+-      } while (0)
+-
+-#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+-      do { \
+-      __asm__ volatile ("1:  ld4      r29=[%1]\n" \
+-              ";;\n"                  \
+-              "mov    ar.ccv=r29\n"   \
+-              "mov    r2=r29\n"       \
+-              "and    r29=-4,r29\n"   \
+-              ";;\n"                  \
+-              "cmpxchg4.acq   r30=[%1],r29,ar.ccv\n" \
+-              ";;\n"                  \
+-              "cmp.eq p6,p7=r2,r30\n" \
+-              "(p7) br.dpnt.few 1b\n" \
+-              "and    %0=1,r2\n"      \
+-              ";;\n"                  \
+-              :"=r"(Acq):"r"(GLptr):"r2","r29","r30","memory"); \
+-      } while (0)
++static inline int
++ia64_acpi_acquire_global_lock (unsigned int *lock)
++{
++      unsigned int old, new, val;
++      do {
++              old = *lock;
++              new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
++              val = ia64_cmpxchg4_acq(lock, new, old);
++      } while (unlikely (val != old));
++      return (new < 3) ? -1 : 0;
++}
++
++static inline int
++ia64_acpi_release_global_lock (unsigned int *lock)
++{
++      unsigned int old, new, val;
++      do {
++              old = *lock;
++              new = old & ~0x3;
++              val = ia64_cmpxchg4_acq(lock, new, old);
++      } while (unlikely (val != old));
++      return old & 0x1;
++}
++
++#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq)                          \
++      ((Acq) = ia64_acpi_acquire_global_lock((unsigned int *) GLptr))
++
++#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq)                          \
++      ((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr))
+ const char *acpi_get_sysname (void);
+ int acpi_request_vector (u32 int_type);
+@@ -109,7 +99,7 @@
+ /* 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__*/
+Index: linux-2.6.0-test5/include/asm-ia64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/cacheflush.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/cacheflush.h    2003-09-27 11:38:40.254408784 +0800
+@@ -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 @@
+       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 */
+Index: linux-2.6.0-test5/include/asm-ia64/hw_irq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/hw_irq.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/hw_irq.h        2003-09-27 11:38:40.257408328 +0800
+@@ -9,6 +9,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+ #include <linux/types.h>
++#include <linux/profile.h>
+ #include <asm/machvec.h>
+ #include <asm/ptrace.h>
+Index: linux-2.6.0-test5/include/asm-ia64/intel_intrin.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/intel_intrin.h     2003-09-27 11:38:18.478719192 +0800
++++ linux-2.6.0-test5/include/asm-ia64/intel_intrin.h  2003-09-27 11:38:40.258408176 +0800
+@@ -0,0 +1,254 @@
++#ifndef _ASM_IA64_INTEL_INTRIN_H
++#define _ASM_IA64_INTEL_INTRIN_H
++/*
++ * Intel Compiler Intrinsics
++ *
++ * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
++ * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
++ *
++ */
++#include <asm/types.h>
++
++void  __lfetch(int lfhint, void *y);
++void  __lfetch_excl(int lfhint, void *y);
++void  __lfetch_fault(int lfhint, void *y);
++void  __lfetch_fault_excl(int lfhint, void *y);
++
++/* In the following, whichFloatReg should be an integer from 0-127 */
++void  __ldfs(const int whichFloatReg, void *src);
++void  __ldfd(const int whichFloatReg, void *src);
++void  __ldfe(const int whichFloatReg, void *src);
++void  __ldf8(const int whichFloatReg, void *src);
++void  __ldf_fill(const int whichFloatReg, void *src);
++void  __stfs(void *dst, const int whichFloatReg);
++void  __stfd(void *dst, const int whichFloatReg);
++void  __stfe(void *dst, const int whichFloatReg);
++void  __stf8(void *dst, const int whichFloatReg);
++void  __stf_spill(void *dst, const int whichFloatReg);
++
++void  __st1_rel(void *dst, const __s8  value);
++void  __st2_rel(void *dst, const __s16 value);
++void  __st4_rel(void *dst, const __s32 value);
++void  __st8_rel(void *dst, const __s64 value);
++__u8  __ld1_acq(void *src);
++__u16 __ld2_acq(void *src);
++__u32 __ld4_acq(void *src);
++__u64 __ld8_acq(void *src);
++
++__u64 __fetchadd4_acq(__u32 *addend, const int increment);
++__u64 __fetchadd4_rel(__u32 *addend, const int increment);
++__u64 __fetchadd8_acq(__u64 *addend, const int increment);
++__u64 __fetchadd8_rel(__u64 *addend, const int increment);
++
++__u64 __getf_exp(double d);
++
++/* OS Related Itanium(R) Intrinsics  */
++
++/* The names to use for whichReg and whichIndReg below come from
++   the include file asm/ia64regs.h */
++
++__u64 __getIndReg(const int whichIndReg, __s64 index);
++__u64 __getReg(const int whichReg);
++
++void  __setIndReg(const int whichIndReg, __s64 index, __u64 value);
++void  __setReg(const int whichReg, __u64 value);
++
++void  __mf(void);
++void  __mfa(void);
++void  __synci(void);
++void  __itcd(__s64 pa);
++void  __itci(__s64 pa);
++void  __itrd(__s64 whichTransReg, __s64 pa);
++void  __itri(__s64 whichTransReg, __s64 pa);
++void  __ptce(__s64 va);
++void  __ptcl(__s64 va, __s64 pagesz);
++void  __ptcg(__s64 va, __s64 pagesz);
++void  __ptcga(__s64 va, __s64 pagesz);
++void  __ptri(__s64 va, __s64 pagesz);
++void  __ptrd(__s64 va, __s64 pagesz);
++void  __invala (void);
++void  __invala_gr(const int whichGeneralReg /* 0-127 */ );
++void  __invala_fr(const int whichFloatReg /* 0-127 */ );
++void  __nop(const int);
++void  __fc(__u64 *addr);
++void  __sum(int mask);
++void  __rum(int mask);
++void  __ssm(int mask);
++void  __rsm(int mask);
++__u64 __thash(__s64);
++__u64 __ttag(__s64);
++__s64 __tpa(__s64);
++
++/* Intrinsics for implementing get/put_user macros */
++void __st_user(const char *tableName, __u64 addr, char size, char relocType, __u64 val);
++void __ld_user(const char *tableName, __u64 addr, char size, char relocType);
++
++/* This intrinsic does not generate code, it creates a barrier across which
++ * the compiler will not schedule data access instructions.
++ */
++void __memory_barrier(void);
++
++void __isrlz(void);
++void __dsrlz(void);
++
++__u64  _m64_mux1(__u64 a, const int n);
++__u64  __thash(__u64);
++
++/* Lock and Atomic Operation Related Intrinsics */
++__u64 _InterlockedExchange8(volatile __u8 *trgt, __u8 value);
++__u64 _InterlockedExchange16(volatile __u16 *trgt, __u16 value);
++__s64 _InterlockedExchange(volatile __u32 *trgt, __u32 value);
++__s64 _InterlockedExchange64(volatile __u64 *trgt, __u64 value);
++
++__u64 _InterlockedCompareExchange8_rel(volatile __u8 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange8_acq(volatile __u8 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange16_rel(volatile __u16 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange16_acq(volatile __u16 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange_rel(volatile __u32 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange_acq(volatile __u32 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange64_rel(volatile __u64 *dest, __u64 xchg, __u64 comp);
++__u64 _InterlockedCompareExchange64_acq(volatile __u64 *dest, __u64 xchg, __u64 comp);
++
++__s64 _m64_dep_mi(const int v, __s64 s, const int p, const int len);
++__s64 _m64_shrp(__s64 a, __s64 b, const int count);
++__s64 _m64_popcnt(__s64 a);
++
++#define ia64_barrier()                __memory_barrier()
++
++#define ia64_stop()   /* Nothing: As of now stop bit is generated for each
++                       * intrinsic
++                       */
++
++#define ia64_getreg           __getReg
++#define ia64_setreg           __setReg
++
++#define ia64_hint(x)
++
++#define ia64_mux1_brcst        0
++#define ia64_mux1_mix          8
++#define ia64_mux1_shuf                 9
++#define ia64_mux1_alt         10
++#define ia64_mux1_rev         11
++
++#define ia64_mux1             _m64_mux1
++#define ia64_popcnt           _m64_popcnt
++#define ia64_getf_exp         __getf_exp
++#define ia64_shrp             _m64_shrp
++
++#define ia64_tpa              __tpa
++#define ia64_invala           __invala
++#define ia64_invala_gr                __invala_gr
++#define ia64_invala_fr                __invala_fr
++#define ia64_nop              __nop
++#define ia64_sum              __sum
++#define ia64_ssm              __ssm
++#define ia64_rum              __rum
++#define ia64_rsm              __rsm
++#define ia64_fc               __fc
++
++#define ia64_ldfs             __ldfs
++#define ia64_ldfd             __ldfd
++#define ia64_ldfe             __ldfe
++#define ia64_ldf8             __ldf8
++#define ia64_ldf_fill         __ldf_fill
++
++#define ia64_stfs             __stfs
++#define ia64_stfd             __stfd
++#define ia64_stfe             __stfe
++#define ia64_stf8             __stf8
++#define ia64_stf_spill                __stf_spill
++
++#define ia64_mf               __mf
++#define ia64_mfa              __mfa
++
++#define ia64_fetchadd4_acq    __fetchadd4_acq
++#define ia64_fetchadd4_rel    __fetchadd4_rel
++#define ia64_fetchadd8_acq    __fetchadd8_acq
++#define ia64_fetchadd8_rel    __fetchadd8_rel
++
++#define ia64_xchg1            _InterlockedExchange8
++#define ia64_xchg2            _InterlockedExchange16
++#define ia64_xchg4            _InterlockedExchange
++#define ia64_xchg8            _InterlockedExchange64
++
++#define ia64_cmpxchg1_rel     _InterlockedCompareExchange8_rel
++#define ia64_cmpxchg1_acq     _InterlockedCompareExchange8_acq
++#define ia64_cmpxchg2_rel     _InterlockedCompareExchange16_rel
++#define ia64_cmpxchg2_acq     _InterlockedCompareExchange16_acq
++#define ia64_cmpxchg4_rel     _InterlockedCompareExchange_rel
++#define ia64_cmpxchg4_acq     _InterlockedCompareExchange_acq
++#define ia64_cmpxchg8_rel     _InterlockedCompareExchange64_rel
++#define ia64_cmpxchg8_acq     _InterlockedCompareExchange64_acq
++
++#define __ia64_set_dbr(index, val)    \
++              __setIndReg(_IA64_REG_INDR_DBR, index, val)
++#define ia64_set_ibr(index, val)      \
++              __setIndReg(_IA64_REG_INDR_IBR, index, val)
++#define ia64_set_pkr(index, val)      \
++              __setIndReg(_IA64_REG_INDR_PKR, index, val)
++#define ia64_set_pmc(index, val)      \
++              __setIndReg(_IA64_REG_INDR_PMC, index, val)
++#define ia64_set_pmd(index, val)      \
++              __setIndReg(_IA64_REG_INDR_PMD, index, val)
++#define ia64_set_rr(index, val)       \
++              __setIndReg(_IA64_REG_INDR_RR, index, val)
++
++#define ia64_get_cpuid(index)         __getIndReg(_IA64_REG_INDR_CPUID, index)
++#define __ia64_get_dbr(index)         __getIndReg(_IA64_REG_INDR_DBR, index)
++#define ia64_get_ibr(index)   __getIndReg(_IA64_REG_INDR_IBR, index)
++#define ia64_get_pkr(index)   __getIndReg(_IA64_REG_INDR_PKR, index)
++#define ia64_get_pmc(index)   __getIndReg(_IA64_REG_INDR_PMC, index)
++#define ia64_get_pmd(index)   __getIndReg(_IA64_REG_INDR_PMD, index)
++#define ia64_get_rr(index)    __getIndReg(_IA64_REG_INDR_RR, index)
++
++#define ia64_srlz_d           __dsrlz
++#define ia64_srlz_i           __isrlz
++
++#define ia64_st1_rel          __st1_rel
++#define ia64_st2_rel          __st2_rel
++#define ia64_st4_rel          __st4_rel
++#define ia64_st8_rel          __st8_rel
++
++#define ia64_ld1_acq          __ld1_acq
++#define ia64_ld2_acq          __ld2_acq
++#define ia64_ld4_acq          __ld4_acq
++#define ia64_ld8_acq          __ld8_acq
++
++#define ia64_sync_i           __synci
++#define ia64_thash            __thash
++#define ia64_ttag             __ttag
++#define ia64_itcd             __itcd
++#define ia64_itci             __itci
++#define ia64_itrd             __itrd
++#define ia64_itri             __itri
++#define ia64_ptce             __ptce
++#define ia64_ptcl             __ptcl
++#define ia64_ptcg             __ptcg
++#define ia64_ptcga            __ptcga
++#define ia64_ptri             __ptri
++#define ia64_ptrd             __ptrd
++#define ia64_dep_mi           _m64_dep_mi
++
++/* Values for lfhint in __lfetch and __lfetch_fault */
++
++#define ia64_lfhint_none      0
++#define ia64_lfhint_nt1       1
++#define ia64_lfhint_nt2       2
++#define ia64_lfhint_nta       3
++
++#define ia64_lfetch           __lfetch
++#define ia64_lfetch_excl      __lfetch_excl
++#define ia64_lfetch_fault     __lfetch_fault
++#define ia64_lfetch_fault_excl        __lfetch_fault_excl
++
++#define ia64_intrin_local_irq_restore(x)              \
++do {                                                  \
++      if ((x) != 0) {                                 \
++              ia64_ssm(IA64_PSR_I);                   \
++              ia64_srlz_d();                          \
++      } else {                                        \
++              ia64_rsm(IA64_PSR_I);                   \
++      }                                               \
++} while (0)
++
++#endif /* _ASM_IA64_INTEL_INTRIN_H */
+Index: linux-2.6.0-test5/include/asm-ia64/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/lockmeter.h        2003-09-27 11:38:18.478719192 +0800
++++ linux-2.6.0-test5/include/asm-ia64/lockmeter.h     2003-09-27 11:38:40.258408176 +0800
+@@ -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 */
++
+Index: linux-2.6.0-test5/include/asm-ia64/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/mmzone.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/mmzone.h        2003-09-27 11:38:40.261407720 +0800
+@@ -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 @@
+ # 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 @@
+ #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 */
+Index: linux-2.6.0-test5/include/asm-ia64/nodedata.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/nodedata.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/nodedata.h      2003-09-27 11:38:40.262407568 +0800
+@@ -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 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];
+ };
+Index: linux-2.6.0-test5/include/asm-ia64/numa.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/numa.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/numa.h  2003-09-27 11:38:40.264407264 +0800
+@@ -13,17 +13,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 unsigned long 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 */
+@@ -57,7 +51,7 @@
+  * 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);
+Index: linux-2.6.0-test5/include/asm-ia64/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/numnodes.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/numnodes.h      2003-09-27 11:38:40.265407112 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-ia64/param.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/param.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/param.h 2003-09-27 11:38:40.267406808 +0800
+@@ -4,22 +4,10 @@
+ /*
+  * Fundamental kernel parameters.
+  *
+- * 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/config.h>
+-
+-#ifdef CONFIG_IA64_HP_SIM
+-/*
+- * Yeah, simulating stuff is slow, so let us catch some breath between
+- * timer interrupts...
+- */
+-# define HZ     32
+-#else
+-# define HZ   1024
+-#endif
+-
+ #define EXEC_PAGESIZE 65536
+ #ifndef NGROUPS
+@@ -33,8 +21,24 @@
+ #define MAXHOSTNAMELEN        64      /* max length of hostname */
+ #ifdef __KERNEL__
++# include <linux/config.h>    /* mustn't include <linux/config.h> outside of #ifdef __KERNEL__ */
++# ifdef CONFIG_IA64_HP_SIM
++  /*
++   * Yeah, simulating stuff is slow, so let us catch some breath between
++   * timer interrupts...
++   */
++#  define HZ    32
++# else
++#  define HZ  1024
++# endif
+ # define USER_HZ      HZ
+ # define CLOCKS_PER_SEC       HZ      /* frequency at which times() counts */
++#else
++   /*
++    * Technically, this is wrong, but some old apps still refer to it.  The proper way to
++    * get the HZ value is via sysconf(_SC_CLK_TCK).
++    */
++# define HZ 1024
+ #endif
+ #endif /* _ASM_IA64_PARAM_H */
+Index: linux-2.6.0-test5/include/asm-ia64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/pgtable.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/pgtable.h       2003-09-27 11:38:40.272406048 +0800
+@@ -207,7 +207,6 @@
+ #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
+Index: linux-2.6.0-test5/include/asm-ia64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/posix_types.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/posix_types.h   2003-09-27 11:38:40.273405896 +0800
+@@ -10,7 +10,6 @@
+  *    David Mosberger-Tang <davidm@hpl.hp.com>
+  */
+-typedef unsigned int  __kernel_dev_t;
+ typedef unsigned int  __kernel_ino_t;
+ typedef unsigned int  __kernel_mode_t;
+ typedef unsigned int  __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-ia64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/processor.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/processor.h     2003-09-27 11:38:40.279404984 +0800
+@@ -56,7 +56,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-ia64/ptrace.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/ptrace.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/ptrace.h        2003-09-27 11:38:40.282404528 +0800
+@@ -223,6 +223,12 @@
+ };
+ #ifdef __KERNEL__
++/*
++ * We use the ia64_psr(regs)->ri to determine which of the three
++ * instructions in bundle (16 bytes) took the sample. Generate
++ * the canonical representation by adding to instruction pointer.
++ */
++# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
+   /* given a pointer to a task_struct, return the user's pt_regs */
+ # define ia64_task_regs(t)            (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
+ # define ia64_psr(regs)                       ((struct ia64_psr *) &(regs)->cr_ipsr)
+Index: linux-2.6.0-test5/include/asm-ia64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/signal.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/signal.h        2003-09-27 11:38:40.284404224 +0800
+@@ -2,7 +2,7 @@
+ #define _ASM_IA64_SIGNAL_H
+ /*
+- * Copyright (C) 1998-2001 Hewlett-Packard Co
++ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+  *    David Mosberger-Tang <davidm@hpl.hp.com>
+  *
+  * Unfortunately, this file is being included by bits/signal.h in
+@@ -50,7 +50,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+@@ -96,7 +96,16 @@
+  * ar.rsc.loadrs is 14 bits, we can assume that they'll never take up
+  * more than 16KB of space.
+  */
+-#define MINSIGSTKSZ   131027  /* min. stack size for sigaltstack() */
++#if 1
++  /*
++   * This is a stupid typo: the value was _meant_ to be 131072 (0x20000), but I typed it
++   * in wrong. ;-(  To preserve backwards compatibility, we leave the kernel at the
++   * incorrect value and fix libc only.
++   */
++# define MINSIGSTKSZ  131027  /* min. stack size for sigaltstack() */
++#else
++# define MINSIGSTKSZ  131072  /* min. stack size for sigaltstack() */
++#endif
+ #define SIGSTKSZ      262144  /* default stack size for sigaltstack() */
+ #ifdef __KERNEL__
+Index: linux-2.6.0-test5/include/asm-ia64/sn/hcl.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/hcl.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/hcl.h        2003-09-27 11:38:40.287403768 +0800
+@@ -10,6 +10,7 @@
+ #define _ASM_IA64_SN_HCL_H
+ #include <asm/sn/sgi.h>
++#include <asm/sn/invent.h>
+ extern vertex_hdl_t hwgraph_root;
+ extern vertex_hdl_t linux_busnum;
+Index: linux-2.6.0-test5/include/asm-ia64/sn/ksys/elsc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/ksys/elsc.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/ksys/elsc.h  2003-09-27 11:38:40.288403616 +0800
+@@ -9,9 +9,6 @@
+ #ifndef _ASM_SN_KSYS_ELSC_H
+ #define _ASM_SN_KSYS_ELSC_H
+-#include <linux/config.h>
+-#include <asm/sn/ksys/l1.h>
+-
+ /*
+  * Error codes
+  *
+Index: linux-2.6.0-test5/include/asm-ia64/sn/ksys/l1.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/ksys/l1.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/ksys/l1.h    2003-09-27 11:38:40.291403160 +0800
+@@ -10,10 +10,7 @@
+ #ifndef _ASM_SN_KSYS_L1_H
+ #define _ASM_SN_KSYS_L1_H
+-#include <linux/config.h>
+-#include <asm/sn/vector.h>
+-#include <asm/sn/addrs.h>
+-#include <asm/atomic.h>
++#include <asm/sn/types.h>
+ /* L1 Target Addresses */
+ /*
+@@ -39,18 +36,6 @@
+ #define L1_ADDR_TASK_BEDROCK  0x05    /* bedrock              */
+ #define L1_ADDR_TASK_GENERAL  0x06    /* general requests     */
+-#define L1_ADDR_LOCAL                         \
+-    (L1_ADDR_TYPE_L1 << L1_ADDR_TYPE_SHFT) |  \
+-    (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) |       \
+-    (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)
+-
+-#define L1_ADDR_LOCALIO                                       \
+-    (L1_ADDR_TYPE_IOBRICK << L1_ADDR_TYPE_SHFT) |     \
+-    (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) |               \
+-    (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)
+-
+-#define L1_ADDR_LOCAL_SHFT    L1_ADDR_BAY_SHFT
+-
+ /* response argument types */
+ #define L1_ARG_INT            0x00    /* 4-byte integer (big-endian)  */
+ #define L1_ARG_ASCII          0x01    /* null-terminated ASCII string */
+@@ -133,18 +118,6 @@
+ #define L1_EEP_IUSE           3       /* internal use area */
+ #define L1_EEP_SPD            4       /* serial presence detect record */
+-typedef uint32_t l1addr_t;
+-
+-#define L1_BUILD_ADDR(addr,at,r,s,t)                                  \
+-    (*(l1addr_t *)(addr) = ((l1addr_t)(at) << L1_ADDR_TYPE_SHFT) |    \
+-                           ((l1addr_t)(r)  << L1_ADDR_RACK_SHFT) |    \
+-                           ((l1addr_t)(s)  << L1_ADDR_BAY_SHFT) |     \
+-                           ((l1addr_t)(t)  << L1_ADDR_TASK_SHFT))
+-
+-#define L1_ADDRESS_TO_TASK(addr,trb,tsk)                              \
+-    (*(l1addr_t *)(addr) = (l1addr_t)(trb) |                          \
+-                           ((l1addr_t)(tsk) << L1_ADDR_TASK_SHFT))
+-
+ #define L1_DISPLAY_LINE_LENGTH        12      /* L1 display characters/line */
+ #ifdef L1_DISP_2LINES
+@@ -154,11 +127,9 @@
+                                        * to system software */
+ #endif
+-#define bzero(d, n)   memset((d), 0, (n))
+-
+ int   elsc_display_line(nasid_t nasid, char *line, int lnum);
+-int   iobrick_rack_bay_type_get( nasid_t nasid, uint *rack,
+-                                 uint *bay, uint *brick_type );
++int   iobrick_rack_bay_type_get( nasid_t nasid, unsigned int *rack,
++                                 unsigned int *bay, unsigned int *brick_type );
+ int   iobrick_module_get( nasid_t nasid );
+Index: linux-2.6.0-test5/include/asm-ia64/sn/nodepda.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/nodepda.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/nodepda.h    2003-09-27 11:38:40.292403008 +0800
+@@ -87,7 +87,7 @@
+       char irq_flags[NR_IRQS];
+       struct pci_dev *device_dev[NR_IRQS];
+       char share_count[NR_IRQS];
+-      struct pci_dev *current;
++      struct pci_dev *curr;
+ };
+ typedef struct irqpda_s irqpda_t;
+@@ -128,7 +128,7 @@
+  * Check if given a compact node id the corresponding node has all the
+  * cpus disabled. 
+  */
+-#define is_headless_node(cnode)               (!node_to_cpumask(cnode))
++#define is_headless_node(cnode)               (!any_online_cpu(node_to_cpumask(cnode)))
+ /*
+  * Check if given a node vertex handle the corresponding node has all the
+Index: linux-2.6.0-test5/include/asm-ia64/sn/pci/pcibr_private.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/pci/pcibr_private.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/pci/pcibr_private.h  2003-09-27 11:38:40.300401792 +0800
+@@ -15,11 +15,9 @@
+  * should ever peek into this file.
+  */
+-#include <linux/config.h>
+ #include <linux/pci.h>
+ #include <asm/sn/pci/pcibr.h>
+ #include <asm/sn/pci/pciio_private.h>
+-#include <asm/sn/ksys/l1.h>
+ /*
+  * convenience typedefs
+Index: linux-2.6.0-test5/include/asm-ia64/sn/pci/pciio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/pci/pciio.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/pci/pciio.h  2003-09-27 11:38:40.308400576 +0800
+@@ -695,5 +695,39 @@
+ extern int              pciio_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
+ extern int            pciio_dma_enabled(vertex_hdl_t);
++/**
++ * sn_pci_set_vchan - Set the requested Virtual Channel bits into the mapped DMA
++ *                    address.
++ * @pci_dev: pci device pointer
++ * @addr: mapped dma address
++ * @vchan: Virtual Channel to use 0 or 1.
++ *
++ * Set the Virtual Channel bit in the mapped dma address.
++ */
++
++static inline int
++sn_pci_set_vchan(struct pci_dev *pci_dev,
++               dma_addr_t *addr,
++               int vchan)
++{
++      if (vchan > 1) {
++              return -1;
++      }
++
++      if (!(*addr >> 32))     /* Using a mask here would be cleaner */
++              return 0;       /* but this generates better code */
++
++      if (vchan == 1) {
++              /* Set Bit 57 */
++              *addr |= (1UL << 57);
++      }
++      else {
++              /* Clear Bit 57 */
++              *addr &= ~(1UL << 57);
++      }
++
++      return 0;
++}
++
+ #endif                                /* C or C++ */
+ #endif                                /* _ASM_SN_PCI_PCIIO_H */
+Index: linux-2.6.0-test5/include/asm-ia64/sn/pda.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/pda.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/pda.h        2003-09-27 11:38:40.309400424 +0800
+@@ -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 @@
+       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;
+Index: linux-2.6.0-test5/include/asm-ia64/sn/router.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/router.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/router.h     2003-09-27 11:38:40.316399360 +0800
+@@ -1,5 +1,4 @@
+-
+-/* $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
++/* $id$
+  *
+  * 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
+@@ -19,7 +18,6 @@
+ #ifndef __ASSEMBLY__
+-#include <linux/devfs_fs_kernel.h>
+ #include <asm/sn/vector.h>
+ #include <asm/sn/slotnum.h>
+ #include <asm/sn/arch.h>
+@@ -31,23 +29,19 @@
+ #define MAX_ROUTER_PATH       80
+ #define ROUTER_REG_CAST               (volatile router_reg_t *)
+-#define PS_UINT_CAST          (__psunsigned_t)
+-#define UINT64_CAST           (uint64_t)
+ typedef signed char port_no_t;         /* Type for router port number      */
+ #else 
+ #define ROUTERREG_CAST
+-#define PS_UINT_CAST
+-#define UINT64_CAST
+ #endif /* __ASSEMBLY__ */
+-#define MAX_ROUTER_PORTS (8)   /* Max. number of ports on a router */
++#define MAX_ROUTER_PORTS      8       /* Max. number of ports on a router */
+ #define ALL_PORTS ((1 << MAX_ROUTER_PORTS) - 1)       /* for 0 based references */
+-#define PORT_INVALID (-1)      /* Invalid port number              */
++#define PORT_INVALID          -1      /* Invalid port number              */
+ #define       IS_META(_rp)    ((_rp)->flags & PCFG_ROUTER_META)
+@@ -126,24 +120,24 @@
+  */
+ #define RSRI_INPORT_SHFT      52
+-#define RSRI_INPORT_MASK      (UINT64_CAST 0xf << 52)
++#define RSRI_INPORT_MASK      (0xfUL << 52)
+ #define RSRI_LINKWORKING_BIT(_L) (35 + 2 * (_L))
+-#define RSRI_LINKWORKING(_L)  (UINT64_CAST 1 << (35 + 2 * (_L)))
+-#define RSRI_LINKRESETFAIL(_L)        (UINT64_CAST 1 << (34 + 2 * (_L)))
++#define RSRI_LINKWORKING(_L)  (1UL << (35 + 2 * (_L)))
++#define RSRI_LINKRESETFAIL(_L)        (1UL << (34 + 2 * (_L)))
+ #define RSRI_LSTAT_SHFT(_L)   (34 + 2 * (_L))
+-#define RSRI_LSTAT_MASK(_L)   (UINT64_CAST 0x3 << 34 + 2 * (_L))
+-#define RSRI_LOCALSBERROR     (UINT64_CAST 1 << 35)
+-#define RSRI_LOCALSTUCK               (UINT64_CAST 1 << 34)
+-#define RSRI_LOCALBADVEC      (UINT64_CAST 1 << 33)
+-#define RSRI_LOCALTAILERR     (UINT64_CAST 1 << 32)
++#define RSRI_LSTAT_MASK(_L)   (0x3UL << 34 + 2 * (_L))
++#define RSRI_LOCALSBERROR     (1UL << 35)
++#define RSRI_LOCALSTUCK               (1UL << 34)
++#define RSRI_LOCALBADVEC      (1UL << 33)
++#define RSRI_LOCALTAILERR     (1UL << 32)
+ #define RSRI_LOCAL_SHFT       32
+-#define RSRI_LOCAL_MASK               (UINT64_CAST 0xf << 32)
++#define RSRI_LOCAL_MASK               (0xfUL << 32)
+ #define RSRI_CHIPREV_SHFT     28
+-#define RSRI_CHIPREV_MASK     (UINT64_CAST 0xf << 28)
++#define RSRI_CHIPREV_MASK     (0xfUL << 28)
+ #define RSRI_CHIPID_SHFT      12
+-#define RSRI_CHIPID_MASK      (UINT64_CAST 0xffff << 12)
++#define RSRI_CHIPID_MASK      (0xffffUL << 12)
+ #define RSRI_MFGID_SHFT               1
+-#define RSRI_MFGID_MASK               (UINT64_CAST 0x7ff << 1)
++#define RSRI_MFGID_MASK               (0x7ffUL << 1)
+ #define RSRI_LSTAT_WENTDOWN   0
+ #define RSRI_LSTAT_RESETFAIL  1
+@@ -154,38 +148,38 @@
+  * RR_PORT_RESET mask definitions
+  */
+-#define RPRESET_WARM          (UINT64_CAST 1 << 9)
+-#define RPRESET_LINK(_L)      (UINT64_CAST 1 << (_L))
+-#define RPRESET_LOCAL         (UINT64_CAST 1)
++#define RPRESET_WARM          (1UL << 9)
++#define RPRESET_LINK(_L)      (1UL << (_L))
++#define RPRESET_LOCAL         1UL
+ /*
+  * RR_PROT_CONF mask and shift definitions
+  */
+ #define RPCONF_DIRCMPDIS_SHFT 13
+-#define RPCONF_DIRCMPDIS_MASK (UINT64_CAST 1 << 13)
+-#define RPCONF_FORCELOCAL     (UINT64_CAST 1 << 12)
++#define RPCONF_DIRCMPDIS_MASK (1UL << 13)
++#define RPCONF_FORCELOCAL     (1UL << 12)
+ #define RPCONF_FLOCAL_SHFT    12
+ #define RPCONF_METAID_SHFT    8
+-#define RPCONF_METAID_MASK    (UINT64_CAST 0xf << 8)
+-#define RPCONF_RESETOK(_L)    (UINT64_CAST 1 << ((_L) - 1))
++#define RPCONF_METAID_MASK    (0xfUL << 8)
++#define RPCONF_RESETOK(_L)    (1UL << ((_L) - 1))
+ /*
+  * RR_GLOBAL_PORT_DEF mask and shift definitions
+  */
+ #define RGPD_MGLBLNHBR_ID_SHFT        12      /* -global neighbor ID */
+-#define RGPD_MGLBLNHBR_ID_MASK        (UINT64_CAST 0xf << 12)
++#define RGPD_MGLBLNHBR_ID_MASK        (0xfUL << 12)
+ #define RGPD_MGLBLNHBR_VLD_SHFT       11      /* -global neighbor Valid */
+-#define RGPD_MGLBLNHBR_VLD_MASK       (UINT64_CAST 0x1 << 11)
++#define RGPD_MGLBLNHBR_VLD_MASK       (0x1UL << 11)
+ #define RGPD_MGLBLPORT_SHFT   8       /* -global neighbor Port */
+-#define RGPD_MGLBLPORT_MASK   (UINT64_CAST 0x7 << 8)
++#define RGPD_MGLBLPORT_MASK   (0x7UL << 8)
+ #define RGPD_PGLBLNHBR_ID_SHFT        4       /* +global neighbor ID */
+-#define RGPD_PGLBLNHBR_ID_MASK        (UINT64_CAST 0xf << 4)
++#define RGPD_PGLBLNHBR_ID_MASK        (0xfUL << 4)
+ #define RGPD_PGLBLNHBR_VLD_SHFT       3       /* +global neighbor Valid */
+-#define RGPD_PGLBLNHBR_VLD_MASK       (UINT64_CAST 0x1 << 3)
++#define RGPD_PGLBLNHBR_VLD_MASK       (0x1UL << 3)
+ #define RGPD_PGLBLPORT_SHFT   0       /* +global neighbor Port */
+-#define RGPD_PGLBLPORT_MASK   (UINT64_CAST 0x7 << 0)
++#define RGPD_PGLBLPORT_MASK   (0x7UL << 0)
+ #define GLBL_PARMS_REGS               2       /* Two Global Parms registers */
+@@ -194,95 +188,95 @@
+  */
+ #define RGPARM0_ARB_VALUE_SHFT        54      /* Local Block Arbitration State */
+-#define RGPARM0_ARB_VALUE_MASK        (UINT64_CAST 0x7 << 54)
++#define RGPARM0_ARB_VALUE_MASK        (0x7UL << 54)
+ #define RGPARM0_ROTATEARB_SHFT        53      /* Rotate Local Block Arbitration */
+-#define RGPARM0_ROTATEARB_MASK        (UINT64_CAST 0x1 << 53)
++#define RGPARM0_ROTATEARB_MASK        (1UL << 53)
+ #define RGPARM0_FAIREN_SHFT   52      /* Fairness logic Enable */
+-#define RGPARM0_FAIREN_MASK   (UINT64_CAST 0x1 << 52)
++#define RGPARM0_FAIREN_MASK   (1UL << 52)
+ #define RGPARM0_LOCGNTTO_SHFT 40      /* Local grant timeout */
+-#define RGPARM0_LOCGNTTO_MASK (UINT64_CAST 0xfff << 40)
++#define RGPARM0_LOCGNTTO_MASK (0xfffUL << 40)
+ #define RGPARM0_DATELINE_SHFT 38      /* Dateline crossing router */
+-#define RGPARM0_DATELINE_MASK (UINT64_CAST 0x1 << 38)
++#define RGPARM0_DATELINE_MASK (1UL << 38)
+ #define RGPARM0_MAXRETRY_SHFT 28      /* Max retry count */
+-#define RGPARM0_MAXRETRY_MASK (UINT64_CAST 0x3ff << 28)
++#define RGPARM0_MAXRETRY_MASK (0x3ffUL << 28)
+ #define RGPARM0_URGWRAP_SHFT  20      /* Urgent wrap */
+-#define RGPARM0_URGWRAP_MASK  (UINT64_CAST 0xff << 20)
++#define RGPARM0_URGWRAP_MASK  (0xffUL << 20)
+ #define RGPARM0_DEADLKTO_SHFT 16      /* Deadlock timeout */
+-#define RGPARM0_DEADLKTO_MASK (UINT64_CAST 0xf << 16)
++#define RGPARM0_DEADLKTO_MASK (0xfUL << 16)
+ #define RGPARM0_URGVAL_SHFT   12      /* Urgent value */
+-#define RGPARM0_URGVAL_MASK   (UINT64_CAST 0xf << 12)
++#define RGPARM0_URGVAL_MASK   (0xfUL << 12)
+ #define RGPARM0_VCHSELEN_SHFT 11      /* VCH_SEL_EN */
+-#define RGPARM0_VCHSELEN_MASK (UINT64_CAST 0x1 << 11)
++#define RGPARM0_VCHSELEN_MASK (1UL << 11)
+ #define RGPARM0_LOCURGTO_SHFT 9       /* Local urgent timeout */
+-#define RGPARM0_LOCURGTO_MASK (UINT64_CAST 0x3 << 9)
++#define RGPARM0_LOCURGTO_MASK (0x3UL << 9)
+ #define RGPARM0_TAILVAL_SHFT  5       /* Tail value */
+-#define RGPARM0_TAILVAL_MASK  (UINT64_CAST 0xf << 5)
++#define RGPARM0_TAILVAL_MASK  (0xfUL << 5)
+ #define RGPARM0_CLOCK_SHFT    1       /* Global clock select */
+-#define RGPARM0_CLOCK_MASK    (UINT64_CAST 0xf << 1)
++#define RGPARM0_CLOCK_MASK    (0xfUL << 1)
+ #define RGPARM0_BYPEN_SHFT    0
+-#define RGPARM0_BYPEN_MASK    (UINT64_CAST 1) /* Bypass enable */
++#define RGPARM0_BYPEN_MASK    1UL     /* Bypass enable */
+ /*
+  * RR_GLOBAL_PARMS1 shift and mask definitions
+  */
+ #define RGPARM1_TTOWRAP_SHFT  12      /* Tail timeout wrap */
+-#define RGPARM1_TTOWRAP_MASK  (UINT64_CAST 0xfffff << 12)
++#define RGPARM1_TTOWRAP_MASK  (0xfffffUL << 12)
+ #define RGPARM1_AGERATE_SHFT  8       /* Age rate */
+-#define RGPARM1_AGERATE_MASK  (UINT64_CAST 0xf << 8)
++#define RGPARM1_AGERATE_MASK  (0xfUL << 8)
+ #define RGPARM1_JSWSTAT_SHFT  0       /* JTAG Sw Register bits */
+-#define RGPARM1_JSWSTAT_MASK  (UINT64_CAST 0xff << 0)
++#define RGPARM1_JSWSTAT_MASK  (0xffUL << 0)
+ /*
+  * RR_DIAG_PARMS mask and shift definitions
+  */
+-#define RDPARM_ABSHISTOGRAM   (UINT64_CAST 1 << 17)   /* Absolute histgrm */
+-#define RDPARM_DEADLOCKRESET  (UINT64_CAST 1 << 16)   /* Reset on deadlck */
+-#define RDPARM_DISABLE(_L)    (UINT64_CAST 1 << ((_L) +  7))
+-#define RDPARM_SENDERROR(_L)  (UINT64_CAST 1 << ((_L) -  1))
++#define RDPARM_ABSHISTOGRAM   (1UL << 17)     /* Absolute histgrm */
++#define RDPARM_DEADLOCKRESET  (1UL << 16)     /* Reset on deadlck */
++#define RDPARM_DISABLE(_L)    (1UL << ((_L) +  7))
++#define RDPARM_SENDERROR(_L)  (1UL << ((_L) -  1))
+ /*
+  * RR_DEBUG_ADDR mask and shift definitions
+  */
+ #define RDA_DATA_SHFT         10      /* Observed debug data */
+-#define RDA_DATA_MASK         (UINT64_CAST 0xffff << 10)
++#define RDA_DATA_MASK         (0xffffUL << 10)
+ #define RDA_ADDR_SHFT         0       /* debug address for data */
+-#define RDA_ADDR_MASK         (UINT64_CAST 0x3ff << 0)
++#define RDA_ADDR_MASK         (0x3ffUL << 0)
+ /*
+  * RR_LB_TO_L2 mask and shift definitions
+  */
+ #define RLBTOL2_DATA_VLD_SHFT 32      /* data is valid for JTAG controller */
+-#define RLBTOL2_DATA_VLD_MASK (UINT64_CAST 0x1 << 32)
++#define RLBTOL2_DATA_VLD_MASK (1UL << 32)
+ #define RLBTOL2_DATA_SHFT     0       /* data bits for JTAG controller */
+-#define RLBTOL2_DATA_MASK     (UINT64_CAST 0xffffffff)
++#define RLBTOL2_DATA_MASK     0xffffffffUL
+ /*
+  * RR_L2_TO_LB mask and shift definitions
+  */
+ #define RL2TOLB_DATA_VLD_SHFT 33      /* data is valid from JTAG controller */
+-#define RL2TOLB_DATA_VLD_MASK (UINT64_CAST 0x1 << 33)
++#define RL2TOLB_DATA_VLD_MASK (1UL << 33)
+ #define RL2TOLB_PARITY_SHFT   32      /* sw implemented parity for data */
+-#define RL2TOLB_PARITY_MASK   (UINT64_CAST 0x1 << 32)
++#define RL2TOLB_PARITY_MASK   (1UL << 32)
+ #define RL2TOLB_DATA_SHFT     0       /* data bits from JTAG controller */
+-#define RL2TOLB_DATA_MASK     (UINT64_CAST 0xffffffff)
++#define RL2TOLB_DATA_MASK     0xffffffffUL
+ /*
+  * RR_JBUS_CONTROL mask and shift definitions
+  */
+ #define RJC_POS_BITS_SHFT     20      /* Router position bits */
+-#define RJC_POS_BITS_MASK     (UINT64_CAST 0xf << 20)
++#define RJC_POS_BITS_MASK     (0xfUL << 20)
+ #define RJC_RD_DATA_STROBE_SHFT       16      /* count when read data is strobed in */
+-#define RJC_RD_DATA_STROBE_MASK       (UINT64_CAST 0xf << 16)
++#define RJC_RD_DATA_STROBE_MASK       (0xfUL << 16)
+ #define RJC_WE_OE_HOLD_SHFT   8       /* time OE or WE is held */
+-#define RJC_WE_OE_HOLD_MASK   (UINT64_CAST 0xff << 8)
++#define RJC_WE_OE_HOLD_MASK   (0xffUL << 8)
+ #define RJC_ADDR_SET_HLD_SHFT 0       /* time address driven around OE/WE */
+-#define RJC_ADDR_SET_HLD_MASK (UINT64_CAST 0xff)
++#define RJC_ADDR_SET_HLD_MASK 0xffUL
+ /*
+  * RR_SCRATCH_REGx mask and shift definitions
+@@ -291,58 +285,58 @@
+  */
+ #define       RSCR0_BOOTED_SHFT       63
+-#define       RSCR0_BOOTED_MASK       (UINT64_CAST 0x1 << RSCR0_BOOTED_SHFT)
++#define       RSCR0_BOOTED_MASK       (0x1UL << RSCR0_BOOTED_SHFT)
+ #define RSCR0_LOCALID_SHFT    56
+-#define RSCR0_LOCALID_MASK    (UINT64_CAST 0x7f << RSCR0_LOCALID_SHFT)
++#define RSCR0_LOCALID_MASK    (0x7fUL << RSCR0_LOCALID_SHFT)
+ #define       RSCR0_UNUSED_SHFT       48
+-#define       RSCR0_UNUSED_MASK       (UINT64_CAST 0xff << RSCR0_UNUSED_SHFT)
++#define       RSCR0_UNUSED_MASK       (0xffUL << RSCR0_UNUSED_SHFT)
+ #define RSCR0_NIC_SHFT                0
+-#define RSCR0_NIC_MASK                (UINT64_CAST 0xffffffffffff)
++#define RSCR0_NIC_MASK                0xffffffffffffUL
+ #define RSCR1_MODID_SHFT      0
+-#define RSCR1_MODID_MASK      (UINT64_CAST 0xffff)
++#define RSCR1_MODID_MASK      0xffffUL
+ /*
+  * RR_VECTOR_HW_BAR mask and shift definitions
+  */
+ #define BAR_TX_SHFT           27      /* Barrier in trans(m)it when read */
+-#define BAR_TX_MASK           (UINT64_CAST 1 << BAR_TX_SHFT)
++#define BAR_TX_MASK           (1UL << BAR_TX_SHFT)
+ #define BAR_VLD_SHFT          26      /* Valid Configuration */
+-#define BAR_VLD_MASK          (UINT64_CAST 1 << BAR_VLD_SHFT)
++#define BAR_VLD_MASK          (1UL << BAR_VLD_SHFT)
+ #define BAR_SEQ_SHFT          24      /* Sequence number */
+-#define BAR_SEQ_MASK          (UINT64_CAST 3 << BAR_SEQ_SHFT)
++#define BAR_SEQ_MASK          (3UL << BAR_SEQ_SHFT)
+ #define BAR_LEAFSTATE_SHFT    18      /* Leaf State */
+-#define BAR_LEAFSTATE_MASK    (UINT64_CAST 0x3f << BAR_LEAFSTATE_SHFT)
++#define BAR_LEAFSTATE_MASK    (0x3fUL << BAR_LEAFSTATE_SHFT)
+ #define BAR_PARENT_SHFT               14      /* Parent Port */
+-#define BAR_PARENT_MASK               (UINT64_CAST 0xf << BAR_PARENT_SHFT)
++#define BAR_PARENT_MASK               (0xfUL << BAR_PARENT_SHFT)
+ #define BAR_CHILDREN_SHFT     6       /* Child Select port bits */
+-#define BAR_CHILDREN_MASK     (UINT64_CAST 0xff << BAR_CHILDREN_SHFT)
++#define BAR_CHILDREN_MASK     (0xffUL << BAR_CHILDREN_SHFT)
+ #define BAR_LEAFCOUNT_SHFT    0       /* Leaf Count to trigger parent */
+-#define BAR_LEAFCOUNT_MASK    (UINT64_CAST 0x3f)
++#define BAR_LEAFCOUNT_MASK    0x3fUL
+ /*
+  * RR_PORT_PARMS(_L) mask and shift definitions
+  */
+ #define RPPARM_MIPRESETEN_SHFT        29      /* Message In Progress reset enable */
+-#define RPPARM_MIPRESETEN_MASK        (UINT64_CAST 0x1 << 29)
++#define RPPARM_MIPRESETEN_MASK        (0x1UL << 29)
+ #define RPPARM_UBAREN_SHFT    28      /* Enable user barrier requests */
+-#define RPPARM_UBAREN_MASK    (UINT64_CAST 0x1 << 28)
++#define RPPARM_UBAREN_MASK    (0x1UL << 28)
+ #define RPPARM_OUTPDTO_SHFT   24      /* Output Port Deadlock TO value */
+-#define RPPARM_OUTPDTO_MASK   (UINT64_CAST 0xf << 24)
++#define RPPARM_OUTPDTO_MASK   (0xfUL << 24)
+ #define RPPARM_PORTMATE_SHFT  21      /* Port Mate for the port */
+-#define RPPARM_PORTMATE_MASK  (UINT64_CAST 0x7 << 21)
++#define RPPARM_PORTMATE_MASK  (0x7UL << 21)
+ #define RPPARM_HISTEN_SHFT    20      /* Histogram counter enable */
+-#define RPPARM_HISTEN_MASK    (UINT64_CAST 0x1 << 20)
++#define RPPARM_HISTEN_MASK    (0x1UL << 20)
+ #define RPPARM_HISTSEL_SHFT   18
+-#define RPPARM_HISTSEL_MASK   (UINT64_CAST 0x3 << 18)
++#define RPPARM_HISTSEL_MASK   (0x3UL << 18)
+ #define RPPARM_DAMQHS_SHFT    16
+-#define RPPARM_DAMQHS_MASK    (UINT64_CAST 0x3 << 16)
++#define RPPARM_DAMQHS_MASK    (0x3UL << 16)
+ #define RPPARM_NULLTO_SHFT    10
+-#define RPPARM_NULLTO_MASK    (UINT64_CAST 0x3f << 10)
++#define RPPARM_NULLTO_MASK    (0x3fUL << 10)
+ #define RPPARM_MAXBURST_SHFT  0
+-#define RPPARM_MAXBURST_MASK  (UINT64_CAST 0x3ff)
++#define RPPARM_MAXBURST_MASK  0x3ffUL
+ /*
+  * NOTE: Normally the kernel tracks only UTILIZATION statistics.
+@@ -356,23 +350,23 @@
+ /*
+  * RR_STATUS_ERROR(_L) and RR_ERROR_CLEAR(_L) mask and shift definitions
+  */
+-#define RSERR_POWERNOK                (UINT64_CAST 1 << 38)
+-#define RSERR_PORT_DEADLOCK     (UINT64_CAST 1 << 37)
+-#define RSERR_WARMRESET         (UINT64_CAST 1 << 36)
+-#define RSERR_LINKRESET         (UINT64_CAST 1 << 35)
+-#define RSERR_RETRYTIMEOUT      (UINT64_CAST 1 << 34)
+-#define RSERR_FIFOOVERFLOW    (UINT64_CAST 1 << 33)
+-#define RSERR_ILLEGALPORT     (UINT64_CAST 1 << 32)
++#define RSERR_POWERNOK                (1UL << 38)
++#define RSERR_PORT_DEADLOCK     (1UL << 37)
++#define RSERR_WARMRESET         (1UL << 36)
++#define RSERR_LINKRESET         (1UL << 35)
++#define RSERR_RETRYTIMEOUT      (1UL << 34)
++#define RSERR_FIFOOVERFLOW    (1UL << 33)
++#define RSERR_ILLEGALPORT     (1UL << 32)
+ #define RSERR_DEADLOCKTO_SHFT 28
+-#define RSERR_DEADLOCKTO_MASK (UINT64_CAST 0xf << 28)
++#define RSERR_DEADLOCKTO_MASK (0xfUL << 28)
+ #define RSERR_RECVTAILTO_SHFT 24
+-#define RSERR_RECVTAILTO_MASK (UINT64_CAST 0xf << 24)
++#define RSERR_RECVTAILTO_MASK (0xfUL << 24)
+ #define RSERR_RETRYCNT_SHFT   16
+-#define RSERR_RETRYCNT_MASK   (UINT64_CAST 0xff << 16)
++#define RSERR_RETRYCNT_MASK   (0xffUL << 16)
+ #define RSERR_CBERRCNT_SHFT   8
+-#define RSERR_CBERRCNT_MASK   (UINT64_CAST 0xff << 8)
++#define RSERR_CBERRCNT_MASK   (0xffUL << 8)
+ #define RSERR_SNERRCNT_SHFT   0
+-#define RSERR_SNERRCNT_MASK   (UINT64_CAST 0xff << 0)
++#define RSERR_SNERRCNT_MASK   (0xffUL << 0)
+ #define PORT_STATUS_UP                (1 << 0)        /* Router link up */
+@@ -393,10 +387,10 @@
+                                                * why the router link
+                                                * went down
+                                                */     
+-#define PROBE_RESULT_BAD      (-1)            /* Set if any of the router
++#define PROBE_RESULT_BAD      -1              /* Set if any of the router
+                                                * links failed after reset
+                                                */
+-#define PROBE_RESULT_GOOD     (0)             /* Set if all the router links
++#define PROBE_RESULT_GOOD     0               /* Set if all the router links
+                                                * which came out of reset 
+                                                * are up
+                                                */
+@@ -528,23 +522,6 @@
+ #define RIP_PROMLOG                   2       /* Router info in promlog */
+ #define RIP_CONSOLE                   4       /* Router info on console */
+-#define ROUTER_INFO_PRINT(_rip,_where)        (_rip->ri_print |= _where)      
+-                                      /* Set the field used to check if a 
+-                                       * router info can be printed
+-                                       */
+-#define IS_ROUTER_INFO_PRINTED(_rip,_where)   \
+-                                      (_rip->ri_print & _where)       
+-                                      /* Was the router info printed to
+-                                       * the given location (_where) ?
+-                                       * Mainly used to prevent duplicate
+-                                       * router error states.
+-                                       */
+-#define ROUTER_INFO_LOCK(_rip,_s)     _s = mutex_spinlock(&(_rip->ri_lock))
+-                                      /* Take the lock on router info
+-                                       * to gain exclusive access
+-                                       */
+-#define ROUTER_INFO_UNLOCK(_rip,_s)   mutex_spinunlock(&(_rip->ri_lock),_s)
+-                                      /* Release the lock on router info */
+ /* 
+  * Router info hanging in the nodepda 
+  */
+@@ -623,7 +600,7 @@
+  */
+ #define RHIST_BUCKET_SHFT(_x) (32 * ((_x) & 0x1))
+-#define RHIST_BUCKET_MASK(_x) (UINT64_CAST 0xffffffff << RHIST_BUCKET_SHFT((_x) & 0x1))
++#define RHIST_BUCKET_MASK(_x) (0xffffffffUL << RHIST_BUCKET_SHFT((_x) & 0x1))
+ #define RHIST_GET_BUCKET(_x, _reg)    \
+       ((RHIST_BUCKET_MASK(_x) & ((_reg)[(_x) >> 1])) >> RHIST_BUCKET_SHFT(_x))
+@@ -631,7 +608,7 @@
+  * RR_RESET_MASK(_L) mask and shift definitions
+  */
+-#define RRM_RESETOK(_L)               (UINT64_CAST 1 << ((_L) - 1))
++#define RRM_RESETOK(_L)               (1UL << ((_L) - 1))
+ #define RRM_RESETOK_ALL               ALL_PORTS
+ /*
+@@ -639,7 +616,7 @@
+  */
+ #define RTABLE_SHFT(_L)               (4 * ((_L) - 1))
+-#define RTABLE_MASK(_L)               (UINT64_CAST 0x7 << RTABLE_SHFT(_L))
++#define RTABLE_MASK(_L)               (0x7UL << RTABLE_SHFT(_L))
+ #define       ROUTERINFO_STKSZ        4096
+Index: linux-2.6.0-test5/include/asm-ia64/sn/sn2/intr.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/sn2/intr.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/sn2/intr.h   2003-09-27 11:38:40.318399056 +0800
+@@ -17,10 +17,11 @@
+ #define SGI_II_ERROR                  (0x31)
+ #define SGI_XBOW_ERROR                        (0x32)
+ #define SGI_PCIBR_ERROR                       (0x33)
++#define SGI_ACPI_SCI_INT              (0x34)
+ #define SGI_XPC_NOTIFY                        (0xe7)
+ #define IA64_SN2_FIRST_DEVICE_VECTOR  (0x34)
+-#define IA64_SN2_LAST_DEVICE_VECTOR   (0xe6)
++#define IA64_SN2_LAST_DEVICE_VECTOR   (0xe7)
+ #define SN2_IRQ_RESERVED        (0x1)
+ #define SN2_IRQ_CONNECTED       (0x2)
+Index: linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/sn2/shub.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub.h   2003-09-27 11:38:40.319398904 +0800
+@@ -11,13 +11,6 @@
+ #ifndef _ASM_IA64_SN_SN2_SHUB_H
+ #define _ASM_IA64_SN_SN2_SHUB_H
+-#include <asm/sn/sn2/shub_mmr.h>              /* shub mmr addresses and formats */
+-#include <asm/sn/sn2/shub_md.h>       
+-#include <asm/sn/sn2/shubio.h>        
+-#ifndef __ASSEMBLY__
+-#include <asm/sn/sn2/shub_mmr_t.h>            /* shub mmr struct defines */
+-#endif
+-
+ /*
+  * Junk Bus Address Space
+  *   The junk bus is used to access the PROM, LED's, and UART. It's 
+Index: linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub_mmr_t.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/sn/sn2/shub_mmr_t.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/sn/sn2/shub_mmr_t.h     2003-09-27 11:38:40.579359384 +0800
+@@ -7,8 +7,6 @@
+  * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+  */
+-
+-
+ #ifndef _ASM_IA64_SN_SN2_SHUB_MMR_T_H
+ #define _ASM_IA64_SN_SN2_SHUB_MMR_T_H
+@@ -19,7 +17,6 @@
+ /*                          FSB BINIT# Control                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_binit_control_u {
+       mmr_t   sh_fsb_binit_control_regval;
+       struct {
+@@ -27,22 +24,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_fsb_binit_control_s;
+ } sh_fsb_binit_control_u_t;
+-#else
+-typedef union sh_fsb_binit_control_u {
+-      mmr_t   sh_fsb_binit_control_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   binit       : 1;
+-      } sh_fsb_binit_control_s;
+-} sh_fsb_binit_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_FSB_RESET_CONTROL"                    */
+ /*                          FSB Reset Control                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_reset_control_u {
+       mmr_t   sh_fsb_reset_control_regval;
+       struct {
+@@ -50,22 +37,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_fsb_reset_control_s;
+ } sh_fsb_reset_control_u_t;
+-#else
+-typedef union sh_fsb_reset_control_u {
+-      mmr_t   sh_fsb_reset_control_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   reset       : 1;
+-      } sh_fsb_reset_control_s;
+-} sh_fsb_reset_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_FSB_SYSTEM_AGENT_CONFIG"                 */
+ /*                    FSB System Agent Configuration                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_system_agent_config_u {
+       mmr_t   sh_fsb_system_agent_config_regval;
+       struct {
+@@ -88,37 +65,12 @@
+               mmr_t   reserved_3          : 18;
+       } sh_fsb_system_agent_config_s;
+ } sh_fsb_system_agent_config_u_t;
+-#else
+-typedef union sh_fsb_system_agent_config_u {
+-      mmr_t   sh_fsb_system_agent_config_regval;
+-      struct {
+-              mmr_t   reserved_3          : 18;
+-              mmr_t   binit_event_enables : 14;
+-              mmr_t   reserved_2          : 7;
+-              mmr_t   serialize_fsb_en    : 1;
+-              mmr_t   tdot                : 1;
+-              mmr_t   reserved_1          : 4;
+-              mmr_t   inta_trans_rsp      : 1;
+-              mmr_t   xtpr_trans_rsp      : 1;
+-              mmr_t   io_trans_rsp        : 1;
+-              mmr_t   inta_rsp_data       : 8;
+-              mmr_t   short_hang_en       : 1;
+-              mmr_t   bnr_throttling_en   : 1;
+-              mmr_t   binit_assert_en     : 1;
+-              mmr_t   berr_sampling_en    : 1;
+-              mmr_t   berr_assert_en      : 1;
+-              mmr_t   reserved_0          : 2;
+-              mmr_t   rcnt_scnt_en        : 1;
+-      } sh_fsb_system_agent_config_s;
+-} sh_fsb_system_agent_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_FSB_VGA_REMAP"                      */
+ /*                     FSB VGA Address Space Remap                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_vga_remap_u {
+       mmr_t   sh_fsb_vga_remap_regval;
+       struct {
+@@ -131,27 +83,12 @@
+               mmr_t   reserved_2            : 1;
+       } sh_fsb_vga_remap_s;
+ } sh_fsb_vga_remap_u_t;
+-#else
+-typedef union sh_fsb_vga_remap_u {
+-      mmr_t   sh_fsb_vga_remap_regval;
+-      struct {
+-              mmr_t   reserved_2            : 1;
+-              mmr_t   vga_remapping_enabled : 1;
+-              mmr_t   reserved_1            : 13;
+-              mmr_t   nid                   : 11;
+-              mmr_t   asid                  : 2;
+-              mmr_t   offset                : 19;
+-              mmr_t   reserved_0            : 17;
+-      } sh_fsb_vga_remap_s;
+-} sh_fsb_vga_remap_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_FSB_RESET_STATUS"                    */
+ /*                           FSB Reset Status                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_reset_status_u {
+       mmr_t   sh_fsb_reset_status_regval;
+       struct {
+@@ -159,22 +96,12 @@
+               mmr_t   reserved_0        : 63;
+       } sh_fsb_reset_status_s;
+ } sh_fsb_reset_status_u_t;
+-#else
+-typedef union sh_fsb_reset_status_u {
+-      mmr_t   sh_fsb_reset_status_regval;
+-      struct {
+-              mmr_t   reserved_0        : 63;
+-              mmr_t   reset_in_progress : 1;
+-      } sh_fsb_reset_status_s;
+-} sh_fsb_reset_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_FSB_SYMMETRIC_AGENT_STATUS"               */
+ /*                      FSB Symmetric Agent Status                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_fsb_symmetric_agent_status_u {
+       mmr_t   sh_fsb_symmetric_agent_status_regval;
+       struct {
+@@ -184,24 +111,12 @@
+               mmr_t   reserved_0   : 61;
+       } sh_fsb_symmetric_agent_status_s;
+ } sh_fsb_symmetric_agent_status_u_t;
+-#else
+-typedef union sh_fsb_symmetric_agent_status_u {
+-      mmr_t   sh_fsb_symmetric_agent_status_regval;
+-      struct {
+-              mmr_t   reserved_0   : 61;
+-              mmr_t   cpus_ready   : 1;
+-              mmr_t   cpu_1_active : 1;
+-              mmr_t   cpu_0_active : 1;
+-      } sh_fsb_symmetric_agent_status_s;
+-} sh_fsb_symmetric_agent_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_CREDIT_COUNT_0"                   */
+ /*                Graphics-write Credit Count for CPU 0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_credit_count_0_u {
+       mmr_t   sh_gfx_credit_count_0_regval;
+       struct {
+@@ -210,23 +125,12 @@
+               mmr_t   reset_gfx_state : 1;
+       } sh_gfx_credit_count_0_s;
+ } sh_gfx_credit_count_0_u_t;
+-#else
+-typedef union sh_gfx_credit_count_0_u {
+-      mmr_t   sh_gfx_credit_count_0_regval;
+-      struct {
+-              mmr_t   reset_gfx_state : 1;
+-              mmr_t   reserved_0      : 43;
+-              mmr_t   count           : 20;
+-      } sh_gfx_credit_count_0_s;
+-} sh_gfx_credit_count_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_CREDIT_COUNT_1"                   */
+ /*                Graphics-write Credit Count for CPU 1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_credit_count_1_u {
+       mmr_t   sh_gfx_credit_count_1_regval;
+       struct {
+@@ -235,23 +139,12 @@
+               mmr_t   reset_gfx_state : 1;
+       } sh_gfx_credit_count_1_s;
+ } sh_gfx_credit_count_1_u_t;
+-#else
+-typedef union sh_gfx_credit_count_1_u {
+-      mmr_t   sh_gfx_credit_count_1_regval;
+-      struct {
+-              mmr_t   reset_gfx_state : 1;
+-              mmr_t   reserved_0      : 43;
+-              mmr_t   count           : 20;
+-      } sh_gfx_credit_count_1_s;
+-} sh_gfx_credit_count_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_GFX_MODE_CNTRL_0"                    */
+ /*         Graphics credit mode amd message ordering for CPU 0          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_mode_cntrl_0_u {
+       mmr_t   sh_gfx_mode_cntrl_0_regval;
+       struct {
+@@ -261,24 +154,12 @@
+               mmr_t   reserved_0         : 61;
+       } sh_gfx_mode_cntrl_0_s;
+ } sh_gfx_mode_cntrl_0_u_t;
+-#else
+-typedef union sh_gfx_mode_cntrl_0_u {
+-      mmr_t   sh_gfx_mode_cntrl_0_regval;
+-      struct {
+-              mmr_t   reserved_0         : 61;
+-              mmr_t   relaxed_ordering   : 1;
+-              mmr_t   mixed_mode_credits : 1;
+-              mmr_t   dword_credits      : 1;
+-      } sh_gfx_mode_cntrl_0_s;
+-} sh_gfx_mode_cntrl_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_GFX_MODE_CNTRL_1"                    */
+ /*         Graphics credit mode amd message ordering for CPU 1          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_mode_cntrl_1_u {
+       mmr_t   sh_gfx_mode_cntrl_1_regval;
+       struct {
+@@ -288,24 +169,12 @@
+               mmr_t   reserved_0         : 61;
+       } sh_gfx_mode_cntrl_1_s;
+ } sh_gfx_mode_cntrl_1_u_t;
+-#else
+-typedef union sh_gfx_mode_cntrl_1_u {
+-      mmr_t   sh_gfx_mode_cntrl_1_regval;
+-      struct {
+-              mmr_t   reserved_0         : 61;
+-              mmr_t   relaxed_ordering   : 1;
+-              mmr_t   mixed_mode_credits : 1;
+-              mmr_t   dword_credits      : 1;
+-      } sh_gfx_mode_cntrl_1_s;
+-} sh_gfx_mode_cntrl_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_GFX_SKID_CREDIT_COUNT_0"                 */
+ /*              Graphics-write Skid Credit Count for CPU 0              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_skid_credit_count_0_u {
+       mmr_t   sh_gfx_skid_credit_count_0_regval;
+       struct {
+@@ -313,22 +182,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_gfx_skid_credit_count_0_s;
+ } sh_gfx_skid_credit_count_0_u_t;
+-#else
+-typedef union sh_gfx_skid_credit_count_0_u {
+-      mmr_t   sh_gfx_skid_credit_count_0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   skid        : 20;
+-      } sh_gfx_skid_credit_count_0_s;
+-} sh_gfx_skid_credit_count_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_GFX_SKID_CREDIT_COUNT_1"                 */
+ /*              Graphics-write Skid Credit Count for CPU 1              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_skid_credit_count_1_u {
+       mmr_t   sh_gfx_skid_credit_count_1_regval;
+       struct {
+@@ -336,22 +195,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_gfx_skid_credit_count_1_s;
+ } sh_gfx_skid_credit_count_1_u_t;
+-#else
+-typedef union sh_gfx_skid_credit_count_1_u {
+-      mmr_t   sh_gfx_skid_credit_count_1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   skid        : 20;
+-      } sh_gfx_skid_credit_count_1_s;
+-} sh_gfx_skid_credit_count_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_STALL_LIMIT_0"                    */
+ /*                 Graphics-write Stall Limit for CPU 0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_limit_0_u {
+       mmr_t   sh_gfx_stall_limit_0_regval;
+       struct {
+@@ -359,22 +208,12 @@
+               mmr_t   reserved_0  : 38;
+       } sh_gfx_stall_limit_0_s;
+ } sh_gfx_stall_limit_0_u_t;
+-#else
+-typedef union sh_gfx_stall_limit_0_u {
+-      mmr_t   sh_gfx_stall_limit_0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 38;
+-              mmr_t   limit       : 26;
+-      } sh_gfx_stall_limit_0_s;
+-} sh_gfx_stall_limit_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_STALL_LIMIT_1"                    */
+ /*                 Graphics-write Stall Limit for CPU 1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_limit_1_u {
+       mmr_t   sh_gfx_stall_limit_1_regval;
+       struct {
+@@ -382,22 +221,12 @@
+               mmr_t   reserved_0  : 38;
+       } sh_gfx_stall_limit_1_s;
+ } sh_gfx_stall_limit_1_u_t;
+-#else
+-typedef union sh_gfx_stall_limit_1_u {
+-      mmr_t   sh_gfx_stall_limit_1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 38;
+-              mmr_t   limit       : 26;
+-      } sh_gfx_stall_limit_1_s;
+-} sh_gfx_stall_limit_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_STALL_TIMER_0"                    */
+ /*                 Graphics-write Stall Timer for CPU 0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_timer_0_u {
+       mmr_t   sh_gfx_stall_timer_0_regval;
+       struct {
+@@ -405,22 +234,12 @@
+               mmr_t   reserved_0  : 38;
+       } sh_gfx_stall_timer_0_s;
+ } sh_gfx_stall_timer_0_u_t;
+-#else
+-typedef union sh_gfx_stall_timer_0_u {
+-      mmr_t   sh_gfx_stall_timer_0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 38;
+-              mmr_t   timer_value : 26;
+-      } sh_gfx_stall_timer_0_s;
+-} sh_gfx_stall_timer_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_STALL_TIMER_1"                    */
+ /*                 Graphics-write Stall Timer for CPU 1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_stall_timer_1_u {
+       mmr_t   sh_gfx_stall_timer_1_regval;
+       struct {
+@@ -428,22 +247,12 @@
+               mmr_t   reserved_0  : 38;
+       } sh_gfx_stall_timer_1_s;
+ } sh_gfx_stall_timer_1_u_t;
+-#else
+-typedef union sh_gfx_stall_timer_1_u {
+-      mmr_t   sh_gfx_stall_timer_1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 38;
+-              mmr_t   timer_value : 26;
+-      } sh_gfx_stall_timer_1_s;
+-} sh_gfx_stall_timer_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_GFX_WINDOW_0"                      */
+ /*                   Graphics-write Window for CPU 0                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_window_0_u {
+       mmr_t   sh_gfx_window_0_regval;
+       struct {
+@@ -453,24 +262,12 @@
+               mmr_t   gfx_window_en : 1;
+       } sh_gfx_window_0_s;
+ } sh_gfx_window_0_u_t;
+-#else
+-typedef union sh_gfx_window_0_u {
+-      mmr_t   sh_gfx_window_0_regval;
+-      struct {
+-              mmr_t   gfx_window_en : 1;
+-              mmr_t   reserved_1    : 27;
+-              mmr_t   base_addr     : 12;
+-              mmr_t   reserved_0    : 24;
+-      } sh_gfx_window_0_s;
+-} sh_gfx_window_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_GFX_WINDOW_1"                      */
+ /*                   Graphics-write Window for CPU 1                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_window_1_u {
+       mmr_t   sh_gfx_window_1_regval;
+       struct {
+@@ -480,24 +277,12 @@
+               mmr_t   gfx_window_en : 1;
+       } sh_gfx_window_1_s;
+ } sh_gfx_window_1_u_t;
+-#else
+-typedef union sh_gfx_window_1_u {
+-      mmr_t   sh_gfx_window_1_regval;
+-      struct {
+-              mmr_t   gfx_window_en : 1;
+-              mmr_t   reserved_1    : 27;
+-              mmr_t   base_addr     : 12;
+-              mmr_t   reserved_0    : 24;
+-      } sh_gfx_window_1_s;
+-} sh_gfx_window_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_GFX_INTERRUPT_TIMER_LIMIT_0"               */
+ /*               Graphics-write Interrupt Limit for CPU 0               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_interrupt_timer_limit_0_u {
+       mmr_t   sh_gfx_interrupt_timer_limit_0_regval;
+       struct {
+@@ -505,22 +290,12 @@
+               mmr_t   reserved_0            : 56;
+       } sh_gfx_interrupt_timer_limit_0_s;
+ } sh_gfx_interrupt_timer_limit_0_u_t;
+-#else
+-typedef union sh_gfx_interrupt_timer_limit_0_u {
+-      mmr_t   sh_gfx_interrupt_timer_limit_0_regval;
+-      struct {
+-              mmr_t   reserved_0            : 56;
+-              mmr_t   interrupt_timer_limit : 8;
+-      } sh_gfx_interrupt_timer_limit_0_s;
+-} sh_gfx_interrupt_timer_limit_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_GFX_INTERRUPT_TIMER_LIMIT_1"               */
+ /*               Graphics-write Interrupt Limit for CPU 1               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_interrupt_timer_limit_1_u {
+       mmr_t   sh_gfx_interrupt_timer_limit_1_regval;
+       struct {
+@@ -528,22 +303,12 @@
+               mmr_t   reserved_0            : 56;
+       } sh_gfx_interrupt_timer_limit_1_s;
+ } sh_gfx_interrupt_timer_limit_1_u_t;
+-#else
+-typedef union sh_gfx_interrupt_timer_limit_1_u {
+-      mmr_t   sh_gfx_interrupt_timer_limit_1_regval;
+-      struct {
+-              mmr_t   reserved_0            : 56;
+-              mmr_t   interrupt_timer_limit : 8;
+-      } sh_gfx_interrupt_timer_limit_1_s;
+-} sh_gfx_interrupt_timer_limit_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_WRITE_STATUS_0"                   */
+ /*                   Graphics Write Status for CPU 0                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_write_status_0_u {
+       mmr_t   sh_gfx_write_status_0_regval;
+       struct {
+@@ -552,23 +317,12 @@
+               mmr_t   re_enable_gfx_stall : 1;
+       } sh_gfx_write_status_0_s;
+ } sh_gfx_write_status_0_u_t;
+-#else
+-typedef union sh_gfx_write_status_0_u {
+-      mmr_t   sh_gfx_write_status_0_regval;
+-      struct {
+-              mmr_t   re_enable_gfx_stall : 1;
+-              mmr_t   reserved_0          : 62;
+-              mmr_t   busy                : 1;
+-      } sh_gfx_write_status_0_s;
+-} sh_gfx_write_status_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_GFX_WRITE_STATUS_1"                   */
+ /*                   Graphics Write Status for CPU 1                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gfx_write_status_1_u {
+       mmr_t   sh_gfx_write_status_1_regval;
+       struct {
+@@ -577,23 +331,12 @@
+               mmr_t   re_enable_gfx_stall : 1;
+       } sh_gfx_write_status_1_s;
+ } sh_gfx_write_status_1_u_t;
+-#else
+-typedef union sh_gfx_write_status_1_u {
+-      mmr_t   sh_gfx_write_status_1_regval;
+-      struct {
+-              mmr_t   re_enable_gfx_stall : 1;
+-              mmr_t   reserved_0          : 62;
+-              mmr_t   busy                : 1;
+-      } sh_gfx_write_status_1_s;
+-} sh_gfx_write_status_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_II_INT0"                         */
+ /*                    SHub II Interrupt 0 Registers                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int0_u {
+       mmr_t   sh_ii_int0_regval;
+       struct {
+@@ -602,23 +345,12 @@
+               mmr_t   reserved_0  : 55;
+       } sh_ii_int0_s;
+ } sh_ii_int0_u_t;
+-#else
+-typedef union sh_ii_int0_u {
+-      mmr_t   sh_ii_int0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 55;
+-              mmr_t   send        : 1;
+-              mmr_t   idx         : 8;
+-      } sh_ii_int0_s;
+-} sh_ii_int0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_II_INT0_CONFIG"                     */
+ /*                 SHub II Interrupt 0 Config Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int0_config_u {
+       mmr_t   sh_ii_int0_config_regval;
+       struct {
+@@ -630,26 +362,12 @@
+               mmr_t   reserved_1  : 14;
+       } sh_ii_int0_config_s;
+ } sh_ii_int0_config_u_t;
+-#else
+-typedef union sh_ii_int0_config_u {
+-      mmr_t   sh_ii_int0_config_regval;
+-      struct {
+-              mmr_t   reserved_1  : 14;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_ii_int0_config_s;
+-} sh_ii_int0_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_II_INT0_ENABLE"                     */
+ /*                 SHub II Interrupt 0 Enable Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int0_enable_u {
+       mmr_t   sh_ii_int0_enable_regval;
+       struct {
+@@ -657,22 +375,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_ii_int0_enable_s;
+ } sh_ii_int0_enable_u_t;
+-#else
+-typedef union sh_ii_int0_enable_u {
+-      mmr_t   sh_ii_int0_enable_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   ii_enable   : 1;
+-      } sh_ii_int0_enable_s;
+-} sh_ii_int0_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_II_INT1"                         */
+ /*                    SHub II Interrupt 1 Registers                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int1_u {
+       mmr_t   sh_ii_int1_regval;
+       struct {
+@@ -681,23 +389,12 @@
+               mmr_t   reserved_0  : 55;
+       } sh_ii_int1_s;
+ } sh_ii_int1_u_t;
+-#else
+-typedef union sh_ii_int1_u {
+-      mmr_t   sh_ii_int1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 55;
+-              mmr_t   send        : 1;
+-              mmr_t   idx         : 8;
+-      } sh_ii_int1_s;
+-} sh_ii_int1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_II_INT1_CONFIG"                     */
+ /*                 SHub II Interrupt 1 Config Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int1_config_u {
+       mmr_t   sh_ii_int1_config_regval;
+       struct {
+@@ -709,26 +406,12 @@
+               mmr_t   reserved_1  : 14;
+       } sh_ii_int1_config_s;
+ } sh_ii_int1_config_u_t;
+-#else
+-typedef union sh_ii_int1_config_u {
+-      mmr_t   sh_ii_int1_config_regval;
+-      struct {
+-              mmr_t   reserved_1  : 14;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_ii_int1_config_s;
+-} sh_ii_int1_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_II_INT1_ENABLE"                     */
+ /*                 SHub II Interrupt 1 Enable Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_int1_enable_u {
+       mmr_t   sh_ii_int1_enable_regval;
+       struct {
+@@ -736,22 +419,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_ii_int1_enable_s;
+ } sh_ii_int1_enable_u_t;
+-#else
+-typedef union sh_ii_int1_enable_u {
+-      mmr_t   sh_ii_int1_enable_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   ii_enable   : 1;
+-      } sh_ii_int1_enable_s;
+-} sh_ii_int1_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_INT_NODE_ID_CONFIG"                   */
+ /*                 SHub Interrupt Node ID Configuration                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_node_id_config_u {
+       mmr_t   sh_int_node_id_config_regval;
+       struct {
+@@ -760,23 +433,12 @@
+               mmr_t   reserved_0  : 52;
+       } sh_int_node_id_config_s;
+ } sh_int_node_id_config_u_t;
+-#else
+-typedef union sh_int_node_id_config_u {
+-      mmr_t   sh_int_node_id_config_regval;
+-      struct {
+-              mmr_t   reserved_0  : 52;
+-              mmr_t   id_sel      : 1;
+-              mmr_t   node_id     : 11;
+-      } sh_int_node_id_config_s;
+-} sh_int_node_id_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_IPI_INT"                         */
+ /*               SHub Inter-Processor Interrupt Registers               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ipi_int_u {
+       mmr_t   sh_ipi_int_regval;
+       struct {
+@@ -791,29 +453,12 @@
+               mmr_t   send        : 1;
+       } sh_ipi_int_s;
+ } sh_ipi_int_u_t;
+-#else
+-typedef union sh_ipi_int_u {
+-      mmr_t   sh_ipi_int_regval;
+-      struct {
+-              mmr_t   send        : 1;
+-              mmr_t   reserved_2  : 3;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_ipi_int_s;
+-} sh_ipi_int_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_IPI_INT_ENABLE"                     */
+ /*           SHub Inter-Processor Interrupt Enable Registers            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ipi_int_enable_u {
+       mmr_t   sh_ipi_int_enable_regval;
+       struct {
+@@ -821,22 +466,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_ipi_int_enable_s;
+ } sh_ipi_int_enable_u_t;
+-#else
+-typedef union sh_ipi_int_enable_u {
+-      mmr_t   sh_ipi_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   pio_enable  : 1;
+-      } sh_ipi_int_enable_s;
+-} sh_ipi_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT0_CONFIG"                    */
+ /*                   SHub Local Interrupt 0 Registers                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int0_config_u {
+       mmr_t   sh_local_int0_config_regval;
+       struct {
+@@ -850,28 +485,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_local_int0_config_s;
+ } sh_local_int0_config_u_t;
+-#else
+-typedef union sh_local_int0_config_u {
+-      mmr_t   sh_local_int0_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_local_int0_config_s;
+-} sh_local_int0_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT0_ENABLE"                    */
+ /*                    SHub Local Interrupt 0 Enable                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int0_enable_u {
+       mmr_t   sh_local_int0_enable_regval;
+       struct {
+@@ -894,37 +513,12 @@
+               mmr_t   reserved_1          : 48;
+       } sh_local_int0_enable_s;
+ } sh_local_int0_enable_u_t;
+-#else
+-typedef union sh_local_int0_enable_u {
+-      mmr_t   sh_local_int0_enable_regval;
+-      struct {
+-              mmr_t   reserved_1          : 48;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_local_int0_enable_s;
+-} sh_local_int0_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT1_CONFIG"                    */
+ /*                   SHub Local Interrupt 1 Registers                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int1_config_u {
+       mmr_t   sh_local_int1_config_regval;
+       struct {
+@@ -938,28 +532,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_local_int1_config_s;
+ } sh_local_int1_config_u_t;
+-#else
+-typedef union sh_local_int1_config_u {
+-      mmr_t   sh_local_int1_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_local_int1_config_s;
+-} sh_local_int1_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT1_ENABLE"                    */
+ /*                    SHub Local Interrupt 1 Enable                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int1_enable_u {
+       mmr_t   sh_local_int1_enable_regval;
+       struct {
+@@ -982,37 +560,12 @@
+               mmr_t   reserved_1          : 48;
+       } sh_local_int1_enable_s;
+ } sh_local_int1_enable_u_t;
+-#else
+-typedef union sh_local_int1_enable_u {
+-      mmr_t   sh_local_int1_enable_regval;
+-      struct {
+-              mmr_t   reserved_1          : 48;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_local_int1_enable_s;
+-} sh_local_int1_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT2_CONFIG"                    */
+ /*                   SHub Local Interrupt 2 Registers                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int2_config_u {
+       mmr_t   sh_local_int2_config_regval;
+       struct {
+@@ -1026,28 +579,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_local_int2_config_s;
+ } sh_local_int2_config_u_t;
+-#else
+-typedef union sh_local_int2_config_u {
+-      mmr_t   sh_local_int2_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_local_int2_config_s;
+-} sh_local_int2_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT2_ENABLE"                    */
+ /*                    SHub Local Interrupt 2 Enable                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int2_enable_u {
+       mmr_t   sh_local_int2_enable_regval;
+       struct {
+@@ -1070,37 +607,12 @@
+               mmr_t   reserved_1          : 48;
+       } sh_local_int2_enable_s;
+ } sh_local_int2_enable_u_t;
+-#else
+-typedef union sh_local_int2_enable_u {
+-      mmr_t   sh_local_int2_enable_regval;
+-      struct {
+-              mmr_t   reserved_1          : 48;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_local_int2_enable_s;
+-} sh_local_int2_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT3_CONFIG"                    */
+ /*                   SHub Local Interrupt 3 Registers                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int3_config_u {
+       mmr_t   sh_local_int3_config_regval;
+       struct {
+@@ -1114,28 +626,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_local_int3_config_s;
+ } sh_local_int3_config_u_t;
+-#else
+-typedef union sh_local_int3_config_u {
+-      mmr_t   sh_local_int3_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_local_int3_config_s;
+-} sh_local_int3_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT3_ENABLE"                    */
+ /*                    SHub Local Interrupt 3 Enable                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int3_enable_u {
+       mmr_t   sh_local_int3_enable_regval;
+       struct {
+@@ -1158,37 +654,12 @@
+               mmr_t   reserved_1          : 48;
+       } sh_local_int3_enable_s;
+ } sh_local_int3_enable_u_t;
+-#else
+-typedef union sh_local_int3_enable_u {
+-      mmr_t   sh_local_int3_enable_regval;
+-      struct {
+-              mmr_t   reserved_1          : 48;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_local_int3_enable_s;
+-} sh_local_int3_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT4_CONFIG"                    */
+ /*                   SHub Local Interrupt 4 Registers                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int4_config_u {
+       mmr_t   sh_local_int4_config_regval;
+       struct {
+@@ -1202,28 +673,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_local_int4_config_s;
+ } sh_local_int4_config_u_t;
+-#else
+-typedef union sh_local_int4_config_u {
+-      mmr_t   sh_local_int4_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_local_int4_config_s;
+-} sh_local_int4_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT4_ENABLE"                    */
+ /*                    SHub Local Interrupt 4 Enable                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int4_enable_u {
+       mmr_t   sh_local_int4_enable_regval;
+       struct {
+@@ -1246,37 +701,12 @@
+               mmr_t   reserved_1          : 48;
+       } sh_local_int4_enable_s;
+ } sh_local_int4_enable_u_t;
+-#else
+-typedef union sh_local_int4_enable_u {
+-      mmr_t   sh_local_int4_enable_regval;
+-      struct {
+-              mmr_t   reserved_1          : 48;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_local_int4_enable_s;
+-} sh_local_int4_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT5_CONFIG"                    */
+ /*                   SHub Local Interrupt 5 Registers                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int5_config_u {
+       mmr_t   sh_local_int5_config_regval;
+       struct {
+@@ -1290,28 +720,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_local_int5_config_s;
+ } sh_local_int5_config_u_t;
+-#else
+-typedef union sh_local_int5_config_u {
+-      mmr_t   sh_local_int5_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_local_int5_config_s;
+-} sh_local_int5_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LOCAL_INT5_ENABLE"                    */
+ /*                    SHub Local Interrupt 5 Enable                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_local_int5_enable_u {
+       mmr_t   sh_local_int5_enable_regval;
+       struct {
+@@ -1334,37 +748,12 @@
+               mmr_t   reserved_1          : 48;
+       } sh_local_int5_enable_s;
+ } sh_local_int5_enable_u_t;
+-#else
+-typedef union sh_local_int5_enable_u {
+-      mmr_t   sh_local_int5_enable_regval;
+-      struct {
+-              mmr_t   reserved_1          : 48;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_local_int5_enable_s;
+-} sh_local_int5_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC0_ERR_INT_CONFIG"                  */
+ /*              SHub Processor 0 Error Interrupt Registers              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_err_int_config_u {
+       mmr_t   sh_proc0_err_int_config_regval;
+       struct {
+@@ -1378,28 +767,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc0_err_int_config_s;
+ } sh_proc0_err_int_config_u_t;
+-#else
+-typedef union sh_proc0_err_int_config_u {
+-      mmr_t   sh_proc0_err_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc0_err_int_config_s;
+-} sh_proc0_err_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC1_ERR_INT_CONFIG"                  */
+ /*              SHub Processor 1 Error Interrupt Registers              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_err_int_config_u {
+       mmr_t   sh_proc1_err_int_config_regval;
+       struct {
+@@ -1413,28 +786,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc1_err_int_config_s;
+ } sh_proc1_err_int_config_u_t;
+-#else
+-typedef union sh_proc1_err_int_config_u {
+-      mmr_t   sh_proc1_err_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc1_err_int_config_s;
+-} sh_proc1_err_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC2_ERR_INT_CONFIG"                  */
+ /*              SHub Processor 2 Error Interrupt Registers              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_err_int_config_u {
+       mmr_t   sh_proc2_err_int_config_regval;
+       struct {
+@@ -1448,28 +805,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc2_err_int_config_s;
+ } sh_proc2_err_int_config_u_t;
+-#else
+-typedef union sh_proc2_err_int_config_u {
+-      mmr_t   sh_proc2_err_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc2_err_int_config_s;
+-} sh_proc2_err_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC3_ERR_INT_CONFIG"                  */
+ /*              SHub Processor 3 Error Interrupt Registers              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_err_int_config_u {
+       mmr_t   sh_proc3_err_int_config_regval;
+       struct {
+@@ -1483,28 +824,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc3_err_int_config_s;
+ } sh_proc3_err_int_config_u_t;
+-#else
+-typedef union sh_proc3_err_int_config_u {
+-      mmr_t   sh_proc3_err_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc3_err_int_config_s;
+-} sh_proc3_err_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC0_ADV_INT_CONFIG"                  */
+ /*            SHub Processor 0 Advisory Interrupt Registers             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_adv_int_config_u {
+       mmr_t   sh_proc0_adv_int_config_regval;
+       struct {
+@@ -1518,28 +843,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc0_adv_int_config_s;
+ } sh_proc0_adv_int_config_u_t;
+-#else
+-typedef union sh_proc0_adv_int_config_u {
+-      mmr_t   sh_proc0_adv_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc0_adv_int_config_s;
+-} sh_proc0_adv_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC1_ADV_INT_CONFIG"                  */
+ /*            SHub Processor 1 Advisory Interrupt Registers             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_adv_int_config_u {
+       mmr_t   sh_proc1_adv_int_config_regval;
+       struct {
+@@ -1553,28 +862,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc1_adv_int_config_s;
+ } sh_proc1_adv_int_config_u_t;
+-#else
+-typedef union sh_proc1_adv_int_config_u {
+-      mmr_t   sh_proc1_adv_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc1_adv_int_config_s;
+-} sh_proc1_adv_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC2_ADV_INT_CONFIG"                  */
+ /*            SHub Processor 2 Advisory Interrupt Registers             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_adv_int_config_u {
+       mmr_t   sh_proc2_adv_int_config_regval;
+       struct {
+@@ -1588,28 +881,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc2_adv_int_config_s;
+ } sh_proc2_adv_int_config_u_t;
+-#else
+-typedef union sh_proc2_adv_int_config_u {
+-      mmr_t   sh_proc2_adv_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc2_adv_int_config_s;
+-} sh_proc2_adv_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC3_ADV_INT_CONFIG"                  */
+ /*            SHub Processor 3 Advisory Interrupt Registers             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_adv_int_config_u {
+       mmr_t   sh_proc3_adv_int_config_regval;
+       struct {
+@@ -1623,28 +900,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_proc3_adv_int_config_s;
+ } sh_proc3_adv_int_config_u_t;
+-#else
+-typedef union sh_proc3_adv_int_config_u {
+-      mmr_t   sh_proc3_adv_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_proc3_adv_int_config_s;
+-} sh_proc3_adv_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC0_ERR_INT_ENABLE"                  */
+ /*          SHub Processor 0 Error Interrupt Enable Registers           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_err_int_enable_u {
+       mmr_t   sh_proc0_err_int_enable_regval;
+       struct {
+@@ -1652,22 +913,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc0_err_int_enable_s;
+ } sh_proc0_err_int_enable_u_t;
+-#else
+-typedef union sh_proc0_err_int_enable_u {
+-      mmr_t   sh_proc0_err_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc0_err_enable : 1;
+-      } sh_proc0_err_int_enable_s;
+-} sh_proc0_err_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC1_ERR_INT_ENABLE"                  */
+ /*          SHub Processor 1 Error Interrupt Enable Registers           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_err_int_enable_u {
+       mmr_t   sh_proc1_err_int_enable_regval;
+       struct {
+@@ -1675,22 +926,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc1_err_int_enable_s;
+ } sh_proc1_err_int_enable_u_t;
+-#else
+-typedef union sh_proc1_err_int_enable_u {
+-      mmr_t   sh_proc1_err_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc1_err_enable : 1;
+-      } sh_proc1_err_int_enable_s;
+-} sh_proc1_err_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC2_ERR_INT_ENABLE"                  */
+ /*          SHub Processor 2 Error Interrupt Enable Registers           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_err_int_enable_u {
+       mmr_t   sh_proc2_err_int_enable_regval;
+       struct {
+@@ -1698,22 +939,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc2_err_int_enable_s;
+ } sh_proc2_err_int_enable_u_t;
+-#else
+-typedef union sh_proc2_err_int_enable_u {
+-      mmr_t   sh_proc2_err_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc2_err_enable : 1;
+-      } sh_proc2_err_int_enable_s;
+-} sh_proc2_err_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC3_ERR_INT_ENABLE"                  */
+ /*          SHub Processor 3 Error Interrupt Enable Registers           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_err_int_enable_u {
+       mmr_t   sh_proc3_err_int_enable_regval;
+       struct {
+@@ -1721,22 +952,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc3_err_int_enable_s;
+ } sh_proc3_err_int_enable_u_t;
+-#else
+-typedef union sh_proc3_err_int_enable_u {
+-      mmr_t   sh_proc3_err_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc3_err_enable : 1;
+-      } sh_proc3_err_int_enable_s;
+-} sh_proc3_err_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC0_ADV_INT_ENABLE"                  */
+ /*         SHub Processor 0 Advisory Interrupt Enable Registers         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_adv_int_enable_u {
+       mmr_t   sh_proc0_adv_int_enable_regval;
+       struct {
+@@ -1744,22 +965,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc0_adv_int_enable_s;
+ } sh_proc0_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc0_adv_int_enable_u {
+-      mmr_t   sh_proc0_adv_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc0_adv_enable : 1;
+-      } sh_proc0_adv_int_enable_s;
+-} sh_proc0_adv_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC1_ADV_INT_ENABLE"                  */
+ /*         SHub Processor 1 Advisory Interrupt Enable Registers         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_adv_int_enable_u {
+       mmr_t   sh_proc1_adv_int_enable_regval;
+       struct {
+@@ -1767,22 +978,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc1_adv_int_enable_s;
+ } sh_proc1_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc1_adv_int_enable_u {
+-      mmr_t   sh_proc1_adv_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc1_adv_enable : 1;
+-      } sh_proc1_adv_int_enable_s;
+-} sh_proc1_adv_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC2_ADV_INT_ENABLE"                  */
+ /*         SHub Processor 2 Advisory Interrupt Enable Registers         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_adv_int_enable_u {
+       mmr_t   sh_proc2_adv_int_enable_regval;
+       struct {
+@@ -1790,22 +991,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc2_adv_int_enable_s;
+ } sh_proc2_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc2_adv_int_enable_u {
+-      mmr_t   sh_proc2_adv_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc2_adv_enable : 1;
+-      } sh_proc2_adv_int_enable_s;
+-} sh_proc2_adv_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC3_ADV_INT_ENABLE"                  */
+ /*         SHub Processor 3 Advisory Interrupt Enable Registers         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_adv_int_enable_u {
+       mmr_t   sh_proc3_adv_int_enable_regval;
+       struct {
+@@ -1813,22 +1004,12 @@
+               mmr_t   reserved_0       : 63;
+       } sh_proc3_adv_int_enable_s;
+ } sh_proc3_adv_int_enable_u_t;
+-#else
+-typedef union sh_proc3_adv_int_enable_u {
+-      mmr_t   sh_proc3_adv_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0       : 63;
+-              mmr_t   proc3_adv_enable : 1;
+-      } sh_proc3_adv_int_enable_s;
+-} sh_proc3_adv_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PROFILE_INT_CONFIG"                   */
+ /*            SHub Profile Interrupt Configuration Registers            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_int_config_u {
+       mmr_t   sh_profile_int_config_regval;
+       struct {
+@@ -1842,28 +1023,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_profile_int_config_s;
+ } sh_profile_int_config_u_t;
+-#else
+-typedef union sh_profile_int_config_u {
+-      mmr_t   sh_profile_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_profile_int_config_s;
+-} sh_profile_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PROFILE_INT_ENABLE"                   */
+ /*               SHub Profile Interrupt Enable Registers                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_int_enable_u {
+       mmr_t   sh_profile_int_enable_regval;
+       struct {
+@@ -1871,22 +1036,12 @@
+               mmr_t   reserved_0     : 63;
+       } sh_profile_int_enable_s;
+ } sh_profile_int_enable_u_t;
+-#else
+-typedef union sh_profile_int_enable_u {
+-      mmr_t   sh_profile_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0     : 63;
+-              mmr_t   profile_enable : 1;
+-      } sh_profile_int_enable_s;
+-} sh_profile_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC0_INT_CONFIG"                     */
+ /*                SHub RTC 0 Interrupt Config Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc0_int_config_u {
+       mmr_t   sh_rtc0_int_config_regval;
+       struct {
+@@ -1900,28 +1055,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_rtc0_int_config_s;
+ } sh_rtc0_int_config_u_t;
+-#else
+-typedef union sh_rtc0_int_config_u {
+-      mmr_t   sh_rtc0_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_rtc0_int_config_s;
+-} sh_rtc0_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC0_INT_ENABLE"                     */
+ /*                SHub RTC 0 Interrupt Enable Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc0_int_enable_u {
+       mmr_t   sh_rtc0_int_enable_regval;
+       struct {
+@@ -1929,22 +1068,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_rtc0_int_enable_s;
+ } sh_rtc0_int_enable_u_t;
+-#else
+-typedef union sh_rtc0_int_enable_u {
+-      mmr_t   sh_rtc0_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   rtc0_enable : 1;
+-      } sh_rtc0_int_enable_s;
+-} sh_rtc0_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC1_INT_CONFIG"                     */
+ /*                SHub RTC 1 Interrupt Config Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc1_int_config_u {
+       mmr_t   sh_rtc1_int_config_regval;
+       struct {
+@@ -1958,28 +1087,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_rtc1_int_config_s;
+ } sh_rtc1_int_config_u_t;
+-#else
+-typedef union sh_rtc1_int_config_u {
+-      mmr_t   sh_rtc1_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_rtc1_int_config_s;
+-} sh_rtc1_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC1_INT_ENABLE"                     */
+ /*                SHub RTC 1 Interrupt Enable Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc1_int_enable_u {
+       mmr_t   sh_rtc1_int_enable_regval;
+       struct {
+@@ -1987,22 +1100,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_rtc1_int_enable_s;
+ } sh_rtc1_int_enable_u_t;
+-#else
+-typedef union sh_rtc1_int_enable_u {
+-      mmr_t   sh_rtc1_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   rtc1_enable : 1;
+-      } sh_rtc1_int_enable_s;
+-} sh_rtc1_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC2_INT_CONFIG"                     */
+ /*                SHub RTC 2 Interrupt Config Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc2_int_config_u {
+       mmr_t   sh_rtc2_int_config_regval;
+       struct {
+@@ -2016,28 +1119,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_rtc2_int_config_s;
+ } sh_rtc2_int_config_u_t;
+-#else
+-typedef union sh_rtc2_int_config_u {
+-      mmr_t   sh_rtc2_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_rtc2_int_config_s;
+-} sh_rtc2_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC2_INT_ENABLE"                     */
+ /*                SHub RTC 2 Interrupt Enable Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc2_int_enable_u {
+       mmr_t   sh_rtc2_int_enable_regval;
+       struct {
+@@ -2045,22 +1132,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_rtc2_int_enable_s;
+ } sh_rtc2_int_enable_u_t;
+-#else
+-typedef union sh_rtc2_int_enable_u {
+-      mmr_t   sh_rtc2_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   rtc2_enable : 1;
+-      } sh_rtc2_int_enable_s;
+-} sh_rtc2_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC3_INT_CONFIG"                     */
+ /*                SHub RTC 3 Interrupt Config Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc3_int_config_u {
+       mmr_t   sh_rtc3_int_config_regval;
+       struct {
+@@ -2074,28 +1151,12 @@
+               mmr_t   reserved_2  : 4;
+       } sh_rtc3_int_config_s;
+ } sh_rtc3_int_config_u_t;
+-#else
+-typedef union sh_rtc3_int_config_u {
+-      mmr_t   sh_rtc3_int_config_regval;
+-      struct {
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   idx         : 8;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   base        : 29;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   pid         : 16;
+-              mmr_t   agt         : 1;
+-              mmr_t   type        : 3;
+-      } sh_rtc3_int_config_s;
+-} sh_rtc3_int_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_RTC3_INT_ENABLE"                     */
+ /*                SHub RTC 3 Interrupt Enable Registers                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc3_int_enable_u {
+       mmr_t   sh_rtc3_int_enable_regval;
+       struct {
+@@ -2103,22 +1164,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_rtc3_int_enable_s;
+ } sh_rtc3_int_enable_u_t;
+-#else
+-typedef union sh_rtc3_int_enable_u {
+-      mmr_t   sh_rtc3_int_enable_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   rtc3_enable : 1;
+-      } sh_rtc3_int_enable_s;
+-} sh_rtc3_int_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_EVENT_OCCURRED"                     */
+ /*                    SHub Interrupt Event Occurred                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_event_occurred_u {
+       mmr_t   sh_event_occurred_regval;
+       struct {
+@@ -2156,54 +1207,14 @@
+               mmr_t   reserved_0          : 33;
+       } sh_event_occurred_s;
+ } sh_event_occurred_u_t;
+-#else
+-typedef union sh_event_occurred_u {
+-      mmr_t   sh_event_occurred_regval;
+-      struct {
+-              mmr_t   reserved_0          : 33;
+-              mmr_t   ii_int1             : 1;
+-              mmr_t   ii_int0             : 1;
+-              mmr_t   ipi_int             : 1;
+-              mmr_t   profile_int         : 1;
+-              mmr_t   rtc3_int            : 1;
+-              mmr_t   rtc2_int            : 1;
+-              mmr_t   rtc1_int            : 1;
+-              mmr_t   rtc0_int            : 1;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   proc3_err_int       : 1;
+-              mmr_t   proc2_err_int       : 1;
+-              mmr_t   proc1_err_int       : 1;
+-              mmr_t   proc0_err_int       : 1;
+-              mmr_t   proc3_adv_int       : 1;
+-              mmr_t   proc2_adv_int       : 1;
+-              mmr_t   proc1_adv_int       : 1;
+-              mmr_t   proc0_adv_int       : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_event_occurred_s;
+-} sh_event_occurred_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                     Register "SH_EVENT_OVERFLOW"                     */
+-/*                SHub Interrupt Event Occurred Overflow                */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_event_overflow_u {
+-      mmr_t   sh_event_overflow_regval;
++
++/* ==================================================================== */
++/*                     Register "SH_EVENT_OVERFLOW"                     */
++/*                SHub Interrupt Event Occurred Overflow                */
++/* ==================================================================== */
++
++typedef union sh_event_overflow_u {
++      mmr_t   sh_event_overflow_regval;
+       struct {
+               mmr_t   pi_hw_int           : 1;
+               mmr_t   md_hw_int           : 1;
+@@ -2236,49 +1247,12 @@
+               mmr_t   reserved_0          : 36;
+       } sh_event_overflow_s;
+ } sh_event_overflow_u_t;
+-#else
+-typedef union sh_event_overflow_u {
+-      mmr_t   sh_event_overflow_regval;
+-      struct {
+-              mmr_t   reserved_0          : 36;
+-              mmr_t   profile_int         : 1;
+-              mmr_t   rtc3_int            : 1;
+-              mmr_t   rtc2_int            : 1;
+-              mmr_t   rtc1_int            : 1;
+-              mmr_t   rtc0_int            : 1;
+-              mmr_t   stop_clock          : 1;
+-              mmr_t   l1_nmi_int          : 1;
+-              mmr_t   uart_int            : 1;
+-              mmr_t   system_shutdown_int : 1;
+-              mmr_t   proc3_err_int       : 1;
+-              mmr_t   proc2_err_int       : 1;
+-              mmr_t   proc1_err_int       : 1;
+-              mmr_t   proc0_err_int       : 1;
+-              mmr_t   proc3_adv_int       : 1;
+-              mmr_t   proc2_adv_int       : 1;
+-              mmr_t   proc1_adv_int       : 1;
+-              mmr_t   proc0_adv_int       : 1;
+-              mmr_t   xn_uce_int          : 1;
+-              mmr_t   md_uce_int          : 1;
+-              mmr_t   pi_uce_int          : 1;
+-              mmr_t   xn_ce_int           : 1;
+-              mmr_t   md_ce_int           : 1;
+-              mmr_t   pi_ce_int           : 1;
+-              mmr_t   ii_hw_int           : 1;
+-              mmr_t   lb_hw_int           : 1;
+-              mmr_t   xn_hw_int           : 1;
+-              mmr_t   md_hw_int           : 1;
+-              mmr_t   pi_hw_int           : 1;
+-      } sh_event_overflow_s;
+-} sh_event_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_JUNK_BUS_TIME"                      */
+ /*                           Junk Bus Timing                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_time_u {
+       mmr_t   sh_junk_bus_time_regval;
+       struct {
+@@ -2289,25 +1263,12 @@
+               mmr_t   reserved_0       : 32;
+       } sh_junk_bus_time_s;
+ } sh_junk_bus_time_u_t;
+-#else
+-typedef union sh_junk_bus_time_u {
+-      mmr_t   sh_junk_bus_time_regval;
+-      struct {
+-              mmr_t   reserved_0       : 32;
+-              mmr_t   uart_enable      : 8;
+-              mmr_t   uart_setup_hold  : 8;
+-              mmr_t   fprom_enable     : 8;
+-              mmr_t   fprom_setup_hold : 8;
+-      } sh_junk_bus_time_s;
+-} sh_junk_bus_time_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_JUNK_LATCH_TIME"                     */
+ /*                        Junk Bus Latch Timing                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_latch_time_u {
+       mmr_t   sh_junk_latch_time_regval;
+       struct {
+@@ -2315,22 +1276,12 @@
+               mmr_t   reserved_0  : 61;
+       } sh_junk_latch_time_s;
+ } sh_junk_latch_time_u_t;
+-#else
+-typedef union sh_junk_latch_time_u {
+-      mmr_t   sh_junk_latch_time_regval;
+-      struct {
+-              mmr_t   reserved_0  : 61;
+-              mmr_t   setup_hold  : 3;
+-      } sh_junk_latch_time_s;
+-} sh_junk_latch_time_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_JUNK_NACK_RESET"                     */
+ /*                     Junk Bus Nack Counter Reset                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_nack_reset_u {
+       mmr_t   sh_junk_nack_reset_regval;
+       struct {
+@@ -2338,22 +1289,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_junk_nack_reset_s;
+ } sh_junk_nack_reset_u_t;
+-#else
+-typedef union sh_junk_nack_reset_u {
+-      mmr_t   sh_junk_nack_reset_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   pulse       : 1;
+-      } sh_junk_nack_reset_s;
+-} sh_junk_nack_reset_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_JUNK_BUS_LED0"                      */
+ /*                            Junk Bus LED0                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led0_u {
+       mmr_t   sh_junk_bus_led0_regval;
+       struct {
+@@ -2361,22 +1302,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_junk_bus_led0_s;
+ } sh_junk_bus_led0_u_t;
+-#else
+-typedef union sh_junk_bus_led0_u {
+-      mmr_t   sh_junk_bus_led0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   led0_data   : 8;
+-      } sh_junk_bus_led0_s;
+-} sh_junk_bus_led0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_JUNK_BUS_LED1"                      */
+ /*                            Junk Bus LED1                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led1_u {
+       mmr_t   sh_junk_bus_led1_regval;
+       struct {
+@@ -2384,22 +1315,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_junk_bus_led1_s;
+ } sh_junk_bus_led1_u_t;
+-#else
+-typedef union sh_junk_bus_led1_u {
+-      mmr_t   sh_junk_bus_led1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   led1_data   : 8;
+-      } sh_junk_bus_led1_s;
+-} sh_junk_bus_led1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_JUNK_BUS_LED2"                      */
+ /*                            Junk Bus LED2                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led2_u {
+       mmr_t   sh_junk_bus_led2_regval;
+       struct {
+@@ -2407,22 +1328,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_junk_bus_led2_s;
+ } sh_junk_bus_led2_u_t;
+-#else
+-typedef union sh_junk_bus_led2_u {
+-      mmr_t   sh_junk_bus_led2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   led2_data   : 8;
+-      } sh_junk_bus_led2_s;
+-} sh_junk_bus_led2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_JUNK_BUS_LED3"                      */
+ /*                            Junk Bus LED3                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_bus_led3_u {
+       mmr_t   sh_junk_bus_led3_regval;
+       struct {
+@@ -2430,22 +1341,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_junk_bus_led3_s;
+ } sh_junk_bus_led3_u_t;
+-#else
+-typedef union sh_junk_bus_led3_u {
+-      mmr_t   sh_junk_bus_led3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   led3_data   : 8;
+-      } sh_junk_bus_led3_s;
+-} sh_junk_bus_led3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_JUNK_ERROR_STATUS"                    */
+ /*                        Junk Bus Error Status                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_junk_error_status_u {
+       mmr_t   sh_junk_error_status_regval;
+       struct {
+@@ -2457,26 +1358,12 @@
+               mmr_t   reserved_1  : 3;
+       } sh_junk_error_status_s;
+ } sh_junk_error_status_u_t;
+-#else
+-typedef union sh_junk_error_status_u {
+-      mmr_t   sh_junk_error_status_regval;
+-      struct {
+-              mmr_t   reserved_1  : 3;
+-              mmr_t   status      : 4;
+-              mmr_t   mode        : 1;
+-              mmr_t   cmd         : 8;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   address     : 47;
+-      } sh_junk_error_status_s;
+-} sh_junk_error_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_NI0_LLP_STAT"                      */
+ /*               This register describes the LLP status.                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_stat_u {
+       mmr_t   sh_ni0_llp_stat_regval;
+       struct {
+@@ -2484,22 +1371,12 @@
+               mmr_t   reserved_0       : 60;
+       } sh_ni0_llp_stat_s;
+ } sh_ni0_llp_stat_u_t;
+-#else
+-typedef union sh_ni0_llp_stat_u {
+-      mmr_t   sh_ni0_llp_stat_regval;
+-      struct {
+-              mmr_t   reserved_0       : 60;
+-              mmr_t   link_reset_state : 4;
+-      } sh_ni0_llp_stat_s;
+-} sh_ni0_llp_stat_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_NI0_LLP_RESET"                      */
+ /*           Writing issues a reset to the network interface            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_reset_u {
+       mmr_t   sh_ni0_llp_reset_regval;
+       struct {
+@@ -2508,23 +1385,12 @@
+               mmr_t   reserved_0  : 62;
+       } sh_ni0_llp_reset_s;
+ } sh_ni0_llp_reset_u_t;
+-#else
+-typedef union sh_ni0_llp_reset_u {
+-      mmr_t   sh_ni0_llp_reset_regval;
+-      struct {
+-              mmr_t   reserved_0  : 62;
+-              mmr_t   warm        : 1;
+-              mmr_t   link        : 1;
+-      } sh_ni0_llp_reset_s;
+-} sh_ni0_llp_reset_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_LLP_RESET_EN"                    */
+ /*                 Controls LLP warm reset propagation                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_reset_en_u {
+       mmr_t   sh_ni0_llp_reset_en_regval;
+       struct {
+@@ -2532,22 +1398,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_ni0_llp_reset_en_s;
+ } sh_ni0_llp_reset_en_u_t;
+-#else
+-typedef union sh_ni0_llp_reset_en_u {
+-      mmr_t   sh_ni0_llp_reset_en_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   ok          : 1;
+-      } sh_ni0_llp_reset_en_s;
+-} sh_ni0_llp_reset_en_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI0_LLP_CHAN_MODE"                    */
+ /*              Sets the signaling mode of LLP and channel              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_chan_mode_u {
+       mmr_t   sh_ni0_llp_chan_mode_regval;
+       struct {
+@@ -2559,26 +1415,12 @@
+               mmr_t   reserved_0        : 59;
+       } sh_ni0_llp_chan_mode_s;
+ } sh_ni0_llp_chan_mode_u_t;
+-#else
+-typedef union sh_ni0_llp_chan_mode_u {
+-      mmr_t   sh_ni0_llp_chan_mode_regval;
+-      struct {
+-              mmr_t   reserved_0        : 59;
+-              mmr_t   enable_clkquad    : 1;
+-              mmr_t   enable_rmt_ft_upd : 1;
+-              mmr_t   enable_tuning     : 1;
+-              mmr_t   ac_encode         : 1;
+-              mmr_t   bitmode32         : 1;
+-      } sh_ni0_llp_chan_mode_s;
+-} sh_ni0_llp_chan_mode_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_NI0_LLP_CONFIG"                     */
+ /*              Sets the configuration of LLP and channel               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_config_u {
+       mmr_t   sh_ni0_llp_config_regval;
+       struct {
+@@ -2589,24 +1431,11 @@
+               mmr_t   reserved_0  : 26;
+       } sh_ni0_llp_config_s;
+ } sh_ni0_llp_config_u_t;
+-#else
+-typedef union sh_ni0_llp_config_u {
+-      mmr_t   sh_ni0_llp_config_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   ftu_time    : 12;
+-              mmr_t   nulltimeout : 6;
+-              mmr_t   maxretry    : 10;
+-              mmr_t   maxburst    : 10;
+-      } sh_ni0_llp_config_s;
+-} sh_ni0_llp_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_LLP_TEST_CTL"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_test_ctl_u {
+       mmr_t   sh_ni0_llp_test_ctl_regval;
+       struct {
+@@ -2627,77 +1456,36 @@
+               mmr_t   reserved_2     : 1;
+       } sh_ni0_llp_test_ctl_s;
+ } sh_ni0_llp_test_ctl_u_t;
+-#else
+-typedef union sh_ni0_llp_test_ctl_u {
+-      mmr_t   sh_ni0_llp_test_ctl_regval;
+-      struct {
+-              mmr_t   reserved_2     : 1;
+-              mmr_t   cberror        : 1;
+-              mmr_t   captured       : 1;
+-              mmr_t   fakesnerror    : 1;
+-              mmr_t   sendsnerror    : 1;
+-              mmr_t   sendcberror    : 1;
+-              mmr_t   capturecbonly  : 1;
+-              mmr_t   armcapture     : 1;
+-              mmr_t   noise_mode     : 2;
+-              mmr_t   lfsr_mode      : 2;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   wire_sel       : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   send_test_mode : 2;
+-              mmr_t   pattern        : 40;
+-      } sh_ni0_llp_test_ctl_s;
+-} sh_ni0_llp_test_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_LLP_CAPT_WD1"                    */
+ /*                    low order 64-bit captured word                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_llp_capt_wd1_u {
+-      mmr_t   sh_ni0_llp_capt_wd1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_ni0_llp_capt_wd1_s;
+-} sh_ni0_llp_capt_wd1_u_t;
+-#else
+ typedef union sh_ni0_llp_capt_wd1_u {
+       mmr_t   sh_ni0_llp_capt_wd1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_ni0_llp_capt_wd1_s;
+ } sh_ni0_llp_capt_wd1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_LLP_CAPT_WD2"                    */
+ /*                   high order 64-bit captured word                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_capt_wd2_u {
+       mmr_t   sh_ni0_llp_capt_wd2_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_ni0_llp_capt_wd2_s;
+ } sh_ni0_llp_capt_wd2_u_t;
+-#else
+-typedef union sh_ni0_llp_capt_wd2_u {
+-      mmr_t   sh_ni0_llp_capt_wd2_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_ni0_llp_capt_wd2_s;
+-} sh_ni0_llp_capt_wd2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI0_LLP_CAPT_SBCB"                    */
+ /*                 captured sideband, sequence, and CRC                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_capt_sbcb_u {
+       mmr_t   sh_ni0_llp_capt_sbcb_regval;
+       struct {
+@@ -2711,27 +1499,11 @@
+               mmr_t   reserved_0       : 27;
+       } sh_ni0_llp_capt_sbcb_s;
+ } sh_ni0_llp_capt_sbcb_u_t;
+-#else
+-typedef union sh_ni0_llp_capt_sbcb_u {
+-      mmr_t   sh_ni0_llp_capt_sbcb_regval;
+-      struct {
+-              mmr_t   reserved_0       : 27;
+-              mmr_t   chargeunderflow  : 1;
+-              mmr_t   chargeoverflow   : 1;
+-              mmr_t   fakedallsnerrors : 1;
+-              mmr_t   sentallsnerrors  : 1;
+-              mmr_t   sentallcberrors  : 1;
+-              mmr_t   capturedrcvcrc   : 16;
+-              mmr_t   capturedrcvsbsn  : 16;
+-      } sh_ni0_llp_capt_sbcb_s;
+-} sh_ni0_llp_capt_sbcb_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_NI0_LLP_ERR"                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_llp_err_u {
+       mmr_t   sh_ni0_llp_err_regval;
+       struct {
+@@ -2747,30 +1519,12 @@
+               mmr_t   reserved_0      : 11;
+       } sh_ni0_llp_err_s;
+ } sh_ni0_llp_err_u_t;
+-#else
+-typedef union sh_ni0_llp_err_u {
+-      mmr_t   sh_ni0_llp_err_regval;
+-      struct {
+-              mmr_t   reserved_0      : 11;
+-              mmr_t   wire_overflow   : 1;
+-              mmr_t   wire_cnt        : 24;
+-              mmr_t   power_not_ok    : 1;
+-              mmr_t   squash          : 1;
+-              mmr_t   rcv_link_reset  : 1;
+-              mmr_t   retry_timeout   : 1;
+-              mmr_t   retry_count     : 8;
+-              mmr_t   rx_cb_err_count : 8;
+-              mmr_t   rx_sn_err_count : 8;
+-      } sh_ni0_llp_err_s;
+-} sh_ni0_llp_err_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_NI1_LLP_STAT"                      */
+ /*               This register describes the LLP status.                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_stat_u {
+       mmr_t   sh_ni1_llp_stat_regval;
+       struct {
+@@ -2778,22 +1532,12 @@
+               mmr_t   reserved_0       : 60;
+       } sh_ni1_llp_stat_s;
+ } sh_ni1_llp_stat_u_t;
+-#else
+-typedef union sh_ni1_llp_stat_u {
+-      mmr_t   sh_ni1_llp_stat_regval;
+-      struct {
+-              mmr_t   reserved_0       : 60;
+-              mmr_t   link_reset_state : 4;
+-      } sh_ni1_llp_stat_s;
+-} sh_ni1_llp_stat_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_NI1_LLP_RESET"                      */
+ /*           Writing issues a reset to the network interface            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_reset_u {
+       mmr_t   sh_ni1_llp_reset_regval;
+       struct {
+@@ -2802,23 +1546,12 @@
+               mmr_t   reserved_0  : 62;
+       } sh_ni1_llp_reset_s;
+ } sh_ni1_llp_reset_u_t;
+-#else
+-typedef union sh_ni1_llp_reset_u {
+-      mmr_t   sh_ni1_llp_reset_regval;
+-      struct {
+-              mmr_t   reserved_0  : 62;
+-              mmr_t   warm        : 1;
+-              mmr_t   link        : 1;
+-      } sh_ni1_llp_reset_s;
+-} sh_ni1_llp_reset_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_LLP_RESET_EN"                    */
+ /*                 Controls LLP warm reset propagation                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_reset_en_u {
+       mmr_t   sh_ni1_llp_reset_en_regval;
+       struct {
+@@ -2826,22 +1559,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_ni1_llp_reset_en_s;
+ } sh_ni1_llp_reset_en_u_t;
+-#else
+-typedef union sh_ni1_llp_reset_en_u {
+-      mmr_t   sh_ni1_llp_reset_en_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   ok          : 1;
+-      } sh_ni1_llp_reset_en_s;
+-} sh_ni1_llp_reset_en_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI1_LLP_CHAN_MODE"                    */
+ /*              Sets the signaling mode of LLP and channel              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_chan_mode_u {
+       mmr_t   sh_ni1_llp_chan_mode_regval;
+       struct {
+@@ -2853,26 +1576,12 @@
+               mmr_t   reserved_0        : 59;
+       } sh_ni1_llp_chan_mode_s;
+ } sh_ni1_llp_chan_mode_u_t;
+-#else
+-typedef union sh_ni1_llp_chan_mode_u {
+-      mmr_t   sh_ni1_llp_chan_mode_regval;
+-      struct {
+-              mmr_t   reserved_0        : 59;
+-              mmr_t   enable_clkquad    : 1;
+-              mmr_t   enable_rmt_ft_upd : 1;
+-              mmr_t   enable_tuning     : 1;
+-              mmr_t   ac_encode         : 1;
+-              mmr_t   bitmode32         : 1;
+-      } sh_ni1_llp_chan_mode_s;
+-} sh_ni1_llp_chan_mode_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_NI1_LLP_CONFIG"                     */
+ /*              Sets the configuration of LLP and channel               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_config_u {
+       mmr_t   sh_ni1_llp_config_regval;
+       struct {
+@@ -2883,24 +1592,11 @@
+               mmr_t   reserved_0  : 26;
+       } sh_ni1_llp_config_s;
+ } sh_ni1_llp_config_u_t;
+-#else
+-typedef union sh_ni1_llp_config_u {
+-      mmr_t   sh_ni1_llp_config_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   ftu_time    : 12;
+-              mmr_t   nulltimeout : 6;
+-              mmr_t   maxretry    : 10;
+-              mmr_t   maxburst    : 10;
+-      } sh_ni1_llp_config_s;
+-} sh_ni1_llp_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_LLP_TEST_CTL"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_test_ctl_u {
+       mmr_t   sh_ni1_llp_test_ctl_regval;
+       struct {
+@@ -2921,77 +1617,36 @@
+               mmr_t   reserved_2     : 1;
+       } sh_ni1_llp_test_ctl_s;
+ } sh_ni1_llp_test_ctl_u_t;
+-#else
+-typedef union sh_ni1_llp_test_ctl_u {
+-      mmr_t   sh_ni1_llp_test_ctl_regval;
+-      struct {
+-              mmr_t   reserved_2     : 1;
+-              mmr_t   cberror        : 1;
+-              mmr_t   captured       : 1;
+-              mmr_t   fakesnerror    : 1;
+-              mmr_t   sendsnerror    : 1;
+-              mmr_t   sendcberror    : 1;
+-              mmr_t   capturecbonly  : 1;
+-              mmr_t   armcapture     : 1;
+-              mmr_t   noise_mode     : 2;
+-              mmr_t   lfsr_mode      : 2;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   wire_sel       : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   send_test_mode : 2;
+-              mmr_t   pattern        : 40;
+-      } sh_ni1_llp_test_ctl_s;
+-} sh_ni1_llp_test_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_LLP_CAPT_WD1"                    */
+ /*                    low order 64-bit captured word                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_llp_capt_wd1_u {
+-      mmr_t   sh_ni1_llp_capt_wd1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_ni1_llp_capt_wd1_s;
+-} sh_ni1_llp_capt_wd1_u_t;
+-#else
+ typedef union sh_ni1_llp_capt_wd1_u {
+       mmr_t   sh_ni1_llp_capt_wd1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_ni1_llp_capt_wd1_s;
+ } sh_ni1_llp_capt_wd1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_LLP_CAPT_WD2"                    */
+ /*                   high order 64-bit captured word                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_llp_capt_wd2_u {
+-      mmr_t   sh_ni1_llp_capt_wd2_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_ni1_llp_capt_wd2_s;
+-} sh_ni1_llp_capt_wd2_u_t;
+-#else
+ typedef union sh_ni1_llp_capt_wd2_u {
+       mmr_t   sh_ni1_llp_capt_wd2_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_ni1_llp_capt_wd2_s;
+ } sh_ni1_llp_capt_wd2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI1_LLP_CAPT_SBCB"                    */
+ /*                 captured sideband, sequence, and CRC                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_capt_sbcb_u {
+       mmr_t   sh_ni1_llp_capt_sbcb_regval;
+       struct {
+@@ -3005,27 +1660,11 @@
+               mmr_t   reserved_0       : 27;
+       } sh_ni1_llp_capt_sbcb_s;
+ } sh_ni1_llp_capt_sbcb_u_t;
+-#else
+-typedef union sh_ni1_llp_capt_sbcb_u {
+-      mmr_t   sh_ni1_llp_capt_sbcb_regval;
+-      struct {
+-              mmr_t   reserved_0       : 27;
+-              mmr_t   chargeunderflow  : 1;
+-              mmr_t   chargeoverflow   : 1;
+-              mmr_t   fakedallsnerrors : 1;
+-              mmr_t   sentallsnerrors  : 1;
+-              mmr_t   sentallcberrors  : 1;
+-              mmr_t   capturedrcvcrc   : 16;
+-              mmr_t   capturedrcvsbsn  : 16;
+-      } sh_ni1_llp_capt_sbcb_s;
+-} sh_ni1_llp_capt_sbcb_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_NI1_LLP_ERR"                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_llp_err_u {
+       mmr_t   sh_ni1_llp_err_regval;
+       struct {
+@@ -3041,29 +1680,11 @@
+               mmr_t   reserved_0      : 11;
+       } sh_ni1_llp_err_s;
+ } sh_ni1_llp_err_u_t;
+-#else
+-typedef union sh_ni1_llp_err_u {
+-      mmr_t   sh_ni1_llp_err_regval;
+-      struct {
+-              mmr_t   reserved_0      : 11;
+-              mmr_t   wire_overflow   : 1;
+-              mmr_t   wire_cnt        : 24;
+-              mmr_t   power_not_ok    : 1;
+-              mmr_t   squash          : 1;
+-              mmr_t   rcv_link_reset  : 1;
+-              mmr_t   retry_timeout   : 1;
+-              mmr_t   retry_count     : 8;
+-              mmr_t   rx_cb_err_count : 8;
+-              mmr_t   rx_sn_err_count : 8;
+-      } sh_ni1_llp_err_s;
+-} sh_ni1_llp_err_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XNNI0_LLP_TO_FIFO02_FLOW"                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_llp_to_fifo02_flow_u {
+       mmr_t   sh_xnni0_llp_to_fifo02_flow_regval;
+       struct {
+@@ -3084,34 +1705,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnni0_llp_to_fifo02_flow_s;
+ } sh_xnni0_llp_to_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni0_llp_to_fifo02_flow_u {
+-      mmr_t   sh_xnni0_llp_to_fifo02_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni0_llp_to_fifo02_flow_s;
+-} sh_xnni0_llp_to_fifo02_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XNNI0_LLP_TO_FIFO13_FLOW"                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_llp_to_fifo13_flow_u {
+       mmr_t   sh_xnni0_llp_to_fifo13_flow_regval;
+       struct {
+@@ -3132,34 +1730,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnni0_llp_to_fifo13_flow_s;
+ } sh_xnni0_llp_to_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni0_llp_to_fifo13_flow_u {
+-      mmr_t   sh_xnni0_llp_to_fifo13_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni0_llp_to_fifo13_flow_s;
+-} sh_xnni0_llp_to_fifo13_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI0_LLP_DEBIT_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_llp_debit_flow_u {
+       mmr_t   sh_xnni0_llp_debit_flow_regval;
+       struct {
+@@ -3181,35 +1756,11 @@
+               mmr_t   reserved_7    : 3;
+       } sh_xnni0_llp_debit_flow_s;
+ } sh_xnni0_llp_debit_flow_u_t;
+-#else
+-typedef union sh_xnni0_llp_debit_flow_u {
+-      mmr_t   sh_xnni0_llp_debit_flow_regval;
+-      struct {
+-              mmr_t   reserved_7    : 3;
+-              mmr_t   debit_vc3_cap : 5;
+-              mmr_t   reserved_6    : 3;
+-              mmr_t   debit_vc3_dyn : 5;
+-              mmr_t   reserved_5    : 3;
+-              mmr_t   debit_vc2_cap : 5;
+-              mmr_t   reserved_4    : 3;
+-              mmr_t   debit_vc2_dyn : 5;
+-              mmr_t   reserved_3    : 3;
+-              mmr_t   debit_vc1_cap : 5;
+-              mmr_t   reserved_2    : 3;
+-              mmr_t   debit_vc1_dyn : 5;
+-              mmr_t   reserved_1    : 3;
+-              mmr_t   debit_vc0_cap : 5;
+-              mmr_t   reserved_0    : 3;
+-              mmr_t   debit_vc0_dyn : 5;
+-      } sh_xnni0_llp_debit_flow_s;
+-} sh_xnni0_llp_debit_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI0_LINK_0_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_0_flow_u {
+       mmr_t   sh_xnni0_link_0_flow_regval;
+       struct {
+@@ -3224,28 +1775,11 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni0_link_0_flow_s;
+ } sh_xnni0_link_0_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_0_flow_u {
+-      mmr_t   sh_xnni0_link_0_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc0_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc0_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc0_test      : 7;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni0_link_0_flow_s;
+-} sh_xnni0_link_0_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI0_LINK_1_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_1_flow_u {
+       mmr_t   sh_xnni0_link_1_flow_regval;
+       struct {
+@@ -3260,28 +1794,11 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni0_link_1_flow_s;
+ } sh_xnni0_link_1_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_1_flow_u {
+-      mmr_t   sh_xnni0_link_1_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc1_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc1_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc1_test      : 7;
+-              mmr_t   debit_vc1_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc1_withhold   : 6;
+-      } sh_xnni0_link_1_flow_s;
+-} sh_xnni0_link_1_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI0_LINK_2_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_2_flow_u {
+       mmr_t   sh_xnni0_link_2_flow_regval;
+       struct {
+@@ -3296,28 +1813,11 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni0_link_2_flow_s;
+ } sh_xnni0_link_2_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_2_flow_u {
+-      mmr_t   sh_xnni0_link_2_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc2_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc2_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc2_test      : 7;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-      } sh_xnni0_link_2_flow_s;
+-} sh_xnni0_link_2_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI0_LINK_3_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_link_3_flow_u {
+       mmr_t   sh_xnni0_link_3_flow_regval;
+       struct {
+@@ -3332,28 +1832,11 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni0_link_3_flow_s;
+ } sh_xnni0_link_3_flow_u_t;
+-#else
+-typedef union sh_xnni0_link_3_flow_u {
+-      mmr_t   sh_xnni0_link_3_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc3_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc3_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc3_test      : 7;
+-              mmr_t   debit_vc3_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc3_withhold   : 6;
+-      } sh_xnni0_link_3_flow_s;
+-} sh_xnni0_link_3_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XNNI1_LLP_TO_FIFO02_FLOW"                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_llp_to_fifo02_flow_u {
+       mmr_t   sh_xnni1_llp_to_fifo02_flow_regval;
+       struct {
+@@ -3374,34 +1857,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnni1_llp_to_fifo02_flow_s;
+ } sh_xnni1_llp_to_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni1_llp_to_fifo02_flow_u {
+-      mmr_t   sh_xnni1_llp_to_fifo02_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni1_llp_to_fifo02_flow_s;
+-} sh_xnni1_llp_to_fifo02_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XNNI1_LLP_TO_FIFO13_FLOW"                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_llp_to_fifo13_flow_u {
+       mmr_t   sh_xnni1_llp_to_fifo13_flow_regval;
+       struct {
+@@ -3422,34 +1882,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnni1_llp_to_fifo13_flow_s;
+ } sh_xnni1_llp_to_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni1_llp_to_fifo13_flow_u {
+-      mmr_t   sh_xnni1_llp_to_fifo13_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni1_llp_to_fifo13_flow_s;
+-} sh_xnni1_llp_to_fifo13_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI1_LLP_DEBIT_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_llp_debit_flow_u {
+       mmr_t   sh_xnni1_llp_debit_flow_regval;
+       struct {
+@@ -3471,35 +1908,11 @@
+               mmr_t   reserved_7    : 3;
+       } sh_xnni1_llp_debit_flow_s;
+ } sh_xnni1_llp_debit_flow_u_t;
+-#else
+-typedef union sh_xnni1_llp_debit_flow_u {
+-      mmr_t   sh_xnni1_llp_debit_flow_regval;
+-      struct {
+-              mmr_t   reserved_7    : 3;
+-              mmr_t   debit_vc3_cap : 5;
+-              mmr_t   reserved_6    : 3;
+-              mmr_t   debit_vc3_dyn : 5;
+-              mmr_t   reserved_5    : 3;
+-              mmr_t   debit_vc2_cap : 5;
+-              mmr_t   reserved_4    : 3;
+-              mmr_t   debit_vc2_dyn : 5;
+-              mmr_t   reserved_3    : 3;
+-              mmr_t   debit_vc1_cap : 5;
+-              mmr_t   reserved_2    : 3;
+-              mmr_t   debit_vc1_dyn : 5;
+-              mmr_t   reserved_1    : 3;
+-              mmr_t   debit_vc0_cap : 5;
+-              mmr_t   reserved_0    : 3;
+-              mmr_t   debit_vc0_dyn : 5;
+-      } sh_xnni1_llp_debit_flow_s;
+-} sh_xnni1_llp_debit_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI1_LINK_0_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_0_flow_u {
+       mmr_t   sh_xnni1_link_0_flow_regval;
+       struct {
+@@ -3514,28 +1927,11 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni1_link_0_flow_s;
+ } sh_xnni1_link_0_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_0_flow_u {
+-      mmr_t   sh_xnni1_link_0_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc0_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc0_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc0_test      : 7;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni1_link_0_flow_s;
+-} sh_xnni1_link_0_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI1_LINK_1_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_1_flow_u {
+       mmr_t   sh_xnni1_link_1_flow_regval;
+       struct {
+@@ -3550,28 +1946,11 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni1_link_1_flow_s;
+ } sh_xnni1_link_1_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_1_flow_u {
+-      mmr_t   sh_xnni1_link_1_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc1_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc1_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc1_test      : 7;
+-              mmr_t   debit_vc1_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc1_withhold   : 6;
+-      } sh_xnni1_link_1_flow_s;
+-} sh_xnni1_link_1_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI1_LINK_2_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_2_flow_u {
+       mmr_t   sh_xnni1_link_2_flow_regval;
+       struct {
+@@ -3586,28 +1965,11 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni1_link_2_flow_s;
+ } sh_xnni1_link_2_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_2_flow_u {
+-      mmr_t   sh_xnni1_link_2_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc2_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc2_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc2_test      : 7;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-      } sh_xnni1_link_2_flow_s;
+-} sh_xnni1_link_2_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI1_LINK_3_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_link_3_flow_u {
+       mmr_t   sh_xnni1_link_3_flow_regval;
+       struct {
+@@ -3622,29 +1984,12 @@
+               mmr_t   reserved_3           : 33;
+       } sh_xnni1_link_3_flow_s;
+ } sh_xnni1_link_3_flow_u_t;
+-#else
+-typedef union sh_xnni1_link_3_flow_u {
+-      mmr_t   sh_xnni1_link_3_flow_regval;
+-      struct {
+-              mmr_t   reserved_3           : 33;
+-              mmr_t   credit_vc3_cap       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc3_dyn       : 7;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   credit_vc3_test      : 7;
+-              mmr_t   debit_vc3_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc3_withhold   : 6;
+-      } sh_xnni1_link_3_flow_s;
+-} sh_xnni1_link_3_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_IILB_LOCAL_TABLE"                    */
+ /*                          local lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_iilb_local_table_u {
+       mmr_t   sh_iilb_local_table_regval;
+       struct {
+@@ -3655,25 +2000,12 @@
+               mmr_t   valid       : 1;
+       } sh_iilb_local_table_s;
+ } sh_iilb_local_table_u_t;
+-#else
+-typedef union sh_iilb_local_table_u {
+-      mmr_t   sh_iilb_local_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_0  : 57;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_iilb_local_table_s;
+-} sh_iilb_local_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_IILB_GLOBAL_TABLE"                    */
+ /*                         global lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_iilb_global_table_u {
+       mmr_t   sh_iilb_global_table_regval;
+       struct {
+@@ -3684,25 +2016,12 @@
+               mmr_t   valid       : 1;
+       } sh_iilb_global_table_s;
+ } sh_iilb_global_table_u_t;
+-#else
+-typedef union sh_iilb_global_table_u {
+-      mmr_t   sh_iilb_global_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_0  : 57;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_iilb_global_table_s;
+-} sh_iilb_global_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_IILB_OVER_RIDE_TABLE"                  */
+ /*              If enabled, bypass the Global/Local tables              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_iilb_over_ride_table_u {
+       mmr_t   sh_iilb_over_ride_table_regval;
+       struct {
+@@ -3713,46 +2032,24 @@
+               mmr_t   enable      : 1;
+       } sh_iilb_over_ride_table_s;
+ } sh_iilb_over_ride_table_u_t;
+-#else
+-typedef union sh_iilb_over_ride_table_u {
+-      mmr_t   sh_iilb_over_ride_table_regval;
+-      struct {
+-              mmr_t   enable      : 1;
+-              mmr_t   reserved_0  : 57;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_iilb_over_ride_table_s;
+-} sh_iilb_over_ride_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_IILB_RSP_PLANE_HINT"                   */
+ /*  If enabled, invert incoming response only plane hint bit before lo  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_iilb_rsp_plane_hint_u {
+-      mmr_t   sh_iilb_rsp_plane_hint_regval;
+-      struct {
+-              mmr_t   reserved_0  : 64;
+-      } sh_iilb_rsp_plane_hint_s;
+-} sh_iilb_rsp_plane_hint_u_t;
+-#else
+ typedef union sh_iilb_rsp_plane_hint_u {
+       mmr_t   sh_iilb_rsp_plane_hint_regval;
+       struct {
+               mmr_t   reserved_0  : 64;
+       } sh_iilb_rsp_plane_hint_s;
+ } sh_iilb_rsp_plane_hint_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PI_LOCAL_TABLE"                     */
+ /*                          local lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_local_table_u {
+       mmr_t   sh_pi_local_table_regval;
+       struct {
+@@ -3767,29 +2064,12 @@
+               mmr_t   valid       : 1;
+       } sh_pi_local_table_s;
+ } sh_pi_local_table_u_t;
+-#else
+-typedef union sh_pi_local_table_u {
+-      mmr_t   sh_pi_local_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_1  : 49;
+-              mmr_t   ni_sel1     : 1;
+-              mmr_t   v1          : 1;
+-              mmr_t   dir1        : 4;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_pi_local_table_s;
+-} sh_pi_local_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_PI_GLOBAL_TABLE"                     */
+ /*                         global lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_global_table_u {
+       mmr_t   sh_pi_global_table_regval;
+       struct {
+@@ -3804,29 +2084,12 @@
+               mmr_t   valid       : 1;
+       } sh_pi_global_table_s;
+ } sh_pi_global_table_u_t;
+-#else
+-typedef union sh_pi_global_table_u {
+-      mmr_t   sh_pi_global_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_1  : 49;
+-              mmr_t   ni_sel1     : 1;
+-              mmr_t   v1          : 1;
+-              mmr_t   dir1        : 4;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_pi_global_table_s;
+-} sh_pi_global_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_OVER_RIDE_TABLE"                   */
+ /*              If enabled, bypass the Global/Local tables              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_over_ride_table_u {
+       mmr_t   sh_pi_over_ride_table_regval;
+       struct {
+@@ -3841,29 +2104,12 @@
+               mmr_t   enable      : 1;
+       } sh_pi_over_ride_table_s;
+ } sh_pi_over_ride_table_u_t;
+-#else
+-typedef union sh_pi_over_ride_table_u {
+-      mmr_t   sh_pi_over_ride_table_regval;
+-      struct {
+-              mmr_t   enable      : 1;
+-              mmr_t   reserved_1  : 49;
+-              mmr_t   ni_sel1     : 1;
+-              mmr_t   v1          : 1;
+-              mmr_t   dir1        : 4;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_pi_over_ride_table_s;
+-} sh_pi_over_ride_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_RSP_PLANE_HINT"                    */
+ /*  If enabled, invert incoming response only plane hint bit before lo  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_rsp_plane_hint_u {
+       mmr_t   sh_pi_rsp_plane_hint_regval;
+       struct {
+@@ -3871,22 +2117,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_pi_rsp_plane_hint_s;
+ } sh_pi_rsp_plane_hint_u_t;
+-#else
+-typedef union sh_pi_rsp_plane_hint_u {
+-      mmr_t   sh_pi_rsp_plane_hint_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   invert      : 1;
+-      } sh_pi_rsp_plane_hint_s;
+-} sh_pi_rsp_plane_hint_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_LOCAL_TABLE"                     */
+ /*                          local lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_local_table_u {
+       mmr_t   sh_ni0_local_table_regval;
+       struct {
+@@ -3896,24 +2132,12 @@
+               mmr_t   valid       : 1;
+       } sh_ni0_local_table_s;
+ } sh_ni0_local_table_u_t;
+-#else
+-typedef union sh_ni0_local_table_u {
+-      mmr_t   sh_ni0_local_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_ni0_local_table_s;
+-} sh_ni0_local_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_GLOBAL_TABLE"                    */
+ /*                         global lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_global_table_u {
+       mmr_t   sh_ni0_global_table_regval;
+       struct {
+@@ -3923,24 +2147,12 @@
+               mmr_t   valid       : 1;
+       } sh_ni0_global_table_s;
+ } sh_ni0_global_table_u_t;
+-#else
+-typedef union sh_ni0_global_table_u {
+-      mmr_t   sh_ni0_global_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_ni0_global_table_s;
+-} sh_ni0_global_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI0_OVER_RIDE_TABLE"                   */
+ /*              If enabled, bypass the Global/Local tables              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_over_ride_table_u {
+       mmr_t   sh_ni0_over_ride_table_regval;
+       struct {
+@@ -3950,45 +2162,24 @@
+               mmr_t   enable      : 1;
+       } sh_ni0_over_ride_table_s;
+ } sh_ni0_over_ride_table_u_t;
+-#else
+-typedef union sh_ni0_over_ride_table_u {
+-      mmr_t   sh_ni0_over_ride_table_regval;
+-      struct {
+-              mmr_t   enable      : 1;
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_ni0_over_ride_table_s;
+-} sh_ni0_over_ride_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI0_RSP_PLANE_HINT"                   */
+ /*  If enabled, invert incoming response only plane hint bit before lo  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_rsp_plane_hint_u {
+-      mmr_t   sh_ni0_rsp_plane_hint_regval;
+-      struct {
+-              mmr_t   reserved_0  : 64;
+-      } sh_ni0_rsp_plane_hint_s;
+-} sh_ni0_rsp_plane_hint_u_t;
+-#else
+ typedef union sh_ni0_rsp_plane_hint_u {
+       mmr_t   sh_ni0_rsp_plane_hint_regval;
+       struct {
+               mmr_t   reserved_0  : 64;
+       } sh_ni0_rsp_plane_hint_s;
+ } sh_ni0_rsp_plane_hint_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_LOCAL_TABLE"                     */
+ /*                          local lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_local_table_u {
+       mmr_t   sh_ni1_local_table_regval;
+       struct {
+@@ -3998,24 +2189,12 @@
+               mmr_t   valid       : 1;
+       } sh_ni1_local_table_s;
+ } sh_ni1_local_table_u_t;
+-#else
+-typedef union sh_ni1_local_table_u {
+-      mmr_t   sh_ni1_local_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_ni1_local_table_s;
+-} sh_ni1_local_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_GLOBAL_TABLE"                    */
+ /*                         global lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_global_table_u {
+       mmr_t   sh_ni1_global_table_regval;
+       struct {
+@@ -4025,24 +2204,12 @@
+               mmr_t   valid       : 1;
+       } sh_ni1_global_table_s;
+ } sh_ni1_global_table_u_t;
+-#else
+-typedef union sh_ni1_global_table_u {
+-      mmr_t   sh_ni1_global_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_ni1_global_table_s;
+-} sh_ni1_global_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI1_OVER_RIDE_TABLE"                   */
+ /*              If enabled, bypass the Global/Local tables              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_over_ride_table_u {
+       mmr_t   sh_ni1_over_ride_table_regval;
+       struct {
+@@ -4052,45 +2219,24 @@
+               mmr_t   enable      : 1;
+       } sh_ni1_over_ride_table_s;
+ } sh_ni1_over_ride_table_u_t;
+-#else
+-typedef union sh_ni1_over_ride_table_u {
+-      mmr_t   sh_ni1_over_ride_table_regval;
+-      struct {
+-              mmr_t   enable      : 1;
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_ni1_over_ride_table_s;
+-} sh_ni1_over_ride_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI1_RSP_PLANE_HINT"                   */
+ /*  If enabled, invert incoming response only plane hint bit before lo  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_rsp_plane_hint_u {
+-      mmr_t   sh_ni1_rsp_plane_hint_regval;
+-      struct {
+-              mmr_t   reserved_0  : 64;
+-      } sh_ni1_rsp_plane_hint_s;
+-} sh_ni1_rsp_plane_hint_u_t;
+-#else
+ typedef union sh_ni1_rsp_plane_hint_u {
+       mmr_t   sh_ni1_rsp_plane_hint_regval;
+       struct {
+               mmr_t   reserved_0  : 64;
+       } sh_ni1_rsp_plane_hint_s;
+ } sh_ni1_rsp_plane_hint_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_MD_LOCAL_TABLE"                     */
+ /*                          local lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_local_table_u {
+       mmr_t   sh_md_local_table_regval;
+       struct {
+@@ -4105,29 +2251,12 @@
+               mmr_t   valid       : 1;
+       } sh_md_local_table_s;
+ } sh_md_local_table_u_t;
+-#else
+-typedef union sh_md_local_table_u {
+-      mmr_t   sh_md_local_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_1  : 49;
+-              mmr_t   ni_sel1     : 1;
+-              mmr_t   v1          : 1;
+-              mmr_t   dir1        : 4;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_md_local_table_s;
+-} sh_md_local_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_MD_GLOBAL_TABLE"                     */
+ /*                         global lookup table                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_global_table_u {
+       mmr_t   sh_md_global_table_regval;
+       struct {
+@@ -4142,29 +2271,12 @@
+               mmr_t   valid       : 1;
+       } sh_md_global_table_s;
+ } sh_md_global_table_u_t;
+-#else
+-typedef union sh_md_global_table_u {
+-      mmr_t   sh_md_global_table_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_1  : 49;
+-              mmr_t   ni_sel1     : 1;
+-              mmr_t   v1          : 1;
+-              mmr_t   dir1        : 4;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_md_global_table_s;
+-} sh_md_global_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_OVER_RIDE_TABLE"                   */
+ /*              If enabled, bypass the Global/Local tables              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_over_ride_table_u {
+       mmr_t   sh_md_over_ride_table_regval;
+       struct {
+@@ -4179,29 +2291,12 @@
+               mmr_t   enable      : 1;
+       } sh_md_over_ride_table_s;
+ } sh_md_over_ride_table_u_t;
+-#else
+-typedef union sh_md_over_ride_table_u {
+-      mmr_t   sh_md_over_ride_table_regval;
+-      struct {
+-              mmr_t   enable      : 1;
+-              mmr_t   reserved_1  : 49;
+-              mmr_t   ni_sel1     : 1;
+-              mmr_t   v1          : 1;
+-              mmr_t   dir1        : 4;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   ni_sel0     : 1;
+-              mmr_t   v0          : 1;
+-              mmr_t   dir0        : 4;
+-      } sh_md_over_ride_table_s;
+-} sh_md_over_ride_table_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_RSP_PLANE_HINT"                    */
+ /*  If enabled, invert incoming response only plane hint bit before lo  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_rsp_plane_hint_u {
+       mmr_t   sh_md_rsp_plane_hint_regval;
+       struct {
+@@ -4209,22 +2304,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_md_rsp_plane_hint_s;
+ } sh_md_rsp_plane_hint_u_t;
+-#else
+-typedef union sh_md_rsp_plane_hint_u {
+-      mmr_t   sh_md_rsp_plane_hint_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   invert      : 1;
+-      } sh_md_rsp_plane_hint_s;
+-} sh_md_rsp_plane_hint_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_LB_LIQ_CTL"                       */
+ /*                       Local Block LIQ Control                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_liq_ctl_u {
+       mmr_t   sh_lb_liq_ctl_regval;
+       struct {
+@@ -4238,28 +2323,12 @@
+               mmr_t   reserved_2         : 45;
+       } sh_lb_liq_ctl_s;
+ } sh_lb_liq_ctl_u_t;
+-#else
+-typedef union sh_lb_liq_ctl_u {
+-      mmr_t   sh_lb_liq_ctl_regval;
+-      struct {
+-              mmr_t   reserved_2         : 45;
+-              mmr_t   force_linvv_credit : 1;
+-              mmr_t   force_rp_credit    : 1;
+-              mmr_t   force_rq_credit    : 1;
+-              mmr_t   reserved_1         : 4;
+-              mmr_t   liq_rpl_ctl        : 4;
+-              mmr_t   reserved_0         : 3;
+-              mmr_t   liq_req_ctl        : 5;
+-      } sh_lb_liq_ctl_s;
+-} sh_lb_liq_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_LB_LOQ_CTL"                       */
+ /*                       Local Block LOQ Control                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_loq_ctl_u {
+       mmr_t   sh_lb_loq_ctl_regval;
+       struct {
+@@ -4268,23 +2337,12 @@
+               mmr_t   reserved_0  : 62;
+       } sh_lb_loq_ctl_s;
+ } sh_lb_loq_ctl_u_t;
+-#else
+-typedef union sh_lb_loq_ctl_u {
+-      mmr_t   sh_lb_loq_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 62;
+-              mmr_t   loq_rpl_ctl : 1;
+-              mmr_t   loq_req_ctl : 1;
+-      } sh_lb_loq_ctl_s;
+-} sh_lb_loq_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_LB_MAX_REP_CREDIT_CNT"                  */
+ /*               Maximum number of reply credits from XN                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_max_rep_credit_cnt_u {
+       mmr_t   sh_lb_max_rep_credit_cnt_regval;
+       struct {
+@@ -4292,22 +2350,12 @@
+               mmr_t   reserved_0  : 59;
+       } sh_lb_max_rep_credit_cnt_s;
+ } sh_lb_max_rep_credit_cnt_u_t;
+-#else
+-typedef union sh_lb_max_rep_credit_cnt_u {
+-      mmr_t   sh_lb_max_rep_credit_cnt_regval;
+-      struct {
+-              mmr_t   reserved_0  : 59;
+-              mmr_t   max_cnt     : 5;
+-      } sh_lb_max_rep_credit_cnt_s;
+-} sh_lb_max_rep_credit_cnt_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_LB_MAX_REQ_CREDIT_CNT"                  */
+ /*              Maximum number of request credits from XN               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_max_req_credit_cnt_u {
+       mmr_t   sh_lb_max_req_credit_cnt_regval;
+       struct {
+@@ -4315,22 +2363,12 @@
+               mmr_t   reserved_0  : 59;
+       } sh_lb_max_req_credit_cnt_s;
+ } sh_lb_max_req_credit_cnt_u_t;
+-#else
+-typedef union sh_lb_max_req_credit_cnt_u {
+-      mmr_t   sh_lb_max_req_credit_cnt_regval;
+-      struct {
+-              mmr_t   reserved_0  : 59;
+-              mmr_t   max_cnt     : 5;
+-      } sh_lb_max_req_credit_cnt_s;
+-} sh_lb_max_req_credit_cnt_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_PIO_TIME_OUT"                      */
+ /*                    Local Block PIO time out value                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_time_out_u {
+       mmr_t   sh_pio_time_out_regval;
+       struct {
+@@ -4338,22 +2376,12 @@
+               mmr_t   reserved_0  : 48;
+       } sh_pio_time_out_s;
+ } sh_pio_time_out_u_t;
+-#else
+-typedef union sh_pio_time_out_u {
+-      mmr_t   sh_pio_time_out_regval;
+-      struct {
+-              mmr_t   reserved_0  : 48;
+-              mmr_t   value       : 16;
+-      } sh_pio_time_out_s;
+-} sh_pio_time_out_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PIO_NACK_RESET"                     */
+ /*               Local Block PIO Reset for nack counters                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_nack_reset_u {
+       mmr_t   sh_pio_nack_reset_regval;
+       struct {
+@@ -4361,22 +2389,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_pio_nack_reset_s;
+ } sh_pio_nack_reset_u_t;
+-#else
+-typedef union sh_pio_nack_reset_u {
+-      mmr_t   sh_pio_nack_reset_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   pulse       : 1;
+-      } sh_pio_nack_reset_s;
+-} sh_pio_nack_reset_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_CONVEYOR_BELT_TIME_OUT"                 */
+ /*               Local Block conveyor belt time out value               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_conveyor_belt_time_out_u {
+       mmr_t   sh_conveyor_belt_time_out_regval;
+       struct {
+@@ -4384,22 +2402,12 @@
+               mmr_t   reserved_0  : 52;
+       } sh_conveyor_belt_time_out_s;
+ } sh_conveyor_belt_time_out_u_t;
+-#else
+-typedef union sh_conveyor_belt_time_out_u {
+-      mmr_t   sh_conveyor_belt_time_out_regval;
+-      struct {
+-              mmr_t   reserved_0  : 52;
+-              mmr_t   value       : 12;
+-      } sh_conveyor_belt_time_out_s;
+-} sh_conveyor_belt_time_out_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_LB_CREDIT_STATUS"                    */
+ /*                    Credit Counter Status Register                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_credit_status_u {
+       mmr_t   sh_lb_credit_status_regval;
+       struct {
+@@ -4413,28 +2421,12 @@
+               mmr_t   reserved_2    : 36;
+       } sh_lb_credit_status_s;
+ } sh_lb_credit_status_u_t;
+-#else
+-typedef union sh_lb_credit_status_u {
+-      mmr_t   sh_lb_credit_status_regval;
+-      struct {
+-              mmr_t   reserved_2    : 36;
+-              mmr_t   loq_rp_credit : 5;
+-              mmr_t   loq_rq_credit : 5;
+-              mmr_t   linvv_credit  : 6;
+-              mmr_t   reserved_1    : 2;
+-              mmr_t   liq_rp_credit : 4;
+-              mmr_t   reserved_0    : 1;
+-              mmr_t   liq_rq_credit : 5;
+-      } sh_lb_credit_status_s;
+-} sh_lb_credit_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_DEBUG_LOCAL_SEL"                   */
+ /*                         LB Debug Port Select                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_local_sel_u {
+       mmr_t   sh_lb_debug_local_sel_regval;
+       struct {
+@@ -4472,52 +2464,12 @@
+               mmr_t   trigger_enable      : 1;
+       } sh_lb_debug_local_sel_s;
+ } sh_lb_debug_local_sel_u_t;
+-#else
+-typedef union sh_lb_debug_local_sel_u {
+-      mmr_t   sh_lb_debug_local_sel_regval;
+-      struct {
+-              mmr_t   trigger_enable      : 1;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   reserved_14         : 1;
+-              mmr_t   nibble7_chiplet_sel : 3;
+-              mmr_t   reserved_13         : 1;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   reserved_12         : 1;
+-              mmr_t   nibble6_chiplet_sel : 3;
+-              mmr_t   reserved_11         : 1;
+-              mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   reserved_10         : 1;
+-              mmr_t   nibble5_chiplet_sel : 3;
+-              mmr_t   reserved_9          : 1;
+-              mmr_t   nibble4_nibble_sel  : 3;
+-              mmr_t   reserved_8          : 1;
+-              mmr_t   nibble4_chiplet_sel : 3;
+-              mmr_t   reserved_7          : 1;
+-              mmr_t   nibble3_nibble_sel  : 3;
+-              mmr_t   reserved_6          : 1;
+-              mmr_t   nibble3_chiplet_sel : 3;
+-              mmr_t   reserved_5          : 1;
+-              mmr_t   nibble2_nibble_sel  : 3;
+-              mmr_t   reserved_4          : 1;
+-              mmr_t   nibble2_chiplet_sel : 3;
+-              mmr_t   reserved_3          : 1;
+-              mmr_t   nibble1_nibble_sel  : 3;
+-              mmr_t   reserved_2          : 1;
+-              mmr_t   nibble1_chiplet_sel : 3;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   nibble0_nibble_sel  : 3;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   nibble0_chiplet_sel : 3;
+-      } sh_lb_debug_local_sel_s;
+-} sh_lb_debug_local_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_DEBUG_PERF_SEL"                    */
+ /*                   LB Debug Port Performance Select                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_perf_sel_u {
+       mmr_t   sh_lb_debug_perf_sel_regval;
+       struct {
+@@ -4555,52 +2507,12 @@
+               mmr_t   reserved_15         : 1;
+       } sh_lb_debug_perf_sel_s;
+ } sh_lb_debug_perf_sel_u_t;
+-#else
+-typedef union sh_lb_debug_perf_sel_u {
+-      mmr_t   sh_lb_debug_perf_sel_regval;
+-      struct {
+-              mmr_t   reserved_15         : 1;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   reserved_14         : 1;
+-              mmr_t   nibble7_chiplet_sel : 3;
+-              mmr_t   reserved_13         : 1;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   reserved_12         : 1;
+-              mmr_t   nibble6_chiplet_sel : 3;
+-              mmr_t   reserved_11         : 1;
+-              mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   reserved_10         : 1;
+-              mmr_t   nibble5_chiplet_sel : 3;
+-              mmr_t   reserved_9          : 1;
+-              mmr_t   nibble4_nibble_sel  : 3;
+-              mmr_t   reserved_8          : 1;
+-              mmr_t   nibble4_chiplet_sel : 3;
+-              mmr_t   reserved_7          : 1;
+-              mmr_t   nibble3_nibble_sel  : 3;
+-              mmr_t   reserved_6          : 1;
+-              mmr_t   nibble3_chiplet_sel : 3;
+-              mmr_t   reserved_5          : 1;
+-              mmr_t   nibble2_nibble_sel  : 3;
+-              mmr_t   reserved_4          : 1;
+-              mmr_t   nibble2_chiplet_sel : 3;
+-              mmr_t   reserved_3          : 1;
+-              mmr_t   nibble1_nibble_sel  : 3;
+-              mmr_t   reserved_2          : 1;
+-              mmr_t   nibble1_chiplet_sel : 3;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   nibble0_nibble_sel  : 3;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   nibble0_chiplet_sel : 3;
+-      } sh_lb_debug_perf_sel_s;
+-} sh_lb_debug_perf_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_DEBUG_TRIG_SEL"                    */
+ /*                       LB Debug Trigger Select                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_trig_sel_u {
+       mmr_t   sh_lb_debug_trig_sel_regval;
+       struct {
+@@ -4638,52 +2550,12 @@
+               mmr_t   reserved_15          : 1;
+       } sh_lb_debug_trig_sel_s;
+ } sh_lb_debug_trig_sel_u_t;
+-#else
+-typedef union sh_lb_debug_trig_sel_u {
+-      mmr_t   sh_lb_debug_trig_sel_regval;
+-      struct {
+-              mmr_t   reserved_15          : 1;
+-              mmr_t   trigger7_nibble_sel  : 3;
+-              mmr_t   reserved_14          : 1;
+-              mmr_t   trigger7_chiplet_sel : 3;
+-              mmr_t   reserved_13          : 1;
+-              mmr_t   trigger6_nibble_sel  : 3;
+-              mmr_t   reserved_12          : 1;
+-              mmr_t   trigger6_chiplet_sel : 3;
+-              mmr_t   reserved_11          : 1;
+-              mmr_t   trigger5_nibble_sel  : 3;
+-              mmr_t   reserved_10          : 1;
+-              mmr_t   trigger5_chiplet_sel : 3;
+-              mmr_t   reserved_9           : 1;
+-              mmr_t   trigger4_nibble_sel  : 3;
+-              mmr_t   reserved_8           : 1;
+-              mmr_t   trigger4_chiplet_sel : 3;
+-              mmr_t   reserved_7           : 1;
+-              mmr_t   trigger3_nibble_sel  : 3;
+-              mmr_t   reserved_6           : 1;
+-              mmr_t   trigger3_chiplet_sel : 3;
+-              mmr_t   reserved_5           : 1;
+-              mmr_t   trigger2_nibble_sel  : 3;
+-              mmr_t   reserved_4           : 1;
+-              mmr_t   trigger2_chiplet_sel : 3;
+-              mmr_t   reserved_3           : 1;
+-              mmr_t   trigger1_nibble_sel  : 3;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   trigger1_chiplet_sel : 3;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   trigger0_nibble_sel  : 3;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   trigger0_chiplet_sel : 3;
+-      } sh_lb_debug_trig_sel_s;
+-} sh_lb_debug_trig_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_ERROR_DETAIL_1"                    */
+ /*                  LB Error capture information: HDR1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_detail_1_u {
+       mmr_t   sh_lb_error_detail_1_regval;
+       struct {
+@@ -4700,31 +2572,12 @@
+               mmr_t   valid       : 1;
+       } sh_lb_error_detail_1_s;
+ } sh_lb_error_detail_1_u_t;
+-#else
+-typedef union sh_lb_error_detail_1_u {
+-      mmr_t   sh_lb_error_detail_1_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_3  : 13;
+-              mmr_t   data_err    : 1;
+-              mmr_t   hdr_err     : 1;
+-              mmr_t   reserved_2  : 5;
+-              mmr_t   dest        : 3;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   source      : 14;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   suppl       : 14;
+-              mmr_t   command     : 8;
+-      } sh_lb_error_detail_1_s;
+-} sh_lb_error_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_ERROR_DETAIL_2"                    */
+ /*                            LB Error Bits                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_detail_2_u {
+       mmr_t   sh_lb_error_detail_2_regval;
+       struct {
+@@ -4732,64 +2585,36 @@
+               mmr_t   reserved_0  : 17;
+       } sh_lb_error_detail_2_s;
+ } sh_lb_error_detail_2_u_t;
+-#else
+-typedef union sh_lb_error_detail_2_u {
+-      mmr_t   sh_lb_error_detail_2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 17;
+-              mmr_t   address     : 47;
+-      } sh_lb_error_detail_2_s;
+-} sh_lb_error_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_ERROR_DETAIL_3"                    */
+ /*                            LB Error Bits                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_lb_error_detail_3_u {
+-      mmr_t   sh_lb_error_detail_3_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_lb_error_detail_3_s;
+-} sh_lb_error_detail_3_u_t;
+-#else
+ typedef union sh_lb_error_detail_3_u {
+       mmr_t   sh_lb_error_detail_3_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_lb_error_detail_3_s;
+ } sh_lb_error_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_ERROR_DETAIL_4"                    */
+ /*                            LB Error Bits                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_lb_error_detail_4_u {
+-      mmr_t   sh_lb_error_detail_4_regval;
+-      struct {
+-              mmr_t   route       : 64;
+-      } sh_lb_error_detail_4_s;
+-} sh_lb_error_detail_4_u_t;
+-#else
+ typedef union sh_lb_error_detail_4_u {
+       mmr_t   sh_lb_error_detail_4_regval;
+       struct {
+               mmr_t   route       : 64;
+       } sh_lb_error_detail_4_s;
+ } sh_lb_error_detail_4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_ERROR_DETAIL_5"                    */
+ /*                            LB Error Bits                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_detail_5_u {
+       mmr_t   sh_lb_error_detail_5_regval;
+       struct {
+@@ -4803,28 +2628,12 @@
+               mmr_t   reserved_0       : 57;
+       } sh_lb_error_detail_5_s;
+ } sh_lb_error_detail_5_u_t;
+-#else
+-typedef union sh_lb_error_detail_5_u {
+-      mmr_t   sh_lb_error_detail_5_regval;
+-      struct {
+-              mmr_t   reserved_0       : 57;
+-              mmr_t   nack_b_timeout   : 1;
+-              mmr_t   nack_a_timeout   : 1;
+-              mmr_t   count_b_overflow : 1;
+-              mmr_t   count_a_overflow : 1;
+-              mmr_t   write_retry      : 1;
+-              mmr_t   ptc1_write       : 1;
+-              mmr_t   read_retry       : 1;
+-      } sh_lb_error_detail_5_s;
+-} sh_lb_error_detail_5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_LB_ERROR_MASK"                      */
+ /*                            LB Error Mask                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_mask_u {
+       mmr_t   sh_lb_error_mask_regval;
+       struct {
+@@ -4854,44 +2663,12 @@
+               mmr_t   reserved_0            : 41;
+       } sh_lb_error_mask_s;
+ } sh_lb_error_mask_u_t;
+-#else
+-typedef union sh_lb_error_mask_u {
+-      mmr_t   sh_lb_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_0            : 41;
+-              mmr_t   rp_credit_overflow    : 1;
+-              mmr_t   rq_credit_overflow    : 1;
+-              mmr_t   unexp_valid           : 1;
+-              mmr_t   rp_fifo_error         : 1;
+-              mmr_t   rq_fifo_error         : 1;
+-              mmr_t   gclk_drop             : 1;
+-              mmr_t   vector_rp_route_error : 1;
+-              mmr_t   vector_rq_route_error : 1;
+-              mmr_t   pio_cb_err            : 1;
+-              mmr_t   junk_bus_err          : 1;
+-              mmr_t   ptc_1_timeout         : 1;
+-              mmr_t   unexpected_linv       : 1;
+-              mmr_t   linvv_overflow        : 1;
+-              mmr_t   rq_time_out           : 1;
+-              mmr_t   rq_bad_addr           : 1;
+-              mmr_t   rp_bad_data           : 1;
+-              mmr_t   rq_bad_data           : 1;
+-              mmr_t   rp_long               : 1;
+-              mmr_t   rq_long               : 1;
+-              mmr_t   rp_short              : 1;
+-              mmr_t   rq_short              : 1;
+-              mmr_t   rp_bad_cmd            : 1;
+-              mmr_t   rq_bad_cmd            : 1;
+-      } sh_lb_error_mask_s;
+-} sh_lb_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_ERROR_OVERFLOW"                    */
+ /*                          LB Error Overflow                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_overflow_u {
+       mmr_t   sh_lb_error_overflow_regval;
+       struct {
+@@ -4921,44 +2698,12 @@
+               mmr_t   reserved_0                  : 41;
+       } sh_lb_error_overflow_s;
+ } sh_lb_error_overflow_u_t;
+-#else
+-typedef union sh_lb_error_overflow_u {
+-      mmr_t   sh_lb_error_overflow_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 41;
+-              mmr_t   rp_credit_overflow_ovrfl    : 1;
+-              mmr_t   rq_credit_overflow_ovrfl    : 1;
+-              mmr_t   unexp_valid_ovrfl           : 1;
+-              mmr_t   rp_fifo_error_ovrfl         : 1;
+-              mmr_t   rq_fifo_error_ovrfl         : 1;
+-              mmr_t   gclk_drop_ovrfl             : 1;
+-              mmr_t   vector_rp_route_error_ovrfl : 1;
+-              mmr_t   vector_rq_route_error_ovrfl : 1;
+-              mmr_t   pio_cb_err_ovrfl            : 1;
+-              mmr_t   junk_bus_err_ovrfl          : 1;
+-              mmr_t   ptc_1_timeout_ovrfl         : 1;
+-              mmr_t   unexpected_linv_ovrfl       : 1;
+-              mmr_t   linvv_overflow_ovrfl        : 1;
+-              mmr_t   rq_time_out_ovrfl           : 1;
+-              mmr_t   rq_bad_addr_ovrfl           : 1;
+-              mmr_t   rp_bad_data_ovrfl           : 1;
+-              mmr_t   rq_bad_data_ovrfl           : 1;
+-              mmr_t   rp_long_ovrfl               : 1;
+-              mmr_t   rq_long_ovrfl               : 1;
+-              mmr_t   rp_short_ovrfl              : 1;
+-              mmr_t   rq_short_ovrfl              : 1;
+-              mmr_t   rp_bad_cmd_ovrfl            : 1;
+-              mmr_t   rq_bad_cmd_ovrfl            : 1;
+-      } sh_lb_error_overflow_s;
+-} sh_lb_error_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_LB_ERROR_SUMMARY"                    */
+ /*                            LB Error Bits                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_error_summary_u {
+       mmr_t   sh_lb_error_summary_regval;
+       struct {
+@@ -4988,44 +2733,12 @@
+               mmr_t   reserved_0            : 41;
+       } sh_lb_error_summary_s;
+ } sh_lb_error_summary_u_t;
+-#else
+-typedef union sh_lb_error_summary_u {
+-      mmr_t   sh_lb_error_summary_regval;
+-      struct {
+-              mmr_t   reserved_0            : 41;
+-              mmr_t   rp_credit_overflow    : 1;
+-              mmr_t   rq_credit_overflow    : 1;
+-              mmr_t   unexp_valid           : 1;
+-              mmr_t   rp_fifo_error         : 1;
+-              mmr_t   rq_fifo_error         : 1;
+-              mmr_t   gclk_drop             : 1;
+-              mmr_t   vector_rp_route_error : 1;
+-              mmr_t   vector_rq_route_error : 1;
+-              mmr_t   pio_cb_err            : 1;
+-              mmr_t   junk_bus_err          : 1;
+-              mmr_t   ptc_1_timeout         : 1;
+-              mmr_t   unexpected_linv       : 1;
+-              mmr_t   linvv_overflow        : 1;
+-              mmr_t   rq_time_out           : 1;
+-              mmr_t   rq_bad_addr           : 1;
+-              mmr_t   rp_bad_data           : 1;
+-              mmr_t   rq_bad_data           : 1;
+-              mmr_t   rp_long               : 1;
+-              mmr_t   rq_long               : 1;
+-              mmr_t   rp_short              : 1;
+-              mmr_t   rq_short              : 1;
+-              mmr_t   rp_bad_cmd            : 1;
+-              mmr_t   rq_bad_cmd            : 1;
+-      } sh_lb_error_summary_s;
+-} sh_lb_error_summary_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_LB_FIRST_ERROR"                     */
+ /*                            LB First Error                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_first_error_u {
+       mmr_t   sh_lb_first_error_regval;
+       struct {
+@@ -5055,44 +2768,12 @@
+               mmr_t   reserved_0            : 41;
+       } sh_lb_first_error_s;
+ } sh_lb_first_error_u_t;
+-#else
+-typedef union sh_lb_first_error_u {
+-      mmr_t   sh_lb_first_error_regval;
+-      struct {
+-              mmr_t   reserved_0            : 41;
+-              mmr_t   rp_credit_overflow    : 1;
+-              mmr_t   rq_credit_overflow    : 1;
+-              mmr_t   unexp_valid           : 1;
+-              mmr_t   rp_fifo_error         : 1;
+-              mmr_t   rq_fifo_error         : 1;
+-              mmr_t   gclk_drop             : 1;
+-              mmr_t   vector_rp_route_error : 1;
+-              mmr_t   vector_rq_route_error : 1;
+-              mmr_t   pio_cb_err            : 1;
+-              mmr_t   junk_bus_err          : 1;
+-              mmr_t   ptc_1_timeout         : 1;
+-              mmr_t   unexpected_linv       : 1;
+-              mmr_t   linvv_overflow        : 1;
+-              mmr_t   rq_time_out           : 1;
+-              mmr_t   rq_bad_addr           : 1;
+-              mmr_t   rp_bad_data           : 1;
+-              mmr_t   rq_bad_data           : 1;
+-              mmr_t   rp_long               : 1;
+-              mmr_t   rq_long               : 1;
+-              mmr_t   rp_short              : 1;
+-              mmr_t   rq_short              : 1;
+-              mmr_t   rp_bad_cmd            : 1;
+-              mmr_t   rq_bad_cmd            : 1;
+-      } sh_lb_first_error_s;
+-} sh_lb_first_error_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_LB_LAST_CREDIT"                     */
+ /*                    Credit counter status register                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_last_credit_u {
+       mmr_t   sh_lb_last_credit_regval;
+       struct {
+@@ -5106,28 +2787,12 @@
+               mmr_t   reserved_2    : 36;
+       } sh_lb_last_credit_s;
+ } sh_lb_last_credit_u_t;
+-#else
+-typedef union sh_lb_last_credit_u {
+-      mmr_t   sh_lb_last_credit_regval;
+-      struct {
+-              mmr_t   reserved_2    : 36;
+-              mmr_t   loq_rp_credit : 5;
+-              mmr_t   loq_rq_credit : 5;
+-              mmr_t   linvv_credit  : 6;
+-              mmr_t   reserved_1    : 2;
+-              mmr_t   liq_rp_credit : 4;
+-              mmr_t   reserved_0    : 1;
+-              mmr_t   liq_rq_credit : 5;
+-      } sh_lb_last_credit_s;
+-} sh_lb_last_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_LB_NACK_STATUS"                     */
+ /*                     Nack Counter Status Register                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_nack_status_u {
+       mmr_t   sh_lb_nack_status_regval;
+       struct {
+@@ -5141,28 +2806,12 @@
+               mmr_t   reserved_2       : 2;
+       } sh_lb_nack_status_s;
+ } sh_lb_nack_status_u_t;
+-#else
+-typedef union sh_lb_nack_status_u {
+-      mmr_t   sh_lb_nack_status_regval;
+-      struct {
+-              mmr_t   reserved_2       : 2;
+-              mmr_t   cb_state         : 2;
+-              mmr_t   cb_timeout_count : 12;
+-              mmr_t   junk_nack        : 16;
+-              mmr_t   reserved_1       : 4;
+-              mmr_t   pio_nack_b       : 12;
+-              mmr_t   reserved_0       : 4;
+-              mmr_t   pio_nack_a       : 12;
+-      } sh_lb_nack_status_s;
+-} sh_lb_nack_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_LB_TRIGGER_COMPARE"                   */
+ /*                    LB Test-point Trigger Compare                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_trigger_compare_u {
+       mmr_t   sh_lb_trigger_compare_regval;
+       struct {
+@@ -5170,22 +2819,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_lb_trigger_compare_s;
+ } sh_lb_trigger_compare_u_t;
+-#else
+-typedef union sh_lb_trigger_compare_u {
+-      mmr_t   sh_lb_trigger_compare_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   mask        : 32;
+-      } sh_lb_trigger_compare_s;
+-} sh_lb_trigger_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_LB_TRIGGER_DATA"                     */
+ /*                  LB Test-point Trigger Compare Data                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_trigger_data_u {
+       mmr_t   sh_lb_trigger_data_regval;
+       struct {
+@@ -5193,22 +2832,12 @@
+               mmr_t   reserved_0      : 32;
+       } sh_lb_trigger_data_s;
+ } sh_lb_trigger_data_u_t;
+-#else
+-typedef union sh_lb_trigger_data_u {
+-      mmr_t   sh_lb_trigger_data_regval;
+-      struct {
+-              mmr_t   reserved_0      : 32;
+-              mmr_t   compare_pattern : 32;
+-      } sh_lb_trigger_data_s;
+-} sh_lb_trigger_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PI_AEC_CONFIG"                      */
+ /*              PI Adaptive Error Correction Configuration              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_aec_config_u {
+       mmr_t   sh_pi_aec_config_regval;
+       struct {
+@@ -5216,22 +2845,12 @@
+               mmr_t   reserved_0  : 61;
+       } sh_pi_aec_config_s;
+ } sh_pi_aec_config_u_t;
+-#else
+-typedef union sh_pi_aec_config_u {
+-      mmr_t   sh_pi_aec_config_regval;
+-      struct {
+-              mmr_t   reserved_0  : 61;
+-              mmr_t   mode        : 3;
+-      } sh_pi_aec_config_s;
+-} sh_pi_aec_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_AFI_ERROR_MASK"                    */
+ /*                          PI AFI Error Mask                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_error_mask_u {
+       mmr_t   sh_pi_afi_error_mask_regval;
+       struct {
+@@ -5253,36 +2872,12 @@
+               mmr_t   reserved_1   : 29;
+       } sh_pi_afi_error_mask_s;
+ } sh_pi_afi_error_mask_u_t;
+-#else
+-typedef union sh_pi_afi_error_mask_u {
+-      mmr_t   sh_pi_afi_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_1   : 29;
+-              mmr_t   msg_len      : 1;
+-              mmr_t   fsb_tbl_miss : 1;
+-              mmr_t   bad_snoop    : 1;
+-              mmr_t   livelock     : 1;
+-              mmr_t   shub_fsb_ce  : 1;
+-              mmr_t   shub_fsb_uce : 1;
+-              mmr_t   shub_fsb_dqe : 1;
+-              mmr_t   addr_parity  : 1;
+-              mmr_t   req_parity   : 1;
+-              mmr_t   addr_access  : 1;
+-              mmr_t   req_format   : 1;
+-              mmr_t   ioq_overrun  : 1;
+-              mmr_t   rsp_parity   : 1;
+-              mmr_t   hung_bus     : 1;
+-              mmr_t   reserved_0   : 21;
+-      } sh_pi_afi_error_mask_s;
+-} sh_pi_afi_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_AFI_TEST_POINT_COMPARE"                */
+ /*                      PI AFI Test Point Compare                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_test_point_compare_u {
+       mmr_t   sh_pi_afi_test_point_compare_regval;
+       struct {
+@@ -5290,22 +2885,12 @@
+               mmr_t   compare_pattern : 32;
+       } sh_pi_afi_test_point_compare_s;
+ } sh_pi_afi_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_afi_test_point_compare_u {
+-      mmr_t   sh_pi_afi_test_point_compare_regval;
+-      struct {
+-              mmr_t   compare_pattern : 32;
+-              mmr_t   compare_mask    : 32;
+-      } sh_pi_afi_test_point_compare_s;
+-} sh_pi_afi_test_point_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_AFI_TEST_POINT_SELECT"                */
+ /*                       PI AFI Test Point Select                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_test_point_select_u {
+       mmr_t   sh_pi_afi_test_point_select_regval;
+       struct {
+@@ -5335,44 +2920,12 @@
+               mmr_t   trigger_enable      : 1;
+       } sh_pi_afi_test_point_select_s;
+ } sh_pi_afi_test_point_select_u_t;
+-#else
+-typedef union sh_pi_afi_test_point_select_u {
+-      mmr_t   sh_pi_afi_test_point_select_regval;
+-      struct {
+-              mmr_t   trigger_enable      : 1;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   nibble7_chiplet_sel : 4;
+-              mmr_t   reserved_6          : 1;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   nibble6_chiplet_sel : 4;
+-              mmr_t   reserved_5          : 1;
+-              mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   nibble5_chiplet_sel : 4;
+-              mmr_t   reserved_4          : 1;
+-              mmr_t   nibble4_nibble_sel  : 3;
+-              mmr_t   nibble4_chiplet_sel : 4;
+-              mmr_t   reserved_3          : 1;
+-              mmr_t   nibble3_nibble_sel  : 3;
+-              mmr_t   nibble3_chiplet_sel : 4;
+-              mmr_t   reserved_2          : 1;
+-              mmr_t   nibble2_nibble_sel  : 3;
+-              mmr_t   nibble2_chiplet_sel : 4;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   nibble1_nibble_sel  : 3;
+-              mmr_t   nibble1_chiplet_sel : 4;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   nibble0_nibble_sel  : 3;
+-              mmr_t   nibble0_chiplet_sel : 4;
+-      } sh_pi_afi_test_point_select_s;
+-} sh_pi_afi_test_point_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*            Register "SH_PI_AFI_TEST_POINT_TRIGGER_SELECT"            */
+ /*                  PI CRBC Test Point Trigger Select                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_test_point_trigger_select_u {
+       mmr_t   sh_pi_afi_test_point_trigger_select_regval;
+       struct {
+@@ -5402,44 +2955,12 @@
+               mmr_t   reserved_7           : 1;
+       } sh_pi_afi_test_point_trigger_select_s;
+ } sh_pi_afi_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_afi_test_point_trigger_select_u {
+-      mmr_t   sh_pi_afi_test_point_trigger_select_regval;
+-      struct {
+-              mmr_t   reserved_7           : 1;
+-              mmr_t   trigger7_nibble_sel  : 3;
+-              mmr_t   trigger7_chiplet_sel : 4;
+-              mmr_t   reserved_6           : 1;
+-              mmr_t   trigger6_nibble_sel  : 3;
+-              mmr_t   trigger6_chiplet_sel : 4;
+-              mmr_t   reserved_5           : 1;
+-              mmr_t   trigger5_nibble_sel  : 3;
+-              mmr_t   trigger5_chiplet_sel : 4;
+-              mmr_t   reserved_4           : 1;
+-              mmr_t   trigger4_nibble_sel  : 3;
+-              mmr_t   trigger4_chiplet_sel : 4;
+-              mmr_t   reserved_3           : 1;
+-              mmr_t   trigger3_nibble_sel  : 3;
+-              mmr_t   trigger3_chiplet_sel : 4;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   trigger2_nibble_sel  : 3;
+-              mmr_t   trigger2_chiplet_sel : 4;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   trigger1_nibble_sel  : 3;
+-              mmr_t   trigger1_chiplet_sel : 4;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   trigger0_nibble_sel  : 3;
+-              mmr_t   trigger0_chiplet_sel : 4;
+-      } sh_pi_afi_test_point_trigger_select_s;
+-} sh_pi_afi_test_point_trigger_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PI_AUTO_REPLY_ENABLE"                  */
+ /*                         PI Auto Reply Enable                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_auto_reply_enable_u {
+       mmr_t   sh_pi_auto_reply_enable_regval;
+       struct {
+@@ -5447,22 +2968,12 @@
+               mmr_t   reserved_0        : 63;
+       } sh_pi_auto_reply_enable_s;
+ } sh_pi_auto_reply_enable_u_t;
+-#else
+-typedef union sh_pi_auto_reply_enable_u {
+-      mmr_t   sh_pi_auto_reply_enable_regval;
+-      struct {
+-              mmr_t   reserved_0        : 63;
+-              mmr_t   auto_reply_enable : 1;
+-      } sh_pi_auto_reply_enable_s;
+-} sh_pi_auto_reply_enable_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PI_CAM_CONTROL"                     */
+ /*                      CRB CAM MMR Access Control                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_cam_control_u {
+       mmr_t   sh_pi_cam_control_regval;
+       struct {
+@@ -5474,26 +2985,12 @@
+               mmr_t   start             : 1;
+       } sh_pi_cam_control_s;
+ } sh_pi_cam_control_u_t;
+-#else
+-typedef union sh_pi_cam_control_u {
+-      mmr_t   sh_pi_cam_control_regval;
+-      struct {
+-              mmr_t   start             : 1;
+-              mmr_t   reserved_1        : 53;
+-              mmr_t   rrb_rd_xfer_clear : 1;
+-              mmr_t   cam_write         : 1;
+-              mmr_t   reserved_0        : 1;
+-              mmr_t   cam_indx          : 7;
+-      } sh_pi_cam_control_s;
+-} sh_pi_cam_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_CRBC_TEST_POINT_COMPARE"               */
+ /*                      PI CRBC Test Point Compare                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbc_test_point_compare_u {
+       mmr_t   sh_pi_crbc_test_point_compare_regval;
+       struct {
+@@ -5501,22 +2998,12 @@
+               mmr_t   compare_pattern : 32;
+       } sh_pi_crbc_test_point_compare_s;
+ } sh_pi_crbc_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_crbc_test_point_compare_u {
+-      mmr_t   sh_pi_crbc_test_point_compare_regval;
+-      struct {
+-              mmr_t   compare_pattern : 32;
+-              mmr_t   compare_mask    : 32;
+-      } sh_pi_crbc_test_point_compare_s;
+-} sh_pi_crbc_test_point_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_CRBC_TEST_POINT_SELECT"                */
+ /*                      PI CRBC Test Point Select                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbc_test_point_select_u {
+       mmr_t   sh_pi_crbc_test_point_select_regval;
+       struct {
+@@ -5554,54 +3041,14 @@
+               mmr_t   trigger_enable      : 1;
+       } sh_pi_crbc_test_point_select_s;
+ } sh_pi_crbc_test_point_select_u_t;
+-#else
+-typedef union sh_pi_crbc_test_point_select_u {
+-      mmr_t   sh_pi_crbc_test_point_select_regval;
+-      struct {
+-              mmr_t   trigger_enable      : 1;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   reserved_14         : 1;
+-              mmr_t   nibble7_chiplet_sel : 3;
+-              mmr_t   reserved_13         : 1;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   reserved_12         : 1;
+-              mmr_t   nibble6_chiplet_sel : 3;
+-              mmr_t   reserved_11         : 1;
+-              mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   reserved_10         : 1;
+-              mmr_t   nibble5_chiplet_sel : 3;
+-              mmr_t   reserved_9          : 1;
+-              mmr_t   nibble4_nibble_sel  : 3;
+-              mmr_t   reserved_8          : 1;
+-              mmr_t   nibble4_chiplet_sel : 3;
+-              mmr_t   reserved_7          : 1;
+-              mmr_t   nibble3_nibble_sel  : 3;
+-              mmr_t   reserved_6          : 1;
+-              mmr_t   nibble3_chiplet_sel : 3;
+-              mmr_t   reserved_5          : 1;
+-              mmr_t   nibble2_nibble_sel  : 3;
+-              mmr_t   reserved_4          : 1;
+-              mmr_t   nibble2_chiplet_sel : 3;
+-              mmr_t   reserved_3          : 1;
+-              mmr_t   nibble1_nibble_sel  : 3;
+-              mmr_t   reserved_2          : 1;
+-              mmr_t   nibble1_chiplet_sel : 3;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   nibble0_nibble_sel  : 3;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   nibble0_chiplet_sel : 3;
+-      } sh_pi_crbc_test_point_select_s;
+-} sh_pi_crbc_test_point_select_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*           Register "SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT"            */
+-/*                  PI CRBC Test Point Trigger Select                   */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_crbc_test_point_trigger_select_u {
+-      mmr_t   sh_pi_crbc_test_point_trigger_select_regval;
++
++/* ==================================================================== */
++/*           Register "SH_PI_CRBC_TEST_POINT_TRIGGER_SELECT"            */
++/*                  PI CRBC Test Point Trigger Select                   */
++/* ==================================================================== */
++
++typedef union sh_pi_crbc_test_point_trigger_select_u {
++      mmr_t   sh_pi_crbc_test_point_trigger_select_regval;
+       struct {
+               mmr_t   trigger0_chiplet_sel : 3;
+               mmr_t   reserved_0           : 1;
+@@ -5637,52 +3084,12 @@
+               mmr_t   reserved_15          : 1;
+       } sh_pi_crbc_test_point_trigger_select_s;
+ } sh_pi_crbc_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_crbc_test_point_trigger_select_u {
+-      mmr_t   sh_pi_crbc_test_point_trigger_select_regval;
+-      struct {
+-              mmr_t   reserved_15          : 1;
+-              mmr_t   trigger7_nibble_sel  : 3;
+-              mmr_t   reserved_14          : 1;
+-              mmr_t   trigger7_chiplet_sel : 3;
+-              mmr_t   reserved_13          : 1;
+-              mmr_t   trigger6_nibble_sel  : 3;
+-              mmr_t   reserved_12          : 1;
+-              mmr_t   trigger6_chiplet_sel : 3;
+-              mmr_t   reserved_11          : 1;
+-              mmr_t   trigger5_nibble_sel  : 3;
+-              mmr_t   reserved_10          : 1;
+-              mmr_t   trigger5_chiplet_sel : 3;
+-              mmr_t   reserved_9           : 1;
+-              mmr_t   trigger4_nibble_sel  : 3;
+-              mmr_t   reserved_8           : 1;
+-              mmr_t   trigger4_chiplet_sel : 3;
+-              mmr_t   reserved_7           : 1;
+-              mmr_t   trigger3_nibble_sel  : 3;
+-              mmr_t   reserved_6           : 1;
+-              mmr_t   trigger3_chiplet_sel : 3;
+-              mmr_t   reserved_5           : 1;
+-              mmr_t   trigger2_nibble_sel  : 3;
+-              mmr_t   reserved_4           : 1;
+-              mmr_t   trigger2_chiplet_sel : 3;
+-              mmr_t   reserved_3           : 1;
+-              mmr_t   trigger1_nibble_sel  : 3;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   trigger1_chiplet_sel : 3;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   trigger0_nibble_sel  : 3;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   trigger0_chiplet_sel : 3;
+-      } sh_pi_crbc_test_point_trigger_select_s;
+-} sh_pi_crbc_test_point_trigger_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_CRBP_ERROR_MASK"                   */
+ /*                          PI CRBP Error Mask                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_error_mask_u {
+       mmr_t   sh_pi_crbp_error_mask_regval;
+       struct {
+@@ -5710,42 +3117,12 @@
+               mmr_t   reserved_0      : 43;
+       } sh_pi_crbp_error_mask_s;
+ } sh_pi_crbp_error_mask_u_t;
+-#else
+-typedef union sh_pi_crbp_error_mask_u {
+-      mmr_t   sh_pi_crbp_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_0      : 43;
+-              mmr_t   xn_rp_crd_oflow : 1;
+-              mmr_t   xn_rq_crd_oflow : 1;
+-              mmr_t   md_rp_crd_oflow : 1;
+-              mmr_t   md_rq_crd_oflow : 1;
+-              mmr_t   gfx_int_1       : 1;
+-              mmr_t   gfx_int_0       : 1;
+-              mmr_t   nack_oflow      : 1;
+-              mmr_t   xn_rp_q_oflow   : 1;
+-              mmr_t   xn_rq_q_oflow   : 1;
+-              mmr_t   md_rp_q_oflow   : 1;
+-              mmr_t   md_rq_q_oflow   : 1;
+-              mmr_t   msg_color_err   : 1;
+-              mmr_t   fsb_shub_ce     : 1;
+-              mmr_t   fsb_shub_uce    : 1;
+-              mmr_t   pio_to_err      : 1;
+-              mmr_t   mem_to_err      : 1;
+-              mmr_t   pio_rp_err      : 1;
+-              mmr_t   mem_rp_err      : 1;
+-              mmr_t   xb_proto_err    : 1;
+-              mmr_t   gfx_rp_err      : 1;
+-              mmr_t   fsb_proto_err   : 1;
+-      } sh_pi_crbp_error_mask_s;
+-} sh_pi_crbp_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_CRBP_FSB_PIPE_COMPARE"                */
+ /*                        CRBP FSB Pipe Compare                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_fsb_pipe_compare_u {
+       mmr_t   sh_pi_crbp_fsb_pipe_compare_regval;
+       struct {
+@@ -5754,23 +3131,12 @@
+               mmr_t   reserved_0      : 11;
+       } sh_pi_crbp_fsb_pipe_compare_s;
+ } sh_pi_crbp_fsb_pipe_compare_u_t;
+-#else
+-typedef union sh_pi_crbp_fsb_pipe_compare_u {
+-      mmr_t   sh_pi_crbp_fsb_pipe_compare_regval;
+-      struct {
+-              mmr_t   reserved_0      : 11;
+-              mmr_t   compare_req     : 6;
+-              mmr_t   compare_address : 47;
+-      } sh_pi_crbp_fsb_pipe_compare_s;
+-} sh_pi_crbp_fsb_pipe_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CRBP_FSB_PIPE_MASK"                  */
+ /*                          CRBP Compare Mask                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_fsb_pipe_mask_u {
+       mmr_t   sh_pi_crbp_fsb_pipe_mask_regval;
+       struct {
+@@ -5779,23 +3145,12 @@
+               mmr_t   reserved_0           : 11;
+       } sh_pi_crbp_fsb_pipe_mask_s;
+ } sh_pi_crbp_fsb_pipe_mask_u_t;
+-#else
+-typedef union sh_pi_crbp_fsb_pipe_mask_u {
+-      mmr_t   sh_pi_crbp_fsb_pipe_mask_regval;
+-      struct {
+-              mmr_t   reserved_0           : 11;
+-              mmr_t   compare_req_mask     : 6;
+-              mmr_t   compare_address_mask : 47;
+-      } sh_pi_crbp_fsb_pipe_mask_s;
+-} sh_pi_crbp_fsb_pipe_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_CRBP_TEST_POINT_COMPARE"               */
+ /*                      PI CRBP Test Point Compare                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_test_point_compare_u {
+       mmr_t   sh_pi_crbp_test_point_compare_regval;
+       struct {
+@@ -5803,22 +3158,12 @@
+               mmr_t   compare_pattern : 32;
+       } sh_pi_crbp_test_point_compare_s;
+ } sh_pi_crbp_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_crbp_test_point_compare_u {
+-      mmr_t   sh_pi_crbp_test_point_compare_regval;
+-      struct {
+-              mmr_t   compare_pattern : 32;
+-              mmr_t   compare_mask    : 32;
+-      } sh_pi_crbp_test_point_compare_s;
+-} sh_pi_crbp_test_point_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_CRBP_TEST_POINT_SELECT"                */
+ /*                      PI CRBP Test Point Select                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_test_point_select_u {
+       mmr_t   sh_pi_crbp_test_point_select_regval;
+       struct {
+@@ -5856,52 +3201,12 @@
+               mmr_t   trigger_enable      : 1;
+       } sh_pi_crbp_test_point_select_s;
+ } sh_pi_crbp_test_point_select_u_t;
+-#else
+-typedef union sh_pi_crbp_test_point_select_u {
+-      mmr_t   sh_pi_crbp_test_point_select_regval;
+-      struct {
+-              mmr_t   trigger_enable      : 1;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   reserved_14         : 1;
+-              mmr_t   nibble7_chiplet_sel : 3;
+-              mmr_t   reserved_13         : 1;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   reserved_12         : 1;
+-              mmr_t   nibble6_chiplet_sel : 3;
+-              mmr_t   reserved_11         : 1;
+-              mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   reserved_10         : 1;
+-              mmr_t   nibble5_chiplet_sel : 3;
+-              mmr_t   reserved_9          : 1;
+-              mmr_t   nibble4_nibble_sel  : 3;
+-              mmr_t   reserved_8          : 1;
+-              mmr_t   nibble4_chiplet_sel : 3;
+-              mmr_t   reserved_7          : 1;
+-              mmr_t   nibble3_nibble_sel  : 3;
+-              mmr_t   reserved_6          : 1;
+-              mmr_t   nibble3_chiplet_sel : 3;
+-              mmr_t   reserved_5          : 1;
+-              mmr_t   nibble2_nibble_sel  : 3;
+-              mmr_t   reserved_4          : 1;
+-              mmr_t   nibble2_chiplet_sel : 3;
+-              mmr_t   reserved_3          : 1;
+-              mmr_t   nibble1_nibble_sel  : 3;
+-              mmr_t   reserved_2          : 1;
+-              mmr_t   nibble1_chiplet_sel : 3;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   nibble0_nibble_sel  : 3;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   nibble0_chiplet_sel : 3;
+-      } sh_pi_crbp_test_point_select_s;
+-} sh_pi_crbp_test_point_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*           Register "SH_PI_CRBP_TEST_POINT_TRIGGER_SELECT"            */
+ /*                  PI CRBP Test Point Trigger Select                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_test_point_trigger_select_u {
+       mmr_t   sh_pi_crbp_test_point_trigger_select_regval;
+       struct {
+@@ -5939,52 +3244,12 @@
+               mmr_t   reserved_15          : 1;
+       } sh_pi_crbp_test_point_trigger_select_s;
+ } sh_pi_crbp_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_crbp_test_point_trigger_select_u {
+-      mmr_t   sh_pi_crbp_test_point_trigger_select_regval;
+-      struct {
+-              mmr_t   reserved_15          : 1;
+-              mmr_t   trigger7_nibble_sel  : 3;
+-              mmr_t   reserved_14          : 1;
+-              mmr_t   trigger7_chiplet_sel : 3;
+-              mmr_t   reserved_13          : 1;
+-              mmr_t   trigger6_nibble_sel  : 3;
+-              mmr_t   reserved_12          : 1;
+-              mmr_t   trigger6_chiplet_sel : 3;
+-              mmr_t   reserved_11          : 1;
+-              mmr_t   trigger5_nibble_sel  : 3;
+-              mmr_t   reserved_10          : 1;
+-              mmr_t   trigger5_chiplet_sel : 3;
+-              mmr_t   reserved_9           : 1;
+-              mmr_t   trigger4_nibble_sel  : 3;
+-              mmr_t   reserved_8           : 1;
+-              mmr_t   trigger4_chiplet_sel : 3;
+-              mmr_t   reserved_7           : 1;
+-              mmr_t   trigger3_nibble_sel  : 3;
+-              mmr_t   reserved_6           : 1;
+-              mmr_t   trigger3_chiplet_sel : 3;
+-              mmr_t   reserved_5           : 1;
+-              mmr_t   trigger2_nibble_sel  : 3;
+-              mmr_t   reserved_4           : 1;
+-              mmr_t   trigger2_chiplet_sel : 3;
+-              mmr_t   reserved_3           : 1;
+-              mmr_t   trigger1_nibble_sel  : 3;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   trigger1_chiplet_sel : 3;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   trigger0_nibble_sel  : 3;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   trigger0_chiplet_sel : 3;
+-      } sh_pi_crbp_test_point_trigger_select_s;
+-} sh_pi_crbp_test_point_trigger_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_CRBP_XB_PIPE_COMPARE_0"                */
+ /*                         CRBP XB Pipe Compare                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_compare_0_u {
+       mmr_t   sh_pi_crbp_xb_pipe_compare_0_regval;
+       struct {
+@@ -5993,23 +3258,12 @@
+               mmr_t   reserved_0      : 9;
+       } sh_pi_crbp_xb_pipe_compare_0_s;
+ } sh_pi_crbp_xb_pipe_compare_0_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_compare_0_u {
+-      mmr_t   sh_pi_crbp_xb_pipe_compare_0_regval;
+-      struct {
+-              mmr_t   reserved_0      : 9;
+-              mmr_t   compare_command : 8;
+-              mmr_t   compare_address : 47;
+-      } sh_pi_crbp_xb_pipe_compare_0_s;
+-} sh_pi_crbp_xb_pipe_compare_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_CRBP_XB_PIPE_COMPARE_1"                */
+ /*                         CRBP XB Pipe Compare                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_compare_1_u {
+       mmr_t   sh_pi_crbp_xb_pipe_compare_1_regval;
+       struct {
+@@ -6021,26 +3275,12 @@
+               mmr_t   reserved_2           : 23;
+       } sh_pi_crbp_xb_pipe_compare_1_s;
+ } sh_pi_crbp_xb_pipe_compare_1_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_compare_1_u {
+-      mmr_t   sh_pi_crbp_xb_pipe_compare_1_regval;
+-      struct {
+-              mmr_t   reserved_2           : 23;
+-              mmr_t   compare_echo         : 9;
+-              mmr_t   reserved_1           : 2;
+-              mmr_t   compare_supplemental : 14;
+-              mmr_t   reserved_0           : 2;
+-              mmr_t   compare_source       : 14;
+-      } sh_pi_crbp_xb_pipe_compare_1_s;
+-} sh_pi_crbp_xb_pipe_compare_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CRBP_XB_PIPE_MASK_0"                 */
+ /*                     CRBP Compare Mask Register 1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_mask_0_u {
+       mmr_t   sh_pi_crbp_xb_pipe_mask_0_regval;
+       struct {
+@@ -6049,23 +3289,12 @@
+               mmr_t   reserved_0           : 9;
+       } sh_pi_crbp_xb_pipe_mask_0_s;
+ } sh_pi_crbp_xb_pipe_mask_0_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_mask_0_u {
+-      mmr_t   sh_pi_crbp_xb_pipe_mask_0_regval;
+-      struct {
+-              mmr_t   reserved_0           : 9;
+-              mmr_t   compare_command_mask : 8;
+-              mmr_t   compare_address_mask : 47;
+-      } sh_pi_crbp_xb_pipe_mask_0_s;
+-} sh_pi_crbp_xb_pipe_mask_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CRBP_XB_PIPE_MASK_1"                 */
+ /*                 CRBP XB Pipe Compare Mask Register 1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_xb_pipe_mask_1_u {
+       mmr_t   sh_pi_crbp_xb_pipe_mask_1_regval;
+       struct {
+@@ -6077,26 +3306,12 @@
+               mmr_t   reserved_2                : 23;
+       } sh_pi_crbp_xb_pipe_mask_1_s;
+ } sh_pi_crbp_xb_pipe_mask_1_u_t;
+-#else
+-typedef union sh_pi_crbp_xb_pipe_mask_1_u {
+-      mmr_t   sh_pi_crbp_xb_pipe_mask_1_regval;
+-      struct {
+-              mmr_t   reserved_2                : 23;
+-              mmr_t   compare_echo_mask         : 9;
+-              mmr_t   reserved_1                : 2;
+-              mmr_t   compare_supplemental_mask : 14;
+-              mmr_t   reserved_0                : 2;
+-              mmr_t   compare_source_mask       : 14;
+-      } sh_pi_crbp_xb_pipe_mask_1_s;
+-} sh_pi_crbp_xb_pipe_mask_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PI_DPC_QUEUE_CONFIG"                   */
+ /*                       DPC Queue Configuration                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_dpc_queue_config_u {
+       mmr_t   sh_pi_dpc_queue_config_regval;
+       struct {
+@@ -6110,28 +3325,12 @@
+               mmr_t   reserved_3     : 35;
+       } sh_pi_dpc_queue_config_s;
+ } sh_pi_dpc_queue_config_u_t;
+-#else
+-typedef union sh_pi_dpc_queue_config_u {
+-      mmr_t   sh_pi_dpc_queue_config_regval;
+-      struct {
+-              mmr_t   reserved_3     : 35;
+-              mmr_t   fwcq_af_thresh : 5;
+-              mmr_t   reserved_2     : 3;
+-              mmr_t   fwcq_ae_level  : 5;
+-              mmr_t   reserved_1     : 3;
+-              mmr_t   dwcq_af_thresh : 5;
+-              mmr_t   reserved_0     : 3;
+-              mmr_t   dwcq_ae_level  : 5;
+-      } sh_pi_dpc_queue_config_s;
+-} sh_pi_dpc_queue_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PI_ERROR_MASK"                      */
+ /*                            PI Error Mask                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_mask_u {
+       mmr_t   sh_pi_error_mask_regval;
+       struct {
+@@ -6173,56 +3372,12 @@
+               mmr_t   reserved_0      : 29;
+       } sh_pi_error_mask_s;
+ } sh_pi_error_mask_u_t;
+-#else
+-typedef union sh_pi_error_mask_u {
+-      mmr_t   sh_pi_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_0      : 29;
+-              mmr_t   msg_length      : 1;
+-              mmr_t   fsb_tbl_miss    : 1;
+-              mmr_t   bad_snoop       : 1;
+-              mmr_t   livelock        : 1;
+-              mmr_t   shub_fsb_ce     : 1;
+-              mmr_t   shub_fsb_uce    : 1;
+-              mmr_t   shub_fsb_dqe    : 1;
+-              mmr_t   addr_parity     : 1;
+-              mmr_t   req_parity      : 1;
+-              mmr_t   addr_access     : 1;
+-              mmr_t   req_format      : 1;
+-              mmr_t   ioq_overrun     : 1;
+-              mmr_t   rsp_parity      : 1;
+-              mmr_t   hung_bus        : 1;
+-              mmr_t   xn_rp_crd_oflow : 1;
+-              mmr_t   xn_rq_crd_oflow : 1;
+-              mmr_t   md_rp_crd_oflow : 1;
+-              mmr_t   md_rq_crd_oflow : 1;
+-              mmr_t   gfx_int_1       : 1;
+-              mmr_t   gfx_int_0       : 1;
+-              mmr_t   nack_oflow      : 1;
+-              mmr_t   xn_rp_q_oflow   : 1;
+-              mmr_t   xn_rq_q_oflow   : 1;
+-              mmr_t   md_rp_q_oflow   : 1;
+-              mmr_t   md_rq_q_oflow   : 1;
+-              mmr_t   msg_color_err   : 1;
+-              mmr_t   fsb_shub_ce     : 1;
+-              mmr_t   fsb_shub_uce    : 1;
+-              mmr_t   pio_to_err      : 1;
+-              mmr_t   mem_to_err      : 1;
+-              mmr_t   pio_rp_err      : 1;
+-              mmr_t   mem_rp_err      : 1;
+-              mmr_t   xb_proto_err    : 1;
+-              mmr_t   gfx_rp_err      : 1;
+-              mmr_t   fsb_proto_err   : 1;
+-      } sh_pi_error_mask_s;
+-} sh_pi_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_EXPRESS_REPLY_CONFIG"                 */
+ /*                    PI Express Reply Configuration                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_express_reply_config_u {
+       mmr_t   sh_pi_express_reply_config_regval;
+       struct {
+@@ -6230,64 +3385,36 @@
+               mmr_t   reserved_0  : 61;
+       } sh_pi_express_reply_config_s;
+ } sh_pi_express_reply_config_u_t;
+-#else
+-typedef union sh_pi_express_reply_config_u {
+-      mmr_t   sh_pi_express_reply_config_regval;
+-      struct {
+-              mmr_t   reserved_0  : 61;
+-              mmr_t   mode        : 3;
+-      } sh_pi_express_reply_config_s;
+-} sh_pi_express_reply_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PI_FSB_COMPARE_VALUE"                  */
+ /*                          FSB Compare Value                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_fsb_compare_value_u {
+-      mmr_t   sh_pi_fsb_compare_value_regval;
+-      struct {
+-              mmr_t   compare_value : 64;
+-      } sh_pi_fsb_compare_value_s;
+-} sh_pi_fsb_compare_value_u_t;
+-#else
+ typedef union sh_pi_fsb_compare_value_u {
+       mmr_t   sh_pi_fsb_compare_value_regval;
+       struct {
+               mmr_t   compare_value : 64;
+       } sh_pi_fsb_compare_value_s;
+ } sh_pi_fsb_compare_value_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PI_FSB_COMPARE_MASK"                   */
+ /*                           FSB Compare Mask                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_fsb_compare_mask_u {
+       mmr_t   sh_pi_fsb_compare_mask_regval;
+       struct {
+               mmr_t   mask_value  : 64;
+       } sh_pi_fsb_compare_mask_s;
+ } sh_pi_fsb_compare_mask_u_t;
+-#else
+-typedef union sh_pi_fsb_compare_mask_u {
+-      mmr_t   sh_pi_fsb_compare_mask_regval;
+-      struct {
+-              mmr_t   mask_value  : 64;
+-      } sh_pi_fsb_compare_mask_s;
+-} sh_pi_fsb_compare_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_FSB_ERROR_INJECTION"                 */
+ /*                     Inject an Error onto the FSB                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_fsb_error_injection_u {
+       mmr_t   sh_pi_fsb_error_injection_regval;
+       struct {
+@@ -6321,48 +3448,12 @@
+               mmr_t   reserved_2       : 29;
+       } sh_pi_fsb_error_injection_s;
+ } sh_pi_fsb_error_injection_u_t;
+-#else
+-typedef union sh_pi_fsb_error_injection_u {
+-      mmr_t   sh_pi_fsb_error_injection_regval;
+-      struct {
+-              mmr_t   reserved_2       : 29;
+-              mmr_t   bus_hang         : 1;
+-              mmr_t   livelock         : 1;
+-              mmr_t   ioq_overrun      : 1;
+-              mmr_t   reserved_1       : 4;
+-              mmr_t   dw3_uce_from_fsb : 1;
+-              mmr_t   dw3_ce_from_fsb  : 1;
+-              mmr_t   dw2_uce_from_fsb : 1;
+-              mmr_t   dw2_ce_from_fsb  : 1;
+-              mmr_t   dw1_uce_from_fsb : 1;
+-              mmr_t   dw1_ce_from_fsb  : 1;
+-              mmr_t   dw0_uce_from_fsb : 1;
+-              mmr_t   dw0_ce_from_fsb  : 1;
+-              mmr_t   rsp_pe_from_fsb  : 1;
+-              mmr_t   ap1_pe_from_fsb  : 1;
+-              mmr_t   ap0_pe_from_fsb  : 1;
+-              mmr_t   rp_pe_from_fsb   : 1;
+-              mmr_t   reserved_0       : 6;
+-              mmr_t   ip1_pe_to_fsb    : 1;
+-              mmr_t   ip0_pe_to_fsb    : 1;
+-              mmr_t   dw1_uce_to_fsb   : 1;
+-              mmr_t   dw1_ce_to_fsb    : 1;
+-              mmr_t   dw0_uce_to_fsb   : 1;
+-              mmr_t   dw0_ce_to_fsb    : 1;
+-              mmr_t   rsp_pe_to_fsb    : 1;
+-              mmr_t   ap1_pe_to_fsb    : 1;
+-              mmr_t   ap0_pe_to_fsb    : 1;
+-              mmr_t   rp_pe_to_fsb     : 1;
+-      } sh_pi_fsb_error_injection_s;
+-} sh_pi_fsb_error_injection_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_MD2PI_REPLY_VC_CONFIG"                */
+ /*             MD-to-PI Reply Virtual Channel Configuration             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_reply_vc_config_u {
+       mmr_t   sh_pi_md2pi_reply_vc_config_regval;
+       struct {
+@@ -6374,26 +3465,12 @@
+               mmr_t   capture_credit_status : 1;
+       } sh_pi_md2pi_reply_vc_config_s;
+ } sh_pi_md2pi_reply_vc_config_u_t;
+-#else
+-typedef union sh_pi_md2pi_reply_vc_config_u {
+-      mmr_t   sh_pi_md2pi_reply_vc_config_regval;
+-      struct {
+-              mmr_t   capture_credit_status : 1;
+-              mmr_t   force_credit          : 1;
+-              mmr_t   reserved_0            : 48;
+-              mmr_t   max_credits           : 6;
+-              mmr_t   data_depth            : 4;
+-              mmr_t   hdr_depth             : 4;
+-      } sh_pi_md2pi_reply_vc_config_s;
+-} sh_pi_md2pi_reply_vc_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_MD2PI_REQUEST_VC_CONFIG"               */
+ /*            MD-to-PI Request Virtual Channel Configuration            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_request_vc_config_u {
+       mmr_t   sh_pi_md2pi_request_vc_config_regval;
+       struct {
+@@ -6405,26 +3482,12 @@
+               mmr_t   capture_credit_status : 1;
+       } sh_pi_md2pi_request_vc_config_s;
+ } sh_pi_md2pi_request_vc_config_u_t;
+-#else
+-typedef union sh_pi_md2pi_request_vc_config_u {
+-      mmr_t   sh_pi_md2pi_request_vc_config_regval;
+-      struct {
+-              mmr_t   capture_credit_status : 1;
+-              mmr_t   force_credit          : 1;
+-              mmr_t   reserved_0            : 48;
+-              mmr_t   max_credits           : 6;
+-              mmr_t   data_depth            : 4;
+-              mmr_t   hdr_depth             : 4;
+-      } sh_pi_md2pi_request_vc_config_s;
+-} sh_pi_md2pi_request_vc_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_QUEUE_ERROR_INJECTION"                */
+ /*                       PI Queue Error Injection                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_queue_error_injection_u {
+       mmr_t   sh_pi_queue_error_injection_regval;
+       struct {
+@@ -6439,29 +3502,12 @@
+               mmr_t   reserved_0     : 56;
+       } sh_pi_queue_error_injection_s;
+ } sh_pi_queue_error_injection_u_t;
+-#else
+-typedef union sh_pi_queue_error_injection_u {
+-      mmr_t   sh_pi_queue_error_injection_regval;
+-      struct {
+-              mmr_t   reserved_0     : 56;
+-              mmr_t   xnpi_rpy_bfr   : 1;
+-              mmr_t   rxl_rdy_q      : 1;
+-              mmr_t   rxl_kill_q     : 1;
+-              mmr_t   ptc_intr       : 1;
+-              mmr_t   mdpi_rpy_bfr   : 1;
+-              mmr_t   fsb_wtl_cmnd_q : 1;
+-              mmr_t   dxb_wtl_cmnd_q : 1;
+-              mmr_t   dat_dfr_q      : 1;
+-      } sh_pi_queue_error_injection_s;
+-} sh_pi_queue_error_injection_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_TEST_POINT_COMPARE"                  */
+ /*                        PI Test Point Compare                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_test_point_compare_u {
+       mmr_t   sh_pi_test_point_compare_regval;
+       struct {
+@@ -6469,22 +3515,12 @@
+               mmr_t   compare_pattern : 32;
+       } sh_pi_test_point_compare_s;
+ } sh_pi_test_point_compare_u_t;
+-#else
+-typedef union sh_pi_test_point_compare_u {
+-      mmr_t   sh_pi_test_point_compare_regval;
+-      struct {
+-              mmr_t   compare_pattern : 32;
+-              mmr_t   compare_mask    : 32;
+-      } sh_pi_test_point_compare_s;
+-} sh_pi_test_point_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PI_TEST_POINT_SELECT"                  */
+ /*                         PI Test Point Select                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_test_point_select_u {
+       mmr_t   sh_pi_test_point_select_regval;
+       struct {
+@@ -6522,52 +3558,12 @@
+               mmr_t   trigger_enable      : 1;
+       } sh_pi_test_point_select_s;
+ } sh_pi_test_point_select_u_t;
+-#else
+-typedef union sh_pi_test_point_select_u {
+-      mmr_t   sh_pi_test_point_select_regval;
+-      struct {
+-              mmr_t   trigger_enable      : 1;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   reserved_14         : 1;
+-              mmr_t   nibble7_chiplet_sel : 3;
+-              mmr_t   reserved_13         : 1;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   reserved_12         : 1;
+-              mmr_t   nibble6_chiplet_sel : 3;
+-              mmr_t   reserved_11         : 1;
+-              mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   reserved_10         : 1;
+-              mmr_t   nibble5_chiplet_sel : 3;
+-              mmr_t   reserved_9          : 1;
+-              mmr_t   nibble4_nibble_sel  : 3;
+-              mmr_t   reserved_8          : 1;
+-              mmr_t   nibble4_chiplet_sel : 3;
+-              mmr_t   reserved_7          : 1;
+-              mmr_t   nibble3_nibble_sel  : 3;
+-              mmr_t   reserved_6          : 1;
+-              mmr_t   nibble3_chiplet_sel : 3;
+-              mmr_t   reserved_5          : 1;
+-              mmr_t   nibble2_nibble_sel  : 3;
+-              mmr_t   reserved_4          : 1;
+-              mmr_t   nibble2_chiplet_sel : 3;
+-              mmr_t   reserved_3          : 1;
+-              mmr_t   nibble1_nibble_sel  : 3;
+-              mmr_t   reserved_2          : 1;
+-              mmr_t   nibble1_chiplet_sel : 3;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   nibble0_nibble_sel  : 3;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   nibble0_chiplet_sel : 3;
+-      } sh_pi_test_point_select_s;
+-} sh_pi_test_point_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_PI_TEST_POINT_TRIGGER_SELECT"              */
+ /*                     PI Test Point Trigger Select                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_test_point_trigger_select_u {
+       mmr_t   sh_pi_test_point_trigger_select_regval;
+       struct {
+@@ -6605,52 +3601,12 @@
+               mmr_t   reserved_15          : 1;
+       } sh_pi_test_point_trigger_select_s;
+ } sh_pi_test_point_trigger_select_u_t;
+-#else
+-typedef union sh_pi_test_point_trigger_select_u {
+-      mmr_t   sh_pi_test_point_trigger_select_regval;
+-      struct {
+-              mmr_t   reserved_15          : 1;
+-              mmr_t   trigger7_nibble_sel  : 3;
+-              mmr_t   reserved_14          : 1;
+-              mmr_t   trigger7_chiplet_sel : 3;
+-              mmr_t   reserved_13          : 1;
+-              mmr_t   trigger6_nibble_sel  : 3;
+-              mmr_t   reserved_12          : 1;
+-              mmr_t   trigger6_chiplet_sel : 3;
+-              mmr_t   reserved_11          : 1;
+-              mmr_t   trigger5_nibble_sel  : 3;
+-              mmr_t   reserved_10          : 1;
+-              mmr_t   trigger5_chiplet_sel : 3;
+-              mmr_t   reserved_9           : 1;
+-              mmr_t   trigger4_nibble_sel  : 3;
+-              mmr_t   reserved_8           : 1;
+-              mmr_t   trigger4_chiplet_sel : 3;
+-              mmr_t   reserved_7           : 1;
+-              mmr_t   trigger3_nibble_sel  : 3;
+-              mmr_t   reserved_6           : 1;
+-              mmr_t   trigger3_chiplet_sel : 3;
+-              mmr_t   reserved_5           : 1;
+-              mmr_t   trigger2_nibble_sel  : 3;
+-              mmr_t   reserved_4           : 1;
+-              mmr_t   trigger2_chiplet_sel : 3;
+-              mmr_t   reserved_3           : 1;
+-              mmr_t   trigger1_nibble_sel  : 3;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   trigger1_chiplet_sel : 3;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   trigger0_nibble_sel  : 3;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   trigger0_chiplet_sel : 3;
+-      } sh_pi_test_point_trigger_select_s;
+-} sh_pi_test_point_trigger_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_XN2PI_REPLY_VC_CONFIG"                */
+ /*             XN-to-PI Reply Virtual Channel Configuration             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_reply_vc_config_u {
+       mmr_t   sh_pi_xn2pi_reply_vc_config_regval;
+       struct {
+@@ -6662,26 +3618,12 @@
+               mmr_t   capture_credit_status : 1;
+       } sh_pi_xn2pi_reply_vc_config_s;
+ } sh_pi_xn2pi_reply_vc_config_u_t;
+-#else
+-typedef union sh_pi_xn2pi_reply_vc_config_u {
+-      mmr_t   sh_pi_xn2pi_reply_vc_config_regval;
+-      struct {
+-              mmr_t   capture_credit_status : 1;
+-              mmr_t   force_credit          : 1;
+-              mmr_t   reserved_0            : 48;
+-              mmr_t   max_credits           : 6;
+-              mmr_t   data_depth            : 4;
+-              mmr_t   hdr_depth             : 4;
+-      } sh_pi_xn2pi_reply_vc_config_s;
+-} sh_pi_xn2pi_reply_vc_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_XN2PI_REQUEST_VC_CONFIG"               */
+ /*            XN-to-PI Request Virtual Channel Configuration            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_request_vc_config_u {
+       mmr_t   sh_pi_xn2pi_request_vc_config_regval;
+       struct {
+@@ -6693,26 +3635,12 @@
+               mmr_t   capture_credit_status : 1;
+       } sh_pi_xn2pi_request_vc_config_s;
+ } sh_pi_xn2pi_request_vc_config_u_t;
+-#else
+-typedef union sh_pi_xn2pi_request_vc_config_u {
+-      mmr_t   sh_pi_xn2pi_request_vc_config_regval;
+-      struct {
+-              mmr_t   capture_credit_status : 1;
+-              mmr_t   force_credit          : 1;
+-              mmr_t   reserved_0            : 48;
+-              mmr_t   max_credits           : 6;
+-              mmr_t   data_depth            : 4;
+-              mmr_t   hdr_depth             : 4;
+-      } sh_pi_xn2pi_request_vc_config_s;
+-} sh_pi_xn2pi_request_vc_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PI_AEC_STATUS"                      */
+ /*                 PI Adaptive Error Correction Status                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_aec_status_u {
+       mmr_t   sh_pi_aec_status_regval;
+       struct {
+@@ -6720,22 +3648,12 @@
+               mmr_t   reserved_0  : 61;
+       } sh_pi_aec_status_s;
+ } sh_pi_aec_status_u_t;
+-#else
+-typedef union sh_pi_aec_status_u {
+-      mmr_t   sh_pi_aec_status_regval;
+-      struct {
+-              mmr_t   reserved_0  : 61;
+-              mmr_t   state       : 3;
+-      } sh_pi_aec_status_s;
+-} sh_pi_aec_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_AFI_FIRST_ERROR"                   */
+ /*                          PI AFI First Error                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_afi_first_error_u {
+       mmr_t   sh_pi_afi_first_error_regval;
+       struct {
+@@ -6760,85 +3678,38 @@
+               mmr_t   reserved_2   : 29;
+       } sh_pi_afi_first_error_s;
+ } sh_pi_afi_first_error_u_t;
+-#else
+-typedef union sh_pi_afi_first_error_u {
+-      mmr_t   sh_pi_afi_first_error_regval;
+-      struct {
+-              mmr_t   reserved_2   : 29;
+-              mmr_t   msg_len      : 1;
+-              mmr_t   fsb_tbl_miss : 1;
+-              mmr_t   bad_snoop    : 1;
+-              mmr_t   livelock     : 1;
+-              mmr_t   shub_fsb_ce  : 1;
+-              mmr_t   shub_fsb_uce : 1;
+-              mmr_t   shub_fsb_dqe : 1;
+-              mmr_t   addr_parity  : 1;
+-              mmr_t   req_parity   : 1;
+-              mmr_t   addr_access  : 1;
+-              mmr_t   req_format   : 1;
+-              mmr_t   ioq_overrun  : 1;
+-              mmr_t   rsp_parity   : 1;
+-              mmr_t   hung_bus     : 1;
+-              mmr_t   reserved_1   : 12;
+-              mmr_t   fsb_shub_ce  : 1;
+-              mmr_t   fsb_shub_uce : 1;
+-              mmr_t   reserved_0   : 7;
+-      } sh_pi_afi_first_error_s;
+-} sh_pi_afi_first_error_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                Register "SH_PI_CAM_ADDRESS_READ_DATA"                */
+-/*                    CRB CAM MMR Address Read Data                     */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_cam_address_read_data_u {
+-      mmr_t   sh_pi_cam_address_read_data_regval;
++
++/* ==================================================================== */
++/*                Register "SH_PI_CAM_ADDRESS_READ_DATA"                */
++/*                    CRB CAM MMR Address Read Data                     */
++/* ==================================================================== */
++
++typedef union sh_pi_cam_address_read_data_u {
++      mmr_t   sh_pi_cam_address_read_data_regval;
+       struct {
+               mmr_t   cam_addr     : 48;
+               mmr_t   reserved_0   : 15;
+               mmr_t   cam_addr_val : 1;
+       } sh_pi_cam_address_read_data_s;
+ } sh_pi_cam_address_read_data_u_t;
+-#else
+-typedef union sh_pi_cam_address_read_data_u {
+-      mmr_t   sh_pi_cam_address_read_data_regval;
+-      struct {
+-              mmr_t   cam_addr_val : 1;
+-              mmr_t   reserved_0   : 15;
+-              mmr_t   cam_addr     : 48;
+-      } sh_pi_cam_address_read_data_s;
+-} sh_pi_cam_address_read_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CAM_LPRA_READ_DATA"                  */
+ /*                      CRB CAM MMR LPRA Read Data                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_cam_lpra_read_data_u {
+-      mmr_t   sh_pi_cam_lpra_read_data_regval;
+-      struct {
+-              mmr_t   cam_lpra    : 64;
+-      } sh_pi_cam_lpra_read_data_s;
+-} sh_pi_cam_lpra_read_data_u_t;
+-#else
+ typedef union sh_pi_cam_lpra_read_data_u {
+       mmr_t   sh_pi_cam_lpra_read_data_regval;
+       struct {
+               mmr_t   cam_lpra    : 64;
+       } sh_pi_cam_lpra_read_data_s;
+ } sh_pi_cam_lpra_read_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CAM_STATE_READ_DATA"                 */
+ /*                     CRB CAM MMR State Read Data                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_cam_state_read_data_u {
+       mmr_t   sh_pi_cam_state_read_data_regval;
+       struct {
+@@ -6851,27 +3722,12 @@
+               mmr_t   cam_rd_data_val   : 1;
+       } sh_pi_cam_state_read_data_s;
+ } sh_pi_cam_state_read_data_u_t;
+-#else
+-typedef union sh_pi_cam_state_read_data_u {
+-      mmr_t   sh_pi_cam_state_read_data_regval;
+-      struct {
+-              mmr_t   cam_rd_data_val   : 1;
+-              mmr_t   reserved_1        : 13;
+-              mmr_t   cam_lpra          : 18;
+-              mmr_t   reserved_0        : 26;
+-              mmr_t   cam_state_rd_pend : 1;
+-              mmr_t   cam_to            : 1;
+-              mmr_t   cam_state         : 4;
+-      } sh_pi_cam_state_read_data_s;
+-} sh_pi_cam_state_read_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CORRECTED_DETAIL_1"                  */
+ /*                      PI Corrected Error Detail                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_corrected_detail_1_u {
+       mmr_t   sh_pi_corrected_detail_1_regval;
+       struct {
+@@ -6880,44 +3736,24 @@
+               mmr_t   dep         : 8;
+       } sh_pi_corrected_detail_1_s;
+ } sh_pi_corrected_detail_1_u_t;
+-#else
+-typedef union sh_pi_corrected_detail_1_u {
+-      mmr_t   sh_pi_corrected_detail_1_regval;
+-      struct {
+-              mmr_t   dep         : 8;
+-              mmr_t   syndrome    : 8;
+-              mmr_t   address     : 48;
+-      } sh_pi_corrected_detail_1_s;
+-} sh_pi_corrected_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CORRECTED_DETAIL_2"                  */
+ /*                     PI Corrected Error Detail 2                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_corrected_detail_2_u {
+-      mmr_t   sh_pi_corrected_detail_2_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_pi_corrected_detail_2_s;
+-} sh_pi_corrected_detail_2_u_t;
+-#else
+ typedef union sh_pi_corrected_detail_2_u {
+       mmr_t   sh_pi_corrected_detail_2_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_pi_corrected_detail_2_s;
+ } sh_pi_corrected_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CORRECTED_DETAIL_3"                  */
+ /*                     PI Corrected Error Detail 3                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_corrected_detail_3_u {
+       mmr_t   sh_pi_corrected_detail_3_regval;
+       struct {
+@@ -6926,44 +3762,24 @@
+               mmr_t   dep         : 8;
+       } sh_pi_corrected_detail_3_s;
+ } sh_pi_corrected_detail_3_u_t;
+-#else
+-typedef union sh_pi_corrected_detail_3_u {
+-      mmr_t   sh_pi_corrected_detail_3_regval;
+-      struct {
+-              mmr_t   dep         : 8;
+-              mmr_t   syndrome    : 8;
+-              mmr_t   address     : 48;
+-      } sh_pi_corrected_detail_3_s;
+-} sh_pi_corrected_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_PI_CORRECTED_DETAIL_4"                  */
+ /*                     PI Corrected Error Detail 4                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_corrected_detail_4_u {
+-      mmr_t   sh_pi_corrected_detail_4_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_pi_corrected_detail_4_s;
+-} sh_pi_corrected_detail_4_u_t;
+-#else
+ typedef union sh_pi_corrected_detail_4_u {
+       mmr_t   sh_pi_corrected_detail_4_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_pi_corrected_detail_4_s;
+ } sh_pi_corrected_detail_4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PI_CRBP_FIRST_ERROR"                   */
+ /*                         PI CRBP First Error                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_crbp_first_error_u {
+       mmr_t   sh_pi_crbp_first_error_regval;
+       struct {
+@@ -6991,84 +3807,36 @@
+               mmr_t   reserved_0      : 43;
+       } sh_pi_crbp_first_error_s;
+ } sh_pi_crbp_first_error_u_t;
+-#else
+-typedef union sh_pi_crbp_first_error_u {
+-      mmr_t   sh_pi_crbp_first_error_regval;
+-      struct {
+-              mmr_t   reserved_0      : 43;
+-              mmr_t   xn_rp_crd_oflow : 1;
+-              mmr_t   xn_rq_crd_oflow : 1;
+-              mmr_t   md_rp_crd_oflow : 1;
+-              mmr_t   md_rq_crd_oflow : 1;
+-              mmr_t   gfx_int_1       : 1;
+-              mmr_t   gfx_int_0       : 1;
+-              mmr_t   nack_oflow      : 1;
+-              mmr_t   xn_rp_q_oflow   : 1;
+-              mmr_t   xn_rq_q_oflow   : 1;
+-              mmr_t   md_rp_q_oflow   : 1;
+-              mmr_t   md_rq_q_oflow   : 1;
+-              mmr_t   msg_color_err   : 1;
+-              mmr_t   fsb_shub_ce     : 1;
+-              mmr_t   fsb_shub_uce    : 1;
+-              mmr_t   pio_to_err      : 1;
+-              mmr_t   mem_to_err      : 1;
+-              mmr_t   pio_rp_err      : 1;
+-              mmr_t   mem_rp_err      : 1;
+-              mmr_t   xb_proto_err    : 1;
+-              mmr_t   gfx_rp_err      : 1;
+-              mmr_t   fsb_proto_err   : 1;
+-      } sh_pi_crbp_first_error_s;
+-} sh_pi_crbp_first_error_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_ERROR_DETAIL_1"                    */
+ /*                          PI Error Detail 1                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_error_detail_1_u {
+-      mmr_t   sh_pi_error_detail_1_regval;
+-      struct {
+-              mmr_t   status      : 64;
+-      } sh_pi_error_detail_1_s;
+-} sh_pi_error_detail_1_u_t;
+-#else
+ typedef union sh_pi_error_detail_1_u {
+       mmr_t   sh_pi_error_detail_1_regval;
+       struct {
+               mmr_t   status      : 64;
+       } sh_pi_error_detail_1_s;
+ } sh_pi_error_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_ERROR_DETAIL_2"                    */
+ /*                          PI Error Detail 2                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_detail_2_u {
+       mmr_t   sh_pi_error_detail_2_regval;
+       struct {
+               mmr_t   status      : 64;
+       } sh_pi_error_detail_2_s;
+ } sh_pi_error_detail_2_u_t;
+-#else
+-typedef union sh_pi_error_detail_2_u {
+-      mmr_t   sh_pi_error_detail_2_regval;
+-      struct {
+-              mmr_t   status      : 64;
+-      } sh_pi_error_detail_2_s;
+-} sh_pi_error_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_ERROR_OVERFLOW"                    */
+ /*                          PI Error Overflow                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_overflow_u {
+       mmr_t   sh_pi_error_overflow_regval;
+       struct {
+@@ -7110,56 +3878,12 @@
+               mmr_t   reserved_0      : 29;
+       } sh_pi_error_overflow_s;
+ } sh_pi_error_overflow_u_t;
+-#else
+-typedef union sh_pi_error_overflow_u {
+-      mmr_t   sh_pi_error_overflow_regval;
+-      struct {
+-              mmr_t   reserved_0      : 29;
+-              mmr_t   msg_length      : 1;
+-              mmr_t   fsb_tbl_miss    : 1;
+-              mmr_t   bad_snoop       : 1;
+-              mmr_t   livelock        : 1;
+-              mmr_t   shub_fsb_ce     : 1;
+-              mmr_t   shub_fsb_uce    : 1;
+-              mmr_t   shub_fsb_dqe    : 1;
+-              mmr_t   addr_parity     : 1;
+-              mmr_t   req_parity      : 1;
+-              mmr_t   addr_access     : 1;
+-              mmr_t   req_format      : 1;
+-              mmr_t   ioq_overrun     : 1;
+-              mmr_t   rsp_parity      : 1;
+-              mmr_t   hung_bus        : 1;
+-              mmr_t   xn_rp_crd_oflow : 1;
+-              mmr_t   xn_rq_crd_oflow : 1;
+-              mmr_t   md_rp_crd_oflow : 1;
+-              mmr_t   md_rq_crd_oflow : 1;
+-              mmr_t   gfx_int_1       : 1;
+-              mmr_t   gfx_int_0       : 1;
+-              mmr_t   nack_oflow      : 1;
+-              mmr_t   xn_rp_q_oflow   : 1;
+-              mmr_t   xn_rq_q_oflow   : 1;
+-              mmr_t   md_rp_q_oflow   : 1;
+-              mmr_t   md_rq_q_oflow   : 1;
+-              mmr_t   msg_color_err   : 1;
+-              mmr_t   fsb_shub_ce     : 1;
+-              mmr_t   fsb_shub_uce    : 1;
+-              mmr_t   pio_to_err      : 1;
+-              mmr_t   mem_to_err      : 1;
+-              mmr_t   pio_rp_err      : 1;
+-              mmr_t   mem_rp_err      : 1;
+-              mmr_t   xb_proto_err    : 1;
+-              mmr_t   gfx_rp_err      : 1;
+-              mmr_t   fsb_proto_err   : 1;
+-      } sh_pi_error_overflow_s;
+-} sh_pi_error_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_PI_ERROR_SUMMARY"                    */
+ /*                           PI Error Summary                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_error_summary_u {
+       mmr_t   sh_pi_error_summary_regval;
+       struct {
+@@ -7201,56 +3925,12 @@
+               mmr_t   reserved_0      : 29;
+       } sh_pi_error_summary_s;
+ } sh_pi_error_summary_u_t;
+-#else
+-typedef union sh_pi_error_summary_u {
+-      mmr_t   sh_pi_error_summary_regval;
+-      struct {
+-              mmr_t   reserved_0      : 29;
+-              mmr_t   msg_length      : 1;
+-              mmr_t   fsb_tbl_miss    : 1;
+-              mmr_t   bad_snoop       : 1;
+-              mmr_t   livelock        : 1;
+-              mmr_t   shub_fsb_ce     : 1;
+-              mmr_t   shub_fsb_uce    : 1;
+-              mmr_t   shub_fsb_dqe    : 1;
+-              mmr_t   addr_parity     : 1;
+-              mmr_t   req_parity      : 1;
+-              mmr_t   addr_access     : 1;
+-              mmr_t   req_format      : 1;
+-              mmr_t   ioq_overrun     : 1;
+-              mmr_t   rsp_parity      : 1;
+-              mmr_t   hung_bus        : 1;
+-              mmr_t   xn_rp_crd_oflow : 1;
+-              mmr_t   xn_rq_crd_oflow : 1;
+-              mmr_t   md_rp_crd_oflow : 1;
+-              mmr_t   md_rq_crd_oflow : 1;
+-              mmr_t   gfx_int_1       : 1;
+-              mmr_t   gfx_int_0       : 1;
+-              mmr_t   nack_oflow      : 1;
+-              mmr_t   xn_rp_q_oflow   : 1;
+-              mmr_t   xn_rq_q_oflow   : 1;
+-              mmr_t   md_rp_q_oflow   : 1;
+-              mmr_t   md_rq_q_oflow   : 1;
+-              mmr_t   msg_color_err   : 1;
+-              mmr_t   fsb_shub_ce     : 1;
+-              mmr_t   fsb_shub_uce    : 1;
+-              mmr_t   pio_to_err      : 1;
+-              mmr_t   mem_to_err      : 1;
+-              mmr_t   pio_rp_err      : 1;
+-              mmr_t   mem_rp_err      : 1;
+-              mmr_t   xb_proto_err    : 1;
+-              mmr_t   gfx_rp_err      : 1;
+-              mmr_t   fsb_proto_err   : 1;
+-      } sh_pi_error_summary_s;
+-} sh_pi_error_summary_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_EXPRESS_REPLY_STATUS"                 */
+ /*                       PI Express Reply Status                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_express_reply_status_u {
+       mmr_t   sh_pi_express_reply_status_regval;
+       struct {
+@@ -7258,22 +3938,12 @@
+               mmr_t   reserved_0  : 61;
+       } sh_pi_express_reply_status_s;
+ } sh_pi_express_reply_status_u_t;
+-#else
+-typedef union sh_pi_express_reply_status_u {
+-      mmr_t   sh_pi_express_reply_status_regval;
+-      struct {
+-              mmr_t   reserved_0  : 61;
+-              mmr_t   state       : 3;
+-      } sh_pi_express_reply_status_s;
+-} sh_pi_express_reply_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PI_FIRST_ERROR"                     */
+ /*                            PI First Error                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_first_error_u {
+       mmr_t   sh_pi_first_error_regval;
+       struct {
+@@ -7315,56 +3985,12 @@
+               mmr_t   reserved_0      : 29;
+       } sh_pi_first_error_s;
+ } sh_pi_first_error_u_t;
+-#else
+-typedef union sh_pi_first_error_u {
+-      mmr_t   sh_pi_first_error_regval;
+-      struct {
+-              mmr_t   reserved_0      : 29;
+-              mmr_t   msg_length      : 1;
+-              mmr_t   fsb_tbl_miss    : 1;
+-              mmr_t   bad_snoop       : 1;
+-              mmr_t   livelock        : 1;
+-              mmr_t   shub_fsb_ce     : 1;
+-              mmr_t   shub_fsb_uce    : 1;
+-              mmr_t   shub_fsb_dqe    : 1;
+-              mmr_t   addr_parity     : 1;
+-              mmr_t   req_parity      : 1;
+-              mmr_t   addr_access     : 1;
+-              mmr_t   req_format      : 1;
+-              mmr_t   ioq_overrun     : 1;
+-              mmr_t   rsp_parity      : 1;
+-              mmr_t   hung_bus        : 1;
+-              mmr_t   xn_rp_crd_oflow : 1;
+-              mmr_t   xn_rq_crd_oflow : 1;
+-              mmr_t   md_rp_crd_oflow : 1;
+-              mmr_t   md_rq_crd_oflow : 1;
+-              mmr_t   gfx_int_1       : 1;
+-              mmr_t   gfx_int_0       : 1;
+-              mmr_t   nack_oflow      : 1;
+-              mmr_t   xn_rp_q_oflow   : 1;
+-              mmr_t   xn_rq_q_oflow   : 1;
+-              mmr_t   md_rp_q_oflow   : 1;
+-              mmr_t   md_rq_q_oflow   : 1;
+-              mmr_t   msg_color_err   : 1;
+-              mmr_t   fsb_shub_ce     : 1;
+-              mmr_t   fsb_shub_uce    : 1;
+-              mmr_t   pio_to_err      : 1;
+-              mmr_t   mem_to_err      : 1;
+-              mmr_t   pio_rp_err      : 1;
+-              mmr_t   mem_rp_err      : 1;
+-              mmr_t   xb_proto_err    : 1;
+-              mmr_t   gfx_rp_err      : 1;
+-              mmr_t   fsb_proto_err   : 1;
+-      } sh_pi_first_error_s;
+-} sh_pi_first_error_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_PI2MD_REPLY_VC_STATUS"                */
+ /*                PI-to-MD Reply Virtual Channel Status                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2md_reply_vc_status_u {
+       mmr_t   sh_pi_pi2md_reply_vc_status_regval;
+       struct {
+@@ -7372,22 +3998,12 @@
+               mmr_t   reserved_0      : 58;
+       } sh_pi_pi2md_reply_vc_status_s;
+ } sh_pi_pi2md_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2md_reply_vc_status_u {
+-      mmr_t   sh_pi_pi2md_reply_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0      : 58;
+-              mmr_t   output_crd_stat : 6;
+-      } sh_pi_pi2md_reply_vc_status_s;
+-} sh_pi_pi2md_reply_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_PI2MD_REQUEST_VC_STATUS"               */
+ /*               PI-to-MD Request Virtual Channel Status                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2md_request_vc_status_u {
+       mmr_t   sh_pi_pi2md_request_vc_status_regval;
+       struct {
+@@ -7395,22 +4011,12 @@
+               mmr_t   reserved_0      : 58;
+       } sh_pi_pi2md_request_vc_status_s;
+ } sh_pi_pi2md_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2md_request_vc_status_u {
+-      mmr_t   sh_pi_pi2md_request_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0      : 58;
+-              mmr_t   output_crd_stat : 6;
+-      } sh_pi_pi2md_request_vc_status_s;
+-} sh_pi_pi2md_request_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_PI2XN_REPLY_VC_STATUS"                */
+ /*                PI-to-XN Reply Virtual Channel Status                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2xn_reply_vc_status_u {
+       mmr_t   sh_pi_pi2xn_reply_vc_status_regval;
+       struct {
+@@ -7418,22 +4024,12 @@
+               mmr_t   reserved_0      : 58;
+       } sh_pi_pi2xn_reply_vc_status_s;
+ } sh_pi_pi2xn_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2xn_reply_vc_status_u {
+-      mmr_t   sh_pi_pi2xn_reply_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0      : 58;
+-              mmr_t   output_crd_stat : 6;
+-      } sh_pi_pi2xn_reply_vc_status_s;
+-} sh_pi_pi2xn_reply_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_PI2XN_REQUEST_VC_STATUS"               */
+ /*               PI-to-XN Request Virtual Channel Status                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_pi2xn_request_vc_status_u {
+       mmr_t   sh_pi_pi2xn_request_vc_status_regval;
+       struct {
+@@ -7441,22 +4037,12 @@
+               mmr_t   reserved_0      : 58;
+       } sh_pi_pi2xn_request_vc_status_s;
+ } sh_pi_pi2xn_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_pi2xn_request_vc_status_u {
+-      mmr_t   sh_pi_pi2xn_request_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0      : 58;
+-              mmr_t   output_crd_stat : 6;
+-      } sh_pi_pi2xn_request_vc_status_s;
+-} sh_pi_pi2xn_request_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_UNCORRECTED_DETAIL_1"                 */
+ /*                    PI Uncorrected Error Detail 1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_uncorrected_detail_1_u {
+       mmr_t   sh_pi_uncorrected_detail_1_regval;
+       struct {
+@@ -7465,44 +4051,24 @@
+               mmr_t   dep         : 8;
+       } sh_pi_uncorrected_detail_1_s;
+ } sh_pi_uncorrected_detail_1_u_t;
+-#else
+-typedef union sh_pi_uncorrected_detail_1_u {
+-      mmr_t   sh_pi_uncorrected_detail_1_regval;
+-      struct {
+-              mmr_t   dep         : 8;
+-              mmr_t   syndrome    : 8;
+-              mmr_t   address     : 48;
+-      } sh_pi_uncorrected_detail_1_s;
+-} sh_pi_uncorrected_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_UNCORRECTED_DETAIL_2"                 */
+ /*                    PI Uncorrected Error Detail 2                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_uncorrected_detail_2_u {
+-      mmr_t   sh_pi_uncorrected_detail_2_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_pi_uncorrected_detail_2_s;
+-} sh_pi_uncorrected_detail_2_u_t;
+-#else
+ typedef union sh_pi_uncorrected_detail_2_u {
+       mmr_t   sh_pi_uncorrected_detail_2_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_pi_uncorrected_detail_2_s;
+ } sh_pi_uncorrected_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_UNCORRECTED_DETAIL_3"                 */
+ /*                    PI Uncorrected Error Detail 3                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_uncorrected_detail_3_u {
+       mmr_t   sh_pi_uncorrected_detail_3_regval;
+       struct {
+@@ -7511,44 +4077,24 @@
+               mmr_t   dep         : 8;
+       } sh_pi_uncorrected_detail_3_s;
+ } sh_pi_uncorrected_detail_3_u_t;
+-#else
+-typedef union sh_pi_uncorrected_detail_3_u {
+-      mmr_t   sh_pi_uncorrected_detail_3_regval;
+-      struct {
+-              mmr_t   dep         : 8;
+-              mmr_t   syndrome    : 8;
+-              mmr_t   address     : 48;
+-      } sh_pi_uncorrected_detail_3_s;
+-} sh_pi_uncorrected_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_UNCORRECTED_DETAIL_4"                 */
+ /*                    PI Uncorrected Error Detail 4                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_pi_uncorrected_detail_4_u {
+-      mmr_t   sh_pi_uncorrected_detail_4_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_pi_uncorrected_detail_4_s;
+-} sh_pi_uncorrected_detail_4_u_t;
+-#else
+ typedef union sh_pi_uncorrected_detail_4_u {
+       mmr_t   sh_pi_uncorrected_detail_4_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_pi_uncorrected_detail_4_s;
+ } sh_pi_uncorrected_detail_4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_MD2PI_REPLY_VC_STATUS"                */
+ /*                MD-to-PI Reply Virtual Channel Status                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_reply_vc_status_u {
+       mmr_t   sh_pi_md2pi_reply_vc_status_regval;
+       struct {
+@@ -7558,24 +4104,12 @@
+               mmr_t   reserved_0         : 52;
+       } sh_pi_md2pi_reply_vc_status_s;
+ } sh_pi_md2pi_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_md2pi_reply_vc_status_u {
+-      mmr_t   sh_pi_md2pi_reply_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0         : 52;
+-              mmr_t   input_queue_stat   : 4;
+-              mmr_t   input_dat_crd_stat : 4;
+-              mmr_t   input_hdr_crd_stat : 4;
+-      } sh_pi_md2pi_reply_vc_status_s;
+-} sh_pi_md2pi_reply_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_MD2PI_REQUEST_VC_STATUS"               */
+ /*               MD-to-PI Request Virtual Channel Status                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md2pi_request_vc_status_u {
+       mmr_t   sh_pi_md2pi_request_vc_status_regval;
+       struct {
+@@ -7585,24 +4119,12 @@
+               mmr_t   reserved_0         : 52;
+       } sh_pi_md2pi_request_vc_status_s;
+ } sh_pi_md2pi_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_md2pi_request_vc_status_u {
+-      mmr_t   sh_pi_md2pi_request_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0         : 52;
+-              mmr_t   input_queue_stat   : 4;
+-              mmr_t   input_dat_crd_stat : 4;
+-              mmr_t   input_hdr_crd_stat : 4;
+-      } sh_pi_md2pi_request_vc_status_s;
+-} sh_pi_md2pi_request_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_PI_XN2PI_REPLY_VC_STATUS"                */
+ /*                XN-to-PI Reply Virtual Channel Status                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_reply_vc_status_u {
+       mmr_t   sh_pi_xn2pi_reply_vc_status_regval;
+       struct {
+@@ -7612,24 +4134,12 @@
+               mmr_t   reserved_0         : 52;
+       } sh_pi_xn2pi_reply_vc_status_s;
+ } sh_pi_xn2pi_reply_vc_status_u_t;
+-#else
+-typedef union sh_pi_xn2pi_reply_vc_status_u {
+-      mmr_t   sh_pi_xn2pi_reply_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0         : 52;
+-              mmr_t   input_queue_stat   : 4;
+-              mmr_t   input_dat_crd_stat : 4;
+-              mmr_t   input_hdr_crd_stat : 4;
+-      } sh_pi_xn2pi_reply_vc_status_s;
+-} sh_pi_xn2pi_reply_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PI_XN2PI_REQUEST_VC_STATUS"               */
+ /*               XN-to-PI Request Virtual Channel Status                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_xn2pi_request_vc_status_u {
+       mmr_t   sh_pi_xn2pi_request_vc_status_regval;
+       struct {
+@@ -7639,23 +4149,11 @@
+               mmr_t   reserved_0         : 52;
+       } sh_pi_xn2pi_request_vc_status_s;
+ } sh_pi_xn2pi_request_vc_status_u_t;
+-#else
+-typedef union sh_pi_xn2pi_request_vc_status_u {
+-      mmr_t   sh_pi_xn2pi_request_vc_status_regval;
+-      struct {
+-              mmr_t   reserved_0         : 52;
+-              mmr_t   input_queue_stat   : 4;
+-              mmr_t   input_dat_crd_stat : 4;
+-              mmr_t   input_hdr_crd_stat : 4;
+-      } sh_pi_xn2pi_request_vc_status_s;
+-} sh_pi_xn2pi_request_vc_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_XNPI_SIC_FLOW"                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_sic_flow_u {
+       mmr_t   sh_xnpi_sic_flow_regval;
+       struct {
+@@ -7680,38 +4178,11 @@
+               mmr_t   disable_bypass_out   : 1;
+       } sh_xnpi_sic_flow_s;
+ } sh_xnpi_sic_flow_u_t;
+-#else
+-typedef union sh_xnpi_sic_flow_u {
+-      mmr_t   sh_xnpi_sic_flow_regval;
+-      struct {
+-              mmr_t   disable_bypass_out   : 1;
+-              mmr_t   reserved_7           : 2;
+-              mmr_t   credit_vc2_cap       : 5;
+-              mmr_t   reserved_6           : 3;
+-              mmr_t   credit_vc2_dyn       : 5;
+-              mmr_t   reserved_5           : 3;
+-              mmr_t   credit_vc2_test      : 5;
+-              mmr_t   reserved_4           : 3;
+-              mmr_t   credit_vc0_cap       : 5;
+-              mmr_t   reserved_3           : 3;
+-              mmr_t   credit_vc0_dyn       : 5;
+-              mmr_t   reserved_2           : 3;
+-              mmr_t   credit_vc0_test      : 5;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 2;
+-              mmr_t   debit_vc2_withhold   : 5;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 2;
+-              mmr_t   debit_vc0_withhold   : 5;
+-      } sh_xnpi_sic_flow_s;
+-} sh_xnpi_sic_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNPI_TO_NI0_PORT_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_to_ni0_port_flow_u {
+       mmr_t   sh_xnpi_to_ni0_port_flow_regval;
+       struct {
+@@ -7732,34 +4203,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnpi_to_ni0_port_flow_s;
+ } sh_xnpi_to_ni0_port_flow_u_t;
+-#else
+-typedef union sh_xnpi_to_ni0_port_flow_u {
+-      mmr_t   sh_xnpi_to_ni0_port_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnpi_to_ni0_port_flow_s;
+-} sh_xnpi_to_ni0_port_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNPI_TO_NI1_PORT_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_to_ni1_port_flow_u {
+       mmr_t   sh_xnpi_to_ni1_port_flow_regval;
+       struct {
+@@ -7780,34 +4228,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnpi_to_ni1_port_flow_s;
+ } sh_xnpi_to_ni1_port_flow_u_t;
+-#else
+-typedef union sh_xnpi_to_ni1_port_flow_u {
+-      mmr_t   sh_xnpi_to_ni1_port_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnpi_to_ni1_port_flow_s;
+-} sh_xnpi_to_ni1_port_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNPI_TO_IILB_PORT_FLOW"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_to_iilb_port_flow_u {
+       mmr_t   sh_xnpi_to_iilb_port_flow_regval;
+       struct {
+@@ -7828,34 +4253,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnpi_to_iilb_port_flow_s;
+ } sh_xnpi_to_iilb_port_flow_u_t;
+-#else
+-typedef union sh_xnpi_to_iilb_port_flow_u {
+-      mmr_t   sh_xnpi_to_iilb_port_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnpi_to_iilb_port_flow_s;
+-} sh_xnpi_to_iilb_port_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XNPI_FR_NI0_PORT_FLOW_FIFO"               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_fr_ni0_port_flow_fifo_u {
+       mmr_t   sh_xnpi_fr_ni0_port_flow_fifo_regval;
+       struct {
+@@ -7873,31 +4275,11 @@
+               mmr_t   reserved_5     : 19;
+       } sh_xnpi_fr_ni0_port_flow_fifo_s;
+ } sh_xnpi_fr_ni0_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnpi_fr_ni0_port_flow_fifo_u {
+-      mmr_t   sh_xnpi_fr_ni0_port_flow_fifo_regval;
+-      struct {
+-              mmr_t   reserved_5     : 19;
+-              mmr_t   entry_vc2_test : 5;
+-              mmr_t   reserved_4     : 3;
+-              mmr_t   entry_vc0_test : 5;
+-              mmr_t   reserved_3     : 2;
+-              mmr_t   entry_vc2_cap  : 6;
+-              mmr_t   reserved_2     : 2;
+-              mmr_t   entry_vc2_dyn  : 6;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   entry_vc0_cap  : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   entry_vc0_dyn  : 6;
+-      } sh_xnpi_fr_ni0_port_flow_fifo_s;
+-} sh_xnpi_fr_ni0_port_flow_fifo_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XNPI_FR_NI1_PORT_FLOW_FIFO"               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_fr_ni1_port_flow_fifo_u {
+       mmr_t   sh_xnpi_fr_ni1_port_flow_fifo_regval;
+       struct {
+@@ -7915,31 +4297,11 @@
+               mmr_t   reserved_5     : 19;
+       } sh_xnpi_fr_ni1_port_flow_fifo_s;
+ } sh_xnpi_fr_ni1_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnpi_fr_ni1_port_flow_fifo_u {
+-      mmr_t   sh_xnpi_fr_ni1_port_flow_fifo_regval;
+-      struct {
+-              mmr_t   reserved_5     : 19;
+-              mmr_t   entry_vc2_test : 5;
+-              mmr_t   reserved_4     : 3;
+-              mmr_t   entry_vc0_test : 5;
+-              mmr_t   reserved_3     : 2;
+-              mmr_t   entry_vc2_cap  : 6;
+-              mmr_t   reserved_2     : 2;
+-              mmr_t   entry_vc2_dyn  : 6;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   entry_vc0_cap  : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   entry_vc0_dyn  : 6;
+-      } sh_xnpi_fr_ni1_port_flow_fifo_s;
+-} sh_xnpi_fr_ni1_port_flow_fifo_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_XNPI_FR_IILB_PORT_FLOW_FIFO"               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_fr_iilb_port_flow_fifo_u {
+       mmr_t   sh_xnpi_fr_iilb_port_flow_fifo_regval;
+       struct {
+@@ -7957,31 +4319,11 @@
+               mmr_t   reserved_5     : 19;
+       } sh_xnpi_fr_iilb_port_flow_fifo_s;
+ } sh_xnpi_fr_iilb_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnpi_fr_iilb_port_flow_fifo_u {
+-      mmr_t   sh_xnpi_fr_iilb_port_flow_fifo_regval;
+-      struct {
+-              mmr_t   reserved_5     : 19;
+-              mmr_t   entry_vc2_test : 5;
+-              mmr_t   reserved_4     : 3;
+-              mmr_t   entry_vc0_test : 5;
+-              mmr_t   reserved_3     : 2;
+-              mmr_t   entry_vc2_cap  : 6;
+-              mmr_t   reserved_2     : 2;
+-              mmr_t   entry_vc2_dyn  : 6;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   entry_vc0_cap  : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   entry_vc0_dyn  : 6;
+-      } sh_xnpi_fr_iilb_port_flow_fifo_s;
+-} sh_xnpi_fr_iilb_port_flow_fifo_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_XNMD_SIC_FLOW"                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_sic_flow_u {
+       mmr_t   sh_xnmd_sic_flow_regval;
+       struct {
+@@ -8006,38 +4348,11 @@
+               mmr_t   disable_bypass_out   : 1;
+       } sh_xnmd_sic_flow_s;
+ } sh_xnmd_sic_flow_u_t;
+-#else
+-typedef union sh_xnmd_sic_flow_u {
+-      mmr_t   sh_xnmd_sic_flow_regval;
+-      struct {
+-              mmr_t   disable_bypass_out   : 1;
+-              mmr_t   reserved_7           : 2;
+-              mmr_t   credit_vc2_cap       : 5;
+-              mmr_t   reserved_6           : 3;
+-              mmr_t   credit_vc2_dyn       : 5;
+-              mmr_t   reserved_5           : 3;
+-              mmr_t   credit_vc2_test      : 5;
+-              mmr_t   reserved_4           : 3;
+-              mmr_t   credit_vc0_cap       : 5;
+-              mmr_t   reserved_3           : 3;
+-              mmr_t   credit_vc0_dyn       : 5;
+-              mmr_t   reserved_2           : 3;
+-              mmr_t   credit_vc0_test      : 5;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 2;
+-              mmr_t   debit_vc2_withhold   : 5;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 2;
+-              mmr_t   debit_vc0_withhold   : 5;
+-      } sh_xnmd_sic_flow_s;
+-} sh_xnmd_sic_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNMD_TO_NI0_PORT_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_to_ni0_port_flow_u {
+       mmr_t   sh_xnmd_to_ni0_port_flow_regval;
+       struct {
+@@ -8058,34 +4373,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnmd_to_ni0_port_flow_s;
+ } sh_xnmd_to_ni0_port_flow_u_t;
+-#else
+-typedef union sh_xnmd_to_ni0_port_flow_u {
+-      mmr_t   sh_xnmd_to_ni0_port_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnmd_to_ni0_port_flow_s;
+-} sh_xnmd_to_ni0_port_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNMD_TO_NI1_PORT_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_to_ni1_port_flow_u {
+       mmr_t   sh_xnmd_to_ni1_port_flow_regval;
+       struct {
+@@ -8106,34 +4398,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnmd_to_ni1_port_flow_s;
+ } sh_xnmd_to_ni1_port_flow_u_t;
+-#else
+-typedef union sh_xnmd_to_ni1_port_flow_u {
+-      mmr_t   sh_xnmd_to_ni1_port_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnmd_to_ni1_port_flow_s;
+-} sh_xnmd_to_ni1_port_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNMD_TO_IILB_PORT_FLOW"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_to_iilb_port_flow_u {
+       mmr_t   sh_xnmd_to_iilb_port_flow_regval;
+       struct {
+@@ -8154,34 +4423,11 @@
+               mmr_t   reserved_6           : 2;
+       } sh_xnmd_to_iilb_port_flow_s;
+ } sh_xnmd_to_iilb_port_flow_u_t;
+-#else
+-typedef union sh_xnmd_to_iilb_port_flow_u {
+-      mmr_t   sh_xnmd_to_iilb_port_flow_regval;
+-      struct {
+-              mmr_t   reserved_6           : 2;
+-              mmr_t   credit_vc2_cap       : 6;
+-              mmr_t   reserved_5           : 2;
+-              mmr_t   credit_vc2_dyn       : 6;
+-              mmr_t   reserved_4           : 10;
+-              mmr_t   credit_vc0_cap       : 6;
+-              mmr_t   reserved_3           : 2;
+-              mmr_t   credit_vc0_dyn       : 6;
+-              mmr_t   reserved_2           : 8;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnmd_to_iilb_port_flow_s;
+-} sh_xnmd_to_iilb_port_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XNMD_FR_NI0_PORT_FLOW_FIFO"               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_fr_ni0_port_flow_fifo_u {
+       mmr_t   sh_xnmd_fr_ni0_port_flow_fifo_regval;
+       struct {
+@@ -8199,31 +4445,11 @@
+               mmr_t   reserved_5     : 19;
+       } sh_xnmd_fr_ni0_port_flow_fifo_s;
+ } sh_xnmd_fr_ni0_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnmd_fr_ni0_port_flow_fifo_u {
+-      mmr_t   sh_xnmd_fr_ni0_port_flow_fifo_regval;
+-      struct {
+-              mmr_t   reserved_5     : 19;
+-              mmr_t   entry_vc2_test : 5;
+-              mmr_t   reserved_4     : 3;
+-              mmr_t   entry_vc0_test : 5;
+-              mmr_t   reserved_3     : 2;
+-              mmr_t   entry_vc2_cap  : 6;
+-              mmr_t   reserved_2     : 2;
+-              mmr_t   entry_vc2_dyn  : 6;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   entry_vc0_cap  : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   entry_vc0_dyn  : 6;
+-      } sh_xnmd_fr_ni0_port_flow_fifo_s;
+-} sh_xnmd_fr_ni0_port_flow_fifo_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XNMD_FR_NI1_PORT_FLOW_FIFO"               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_fr_ni1_port_flow_fifo_u {
+       mmr_t   sh_xnmd_fr_ni1_port_flow_fifo_regval;
+       struct {
+@@ -8241,31 +4467,11 @@
+               mmr_t   reserved_5     : 19;
+       } sh_xnmd_fr_ni1_port_flow_fifo_s;
+ } sh_xnmd_fr_ni1_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnmd_fr_ni1_port_flow_fifo_u {
+-      mmr_t   sh_xnmd_fr_ni1_port_flow_fifo_regval;
+-      struct {
+-              mmr_t   reserved_5     : 19;
+-              mmr_t   entry_vc2_test : 5;
+-              mmr_t   reserved_4     : 3;
+-              mmr_t   entry_vc0_test : 5;
+-              mmr_t   reserved_3     : 2;
+-              mmr_t   entry_vc2_cap  : 6;
+-              mmr_t   reserved_2     : 2;
+-              mmr_t   entry_vc2_dyn  : 6;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   entry_vc0_cap  : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   entry_vc0_dyn  : 6;
+-      } sh_xnmd_fr_ni1_port_flow_fifo_s;
+-} sh_xnmd_fr_ni1_port_flow_fifo_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_XNMD_FR_IILB_PORT_FLOW_FIFO"               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_fr_iilb_port_flow_fifo_u {
+       mmr_t   sh_xnmd_fr_iilb_port_flow_fifo_regval;
+       struct {
+@@ -8283,31 +4489,11 @@
+               mmr_t   reserved_5     : 19;
+       } sh_xnmd_fr_iilb_port_flow_fifo_s;
+ } sh_xnmd_fr_iilb_port_flow_fifo_u_t;
+-#else
+-typedef union sh_xnmd_fr_iilb_port_flow_fifo_u {
+-      mmr_t   sh_xnmd_fr_iilb_port_flow_fifo_regval;
+-      struct {
+-              mmr_t   reserved_5     : 19;
+-              mmr_t   entry_vc2_test : 5;
+-              mmr_t   reserved_4     : 3;
+-              mmr_t   entry_vc0_test : 5;
+-              mmr_t   reserved_3     : 2;
+-              mmr_t   entry_vc2_cap  : 6;
+-              mmr_t   reserved_2     : 2;
+-              mmr_t   entry_vc2_dyn  : 6;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   entry_vc0_cap  : 6;
+-              mmr_t   reserved_0     : 2;
+-              mmr_t   entry_vc0_dyn  : 6;
+-      } sh_xnmd_fr_iilb_port_flow_fifo_s;
+-} sh_xnmd_fr_iilb_port_flow_fifo_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNII_INTRA_FLOW"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnii_intra_flow_u {
+       mmr_t   sh_xnii_intra_flow_regval;
+       struct {
+@@ -8331,37 +4517,11 @@
+               mmr_t   reserved_7           : 1;
+       } sh_xnii_intra_flow_s;
+ } sh_xnii_intra_flow_u_t;
+-#else
+-typedef union sh_xnii_intra_flow_u {
+-      mmr_t   sh_xnii_intra_flow_regval;
+-      struct {
+-              mmr_t   reserved_7           : 1;
+-              mmr_t   credit_vc2_cap       : 7;
+-              mmr_t   reserved_6           : 1;
+-              mmr_t   credit_vc2_dyn       : 7;
+-              mmr_t   reserved_5           : 1;
+-              mmr_t   credit_vc2_test      : 7;
+-              mmr_t   reserved_4           : 1;
+-              mmr_t   credit_vc0_cap       : 7;
+-              mmr_t   reserved_3           : 1;
+-              mmr_t   credit_vc0_dyn       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc0_test      : 7;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnii_intra_flow_s;
+-} sh_xnii_intra_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNLB_INTRA_FLOW"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnlb_intra_flow_u {
+       mmr_t   sh_xnlb_intra_flow_regval;
+       struct {
+@@ -8385,37 +4545,11 @@
+               mmr_t   disable_bypass_in    : 1;
+       } sh_xnlb_intra_flow_s;
+ } sh_xnlb_intra_flow_u_t;
+-#else
+-typedef union sh_xnlb_intra_flow_u {
+-      mmr_t   sh_xnlb_intra_flow_regval;
+-      struct {
+-              mmr_t   disable_bypass_in    : 1;
+-              mmr_t   credit_vc2_cap       : 7;
+-              mmr_t   reserved_6           : 1;
+-              mmr_t   credit_vc2_dyn       : 7;
+-              mmr_t   reserved_5           : 1;
+-              mmr_t   credit_vc2_test      : 7;
+-              mmr_t   reserved_4           : 1;
+-              mmr_t   credit_vc0_cap       : 7;
+-              mmr_t   reserved_3           : 1;
+-              mmr_t   credit_vc0_dyn       : 7;
+-              mmr_t   reserved_2           : 1;
+-              mmr_t   credit_vc0_test      : 7;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_1           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnlb_intra_flow_s;
+-} sh_xnlb_intra_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNIILB_TO_NI0_INTRA_FLOW_DEBIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_ni0_intra_flow_debit_u {
+       mmr_t   sh_xniilb_to_ni0_intra_flow_debit_regval;
+       struct {
+@@ -8436,34 +4570,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xniilb_to_ni0_intra_flow_debit_s;
+ } sh_xniilb_to_ni0_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_ni0_intra_flow_debit_u {
+-      mmr_t   sh_xniilb_to_ni0_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xniilb_to_ni0_intra_flow_debit_s;
+-} sh_xniilb_to_ni0_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNIILB_TO_NI1_INTRA_FLOW_DEBIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_ni1_intra_flow_debit_u {
+       mmr_t   sh_xniilb_to_ni1_intra_flow_debit_regval;
+       struct {
+@@ -8484,34 +4595,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xniilb_to_ni1_intra_flow_debit_s;
+ } sh_xniilb_to_ni1_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_ni1_intra_flow_debit_u {
+-      mmr_t   sh_xniilb_to_ni1_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xniilb_to_ni1_intra_flow_debit_s;
+-} sh_xniilb_to_ni1_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNIILB_TO_MD_INTRA_FLOW_DEBIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_md_intra_flow_debit_u {
+       mmr_t   sh_xniilb_to_md_intra_flow_debit_regval;
+       struct {
+@@ -8532,34 +4620,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xniilb_to_md_intra_flow_debit_s;
+ } sh_xniilb_to_md_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_md_intra_flow_debit_u {
+-      mmr_t   sh_xniilb_to_md_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xniilb_to_md_intra_flow_debit_s;
+-} sh_xniilb_to_md_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*            Register "SH_XNIILB_TO_IILB_INTRA_FLOW_DEBIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_iilb_intra_flow_debit_u {
+       mmr_t   sh_xniilb_to_iilb_intra_flow_debit_regval;
+       struct {
+@@ -8580,34 +4645,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xniilb_to_iilb_intra_flow_debit_s;
+ } sh_xniilb_to_iilb_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_iilb_intra_flow_debit_u {
+-      mmr_t   sh_xniilb_to_iilb_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xniilb_to_iilb_intra_flow_debit_s;
+-} sh_xniilb_to_iilb_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNIILB_TO_PI_INTRA_FLOW_DEBIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_to_pi_intra_flow_debit_u {
+       mmr_t   sh_xniilb_to_pi_intra_flow_debit_regval;
+       struct {
+@@ -8628,34 +4670,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xniilb_to_pi_intra_flow_debit_s;
+ } sh_xniilb_to_pi_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xniilb_to_pi_intra_flow_debit_u {
+-      mmr_t   sh_xniilb_to_pi_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xniilb_to_pi_intra_flow_debit_s;
+-} sh_xniilb_to_pi_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*            Register "SH_XNIILB_FR_NI0_INTRA_FLOW_CREDIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_ni0_intra_flow_credit_u {
+       mmr_t   sh_xniilb_fr_ni0_intra_flow_credit_regval;
+       struct {
+@@ -8673,31 +4692,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xniilb_fr_ni0_intra_flow_credit_s;
+ } sh_xniilb_fr_ni0_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_ni0_intra_flow_credit_u {
+-      mmr_t   sh_xniilb_fr_ni0_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xniilb_fr_ni0_intra_flow_credit_s;
+-} sh_xniilb_fr_ni0_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*            Register "SH_XNIILB_FR_NI1_INTRA_FLOW_CREDIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_ni1_intra_flow_credit_u {
+       mmr_t   sh_xniilb_fr_ni1_intra_flow_credit_regval;
+       struct {
+@@ -8715,31 +4714,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xniilb_fr_ni1_intra_flow_credit_s;
+ } sh_xniilb_fr_ni1_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_ni1_intra_flow_credit_u {
+-      mmr_t   sh_xniilb_fr_ni1_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xniilb_fr_ni1_intra_flow_credit_s;
+-} sh_xniilb_fr_ni1_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNIILB_FR_MD_INTRA_FLOW_CREDIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_md_intra_flow_credit_u {
+       mmr_t   sh_xniilb_fr_md_intra_flow_credit_regval;
+       struct {
+@@ -8757,31 +4736,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xniilb_fr_md_intra_flow_credit_s;
+ } sh_xniilb_fr_md_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_md_intra_flow_credit_u {
+-      mmr_t   sh_xniilb_fr_md_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xniilb_fr_md_intra_flow_credit_s;
+-} sh_xniilb_fr_md_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*            Register "SH_XNIILB_FR_IILB_INTRA_FLOW_CREDIT"            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_iilb_intra_flow_credit_u {
+       mmr_t   sh_xniilb_fr_iilb_intra_flow_credit_regval;
+       struct {
+@@ -8799,31 +4758,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xniilb_fr_iilb_intra_flow_credit_s;
+ } sh_xniilb_fr_iilb_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_iilb_intra_flow_credit_u {
+-      mmr_t   sh_xniilb_fr_iilb_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xniilb_fr_iilb_intra_flow_credit_s;
+-} sh_xniilb_fr_iilb_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNIILB_FR_PI_INTRA_FLOW_CREDIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_fr_pi_intra_flow_credit_u {
+       mmr_t   sh_xniilb_fr_pi_intra_flow_credit_regval;
+       struct {
+@@ -8841,31 +4780,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xniilb_fr_pi_intra_flow_credit_s;
+ } sh_xniilb_fr_pi_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xniilb_fr_pi_intra_flow_credit_u {
+-      mmr_t   sh_xniilb_fr_pi_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xniilb_fr_pi_intra_flow_credit_s;
+-} sh_xniilb_fr_pi_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_XNNI0_TO_PI_INTRA_FLOW_DEBIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_to_pi_intra_flow_debit_u {
+       mmr_t   sh_xnni0_to_pi_intra_flow_debit_regval;
+       struct {
+@@ -8886,34 +4805,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xnni0_to_pi_intra_flow_debit_s;
+ } sh_xnni0_to_pi_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni0_to_pi_intra_flow_debit_u {
+-      mmr_t   sh_xnni0_to_pi_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xnni0_to_pi_intra_flow_debit_s;
+-} sh_xnni0_to_pi_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_XNNI0_TO_MD_INTRA_FLOW_DEBIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_to_md_intra_flow_debit_u {
+       mmr_t   sh_xnni0_to_md_intra_flow_debit_regval;
+       struct {
+@@ -8934,34 +4830,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xnni0_to_md_intra_flow_debit_s;
+ } sh_xnni0_to_md_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni0_to_md_intra_flow_debit_u {
+-      mmr_t   sh_xnni0_to_md_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xnni0_to_md_intra_flow_debit_s;
+-} sh_xnni0_to_md_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNNI0_TO_IILB_INTRA_FLOW_DEBIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_to_iilb_intra_flow_debit_u {
+       mmr_t   sh_xnni0_to_iilb_intra_flow_debit_regval;
+       struct {
+@@ -8982,34 +4855,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xnni0_to_iilb_intra_flow_debit_s;
+ } sh_xnni0_to_iilb_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni0_to_iilb_intra_flow_debit_u {
+-      mmr_t   sh_xnni0_to_iilb_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xnni0_to_iilb_intra_flow_debit_s;
+-} sh_xnni0_to_iilb_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNNI0_FR_PI_INTRA_FLOW_CREDIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fr_pi_intra_flow_credit_u {
+       mmr_t   sh_xnni0_fr_pi_intra_flow_credit_regval;
+       struct {
+@@ -9027,31 +4877,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xnni0_fr_pi_intra_flow_credit_s;
+ } sh_xnni0_fr_pi_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni0_fr_pi_intra_flow_credit_u {
+-      mmr_t   sh_xnni0_fr_pi_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xnni0_fr_pi_intra_flow_credit_s;
+-} sh_xnni0_fr_pi_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNNI0_FR_MD_INTRA_FLOW_CREDIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fr_md_intra_flow_credit_u {
+       mmr_t   sh_xnni0_fr_md_intra_flow_credit_regval;
+       struct {
+@@ -9069,31 +4899,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xnni0_fr_md_intra_flow_credit_s;
+ } sh_xnni0_fr_md_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni0_fr_md_intra_flow_credit_u {
+-      mmr_t   sh_xnni0_fr_md_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xnni0_fr_md_intra_flow_credit_s;
+-} sh_xnni0_fr_md_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*            Register "SH_XNNI0_FR_IILB_INTRA_FLOW_CREDIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fr_iilb_intra_flow_credit_u {
+       mmr_t   sh_xnni0_fr_iilb_intra_flow_credit_regval;
+       struct {
+@@ -9111,31 +4921,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xnni0_fr_iilb_intra_flow_credit_s;
+ } sh_xnni0_fr_iilb_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni0_fr_iilb_intra_flow_credit_u {
+-      mmr_t   sh_xnni0_fr_iilb_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xnni0_fr_iilb_intra_flow_credit_s;
+-} sh_xnni0_fr_iilb_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI0_0_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_0_intrani_flow_u {
+       mmr_t   sh_xnni0_0_intrani_flow_regval;
+       struct {
+@@ -9145,23 +4935,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni0_0_intrani_flow_s;
+ } sh_xnni0_0_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_0_intrani_flow_u {
+-      mmr_t   sh_xnni0_0_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni0_0_intrani_flow_s;
+-} sh_xnni0_0_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI0_1_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_1_intrani_flow_u {
+       mmr_t   sh_xnni0_1_intrani_flow_regval;
+       struct {
+@@ -9171,23 +4949,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni0_1_intrani_flow_s;
+ } sh_xnni0_1_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_1_intrani_flow_u {
+-      mmr_t   sh_xnni0_1_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc1_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc1_withhold   : 6;
+-      } sh_xnni0_1_intrani_flow_s;
+-} sh_xnni0_1_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI0_2_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_2_intrani_flow_u {
+       mmr_t   sh_xnni0_2_intrani_flow_regval;
+       struct {
+@@ -9197,23 +4963,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni0_2_intrani_flow_s;
+ } sh_xnni0_2_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_2_intrani_flow_u {
+-      mmr_t   sh_xnni0_2_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-      } sh_xnni0_2_intrani_flow_s;
+-} sh_xnni0_2_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI0_3_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_3_intrani_flow_u {
+       mmr_t   sh_xnni0_3_intrani_flow_regval;
+       struct {
+@@ -9223,23 +4977,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni0_3_intrani_flow_s;
+ } sh_xnni0_3_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni0_3_intrani_flow_u {
+-      mmr_t   sh_xnni0_3_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc3_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc3_withhold   : 6;
+-      } sh_xnni0_3_intrani_flow_s;
+-} sh_xnni0_3_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI0_VCSWITCH_FLOW"                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_vcswitch_flow_u {
+       mmr_t   sh_xnni0_vcswitch_flow_regval;
+       struct {
+@@ -9257,31 +4999,11 @@
+               mmr_t   reserved_4                : 29;
+       } sh_xnni0_vcswitch_flow_s;
+ } sh_xnni0_vcswitch_flow_u_t;
+-#else
+-typedef union sh_xnni0_vcswitch_flow_u {
+-      mmr_t   sh_xnni0_vcswitch_flow_regval;
+-      struct {
+-              mmr_t   reserved_4                : 29;
+-              mmr_t   async_fifoes              : 1;
+-              mmr_t   disable_sync_bypass_out   : 1;
+-              mmr_t   disable_sync_bypass_in    : 1;
+-              mmr_t   reserved_3                : 7;
+-              mmr_t   iilb_vcfifo_switch        : 1;
+-              mmr_t   reserved_2                : 7;
+-              mmr_t   md_vcfifo_switch          : 1;
+-              mmr_t   reserved_1                : 7;
+-              mmr_t   pi_vcfifo_switch          : 1;
+-              mmr_t   reserved_0                : 7;
+-              mmr_t   ni_vcfifo_dateline_switch : 1;
+-      } sh_xnni0_vcswitch_flow_s;
+-} sh_xnni0_vcswitch_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNNI0_TIMER_REG"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_timer_reg_u {
+       mmr_t   sh_xnni0_timer_reg_regval;
+       struct {
+@@ -9291,23 +5013,11 @@
+               mmr_t   reserved_1      : 31;
+       } sh_xnni0_timer_reg_s;
+ } sh_xnni0_timer_reg_u_t;
+-#else
+-typedef union sh_xnni0_timer_reg_u {
+-      mmr_t   sh_xnni0_timer_reg_regval;
+-      struct {
+-              mmr_t   reserved_1      : 31;
+-              mmr_t   linkcleanup_reg : 1;
+-              mmr_t   reserved_0      : 8;
+-              mmr_t   timeout_reg     : 24;
+-      } sh_xnni0_timer_reg_s;
+-} sh_xnni0_timer_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI0_FIFO02_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fifo02_flow_u {
+       mmr_t   sh_xnni0_fifo02_flow_regval;
+       struct {
+@@ -9325,31 +5035,11 @@
+               mmr_t   reserved_5      : 20;
+       } sh_xnni0_fifo02_flow_s;
+ } sh_xnni0_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni0_fifo02_flow_u {
+-      mmr_t   sh_xnni0_fifo02_flow_regval;
+-      struct {
+-              mmr_t   reserved_5      : 20;
+-              mmr_t   count_vc2_cap   : 4;
+-              mmr_t   reserved_4      : 4;
+-              mmr_t   count_vc2_dyn   : 4;
+-              mmr_t   reserved_3      : 4;
+-              mmr_t   count_vc2_limit : 4;
+-              mmr_t   reserved_2      : 4;
+-              mmr_t   count_vc0_cap   : 4;
+-              mmr_t   reserved_1      : 4;
+-              mmr_t   count_vc0_dyn   : 4;
+-              mmr_t   reserved_0      : 4;
+-              mmr_t   count_vc0_limit : 4;
+-      } sh_xnni0_fifo02_flow_s;
+-} sh_xnni0_fifo02_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI0_FIFO13_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_fifo13_flow_u {
+       mmr_t   sh_xnni0_fifo13_flow_regval;
+       struct {
+@@ -9367,31 +5057,11 @@
+               mmr_t   reserved_5      : 20;
+       } sh_xnni0_fifo13_flow_s;
+ } sh_xnni0_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni0_fifo13_flow_u {
+-      mmr_t   sh_xnni0_fifo13_flow_regval;
+-      struct {
+-              mmr_t   reserved_5      : 20;
+-              mmr_t   count_vc3_cap   : 4;
+-              mmr_t   reserved_4      : 4;
+-              mmr_t   count_vc3_dyn   : 4;
+-              mmr_t   reserved_3      : 4;
+-              mmr_t   count_vc3_limit : 4;
+-              mmr_t   reserved_2      : 4;
+-              mmr_t   count_vc1_cap   : 4;
+-              mmr_t   reserved_1      : 4;
+-              mmr_t   count_vc1_dyn   : 4;
+-              mmr_t   reserved_0      : 4;
+-              mmr_t   count_vc1_limit : 4;
+-      } sh_xnni0_fifo13_flow_s;
+-} sh_xnni0_fifo13_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_XNNI0_NI_FLOW"                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_ni_flow_u {
+       mmr_t   sh_xnni0_ni_flow_regval;
+       struct {
+@@ -9413,35 +5083,11 @@
+               mmr_t   vc3_cap     : 4;
+       } sh_xnni0_ni_flow_s;
+ } sh_xnni0_ni_flow_u_t;
+-#else
+-typedef union sh_xnni0_ni_flow_u {
+-      mmr_t   sh_xnni0_ni_flow_regval;
+-      struct {
+-              mmr_t   vc3_cap     : 4;
+-              mmr_t   vc3_dyn     : 4;
+-              mmr_t   reserved_3  : 4;
+-              mmr_t   vc3_limit   : 4;
+-              mmr_t   vc2_cap     : 4;
+-              mmr_t   vc2_dyn     : 4;
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   vc2_limit   : 4;
+-              mmr_t   vc1_cap     : 4;
+-              mmr_t   vc1_dyn     : 4;
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   vc1_limit   : 4;
+-              mmr_t   vc0_cap     : 4;
+-              mmr_t   vc0_dyn     : 4;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   vc0_limit   : 4;
+-      } sh_xnni0_ni_flow_s;
+-} sh_xnni0_ni_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNNI0_DEAD_FLOW"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_dead_flow_u {
+       mmr_t   sh_xnni0_dead_flow_regval;
+       struct {
+@@ -9463,35 +5109,11 @@
+               mmr_t   vc3_cap     : 4;
+       } sh_xnni0_dead_flow_s;
+ } sh_xnni0_dead_flow_u_t;
+-#else
+-typedef union sh_xnni0_dead_flow_u {
+-      mmr_t   sh_xnni0_dead_flow_regval;
+-      struct {
+-              mmr_t   vc3_cap     : 4;
+-              mmr_t   vc3_dyn     : 4;
+-              mmr_t   reserved_3  : 4;
+-              mmr_t   vc3_limit   : 4;
+-              mmr_t   vc2_cap     : 4;
+-              mmr_t   vc2_dyn     : 4;
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   vc2_limit   : 4;
+-              mmr_t   vc1_cap     : 4;
+-              mmr_t   vc1_dyn     : 4;
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   vc1_limit   : 4;
+-              mmr_t   vc0_cap     : 4;
+-              mmr_t   vc0_dyn     : 4;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   vc0_limit   : 4;
+-      } sh_xnni0_dead_flow_s;
+-} sh_xnni0_dead_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNNI0_INJECT_AGE"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni0_inject_age_u {
+       mmr_t   sh_xnni0_inject_age_regval;
+       struct {
+@@ -9500,22 +5122,11 @@
+               mmr_t   reserved_0     : 48;
+       } sh_xnni0_inject_age_s;
+ } sh_xnni0_inject_age_u_t;
+-#else
+-typedef union sh_xnni0_inject_age_u {
+-      mmr_t   sh_xnni0_inject_age_regval;
+-      struct {
+-              mmr_t   reserved_0     : 48;
+-              mmr_t   reply_inject   : 8;
+-              mmr_t   request_inject : 8;
+-      } sh_xnni0_inject_age_s;
+-} sh_xnni0_inject_age_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_XNNI1_TO_PI_INTRA_FLOW_DEBIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_to_pi_intra_flow_debit_u {
+       mmr_t   sh_xnni1_to_pi_intra_flow_debit_regval;
+       struct {
+@@ -9536,34 +5147,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xnni1_to_pi_intra_flow_debit_s;
+ } sh_xnni1_to_pi_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni1_to_pi_intra_flow_debit_u {
+-      mmr_t   sh_xnni1_to_pi_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xnni1_to_pi_intra_flow_debit_s;
+-} sh_xnni1_to_pi_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_XNNI1_TO_MD_INTRA_FLOW_DEBIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_to_md_intra_flow_debit_u {
+       mmr_t   sh_xnni1_to_md_intra_flow_debit_regval;
+       struct {
+@@ -9584,34 +5172,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xnni1_to_md_intra_flow_debit_s;
+ } sh_xnni1_to_md_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni1_to_md_intra_flow_debit_u {
+-      mmr_t   sh_xnni1_to_md_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xnni1_to_md_intra_flow_debit_s;
+-} sh_xnni1_to_md_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNNI1_TO_IILB_INTRA_FLOW_DEBIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_to_iilb_intra_flow_debit_u {
+       mmr_t   sh_xnni1_to_iilb_intra_flow_debit_regval;
+       struct {
+@@ -9632,34 +5197,11 @@
+               mmr_t   reserved_6     : 1;
+       } sh_xnni1_to_iilb_intra_flow_debit_s;
+ } sh_xnni1_to_iilb_intra_flow_debit_u_t;
+-#else
+-typedef union sh_xnni1_to_iilb_intra_flow_debit_u {
+-      mmr_t   sh_xnni1_to_iilb_intra_flow_debit_regval;
+-      struct {
+-              mmr_t   reserved_6     : 1;
+-              mmr_t   vc2_cap        : 7;
+-              mmr_t   reserved_5     : 1;
+-              mmr_t   vc2_dyn        : 7;
+-              mmr_t   reserved_4     : 9;
+-              mmr_t   vc0_cap        : 7;
+-              mmr_t   reserved_3     : 1;
+-              mmr_t   vc0_dyn        : 7;
+-              mmr_t   reserved_2     : 8;
+-              mmr_t   vc2_force_cred : 1;
+-              mmr_t   reserved_1     : 1;
+-              mmr_t   vc2_withhold   : 6;
+-              mmr_t   vc0_force_cred : 1;
+-              mmr_t   reserved_0     : 1;
+-              mmr_t   vc0_withhold   : 6;
+-      } sh_xnni1_to_iilb_intra_flow_debit_s;
+-} sh_xnni1_to_iilb_intra_flow_debit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNNI1_FR_PI_INTRA_FLOW_CREDIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fr_pi_intra_flow_credit_u {
+       mmr_t   sh_xnni1_fr_pi_intra_flow_credit_regval;
+       struct {
+@@ -9677,31 +5219,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xnni1_fr_pi_intra_flow_credit_s;
+ } sh_xnni1_fr_pi_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni1_fr_pi_intra_flow_credit_u {
+-      mmr_t   sh_xnni1_fr_pi_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xnni1_fr_pi_intra_flow_credit_s;
+-} sh_xnni1_fr_pi_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_XNNI1_FR_MD_INTRA_FLOW_CREDIT"              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fr_md_intra_flow_credit_u {
+       mmr_t   sh_xnni1_fr_md_intra_flow_credit_regval;
+       struct {
+@@ -9719,31 +5241,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xnni1_fr_md_intra_flow_credit_s;
+ } sh_xnni1_fr_md_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni1_fr_md_intra_flow_credit_u {
+-      mmr_t   sh_xnni1_fr_md_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xnni1_fr_md_intra_flow_credit_s;
+-} sh_xnni1_fr_md_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*            Register "SH_XNNI1_FR_IILB_INTRA_FLOW_CREDIT"             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fr_iilb_intra_flow_credit_u {
+       mmr_t   sh_xnni1_fr_iilb_intra_flow_credit_regval;
+       struct {
+@@ -9761,31 +5263,11 @@
+               mmr_t   reserved_5  : 17;
+       } sh_xnni1_fr_iilb_intra_flow_credit_s;
+ } sh_xnni1_fr_iilb_intra_flow_credit_u_t;
+-#else
+-typedef union sh_xnni1_fr_iilb_intra_flow_credit_u {
+-      mmr_t   sh_xnni1_fr_iilb_intra_flow_credit_regval;
+-      struct {
+-              mmr_t   reserved_5  : 17;
+-              mmr_t   vc2_cap     : 7;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   vc2_dyn     : 7;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   vc2_test    : 7;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   vc0_cap     : 7;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   vc0_dyn     : 7;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   vc0_test    : 7;
+-      } sh_xnni1_fr_iilb_intra_flow_credit_s;
+-} sh_xnni1_fr_iilb_intra_flow_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI1_0_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_0_intrani_flow_u {
+       mmr_t   sh_xnni1_0_intrani_flow_regval;
+       struct {
+@@ -9795,23 +5277,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni1_0_intrani_flow_s;
+ } sh_xnni1_0_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_0_intrani_flow_u {
+-      mmr_t   sh_xnni1_0_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc0_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc0_withhold   : 6;
+-      } sh_xnni1_0_intrani_flow_s;
+-} sh_xnni1_0_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI1_1_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_1_intrani_flow_u {
+       mmr_t   sh_xnni1_1_intrani_flow_regval;
+       struct {
+@@ -9821,23 +5291,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni1_1_intrani_flow_s;
+ } sh_xnni1_1_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_1_intrani_flow_u {
+-      mmr_t   sh_xnni1_1_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc1_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc1_withhold   : 6;
+-      } sh_xnni1_1_intrani_flow_s;
+-} sh_xnni1_1_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI1_2_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_2_intrani_flow_u {
+       mmr_t   sh_xnni1_2_intrani_flow_regval;
+       struct {
+@@ -9847,23 +5305,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni1_2_intrani_flow_s;
+ } sh_xnni1_2_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_2_intrani_flow_u {
+-      mmr_t   sh_xnni1_2_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc2_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc2_withhold   : 6;
+-      } sh_xnni1_2_intrani_flow_s;
+-} sh_xnni1_2_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI1_3_INTRANI_FLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_3_intrani_flow_u {
+       mmr_t   sh_xnni1_3_intrani_flow_regval;
+       struct {
+@@ -9873,23 +5319,11 @@
+               mmr_t   reserved_1           : 56;
+       } sh_xnni1_3_intrani_flow_s;
+ } sh_xnni1_3_intrani_flow_u_t;
+-#else
+-typedef union sh_xnni1_3_intrani_flow_u {
+-      mmr_t   sh_xnni1_3_intrani_flow_regval;
+-      struct {
+-              mmr_t   reserved_1           : 56;
+-              mmr_t   debit_vc3_force_cred : 1;
+-              mmr_t   reserved_0           : 1;
+-              mmr_t   debit_vc3_withhold   : 6;
+-      } sh_xnni1_3_intrani_flow_s;
+-} sh_xnni1_3_intrani_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNNI1_VCSWITCH_FLOW"                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_vcswitch_flow_u {
+       mmr_t   sh_xnni1_vcswitch_flow_regval;
+       struct {
+@@ -9907,31 +5341,11 @@
+               mmr_t   reserved_4                : 29;
+       } sh_xnni1_vcswitch_flow_s;
+ } sh_xnni1_vcswitch_flow_u_t;
+-#else
+-typedef union sh_xnni1_vcswitch_flow_u {
+-      mmr_t   sh_xnni1_vcswitch_flow_regval;
+-      struct {
+-              mmr_t   reserved_4                : 29;
+-              mmr_t   async_fifoes              : 1;
+-              mmr_t   disable_sync_bypass_out   : 1;
+-              mmr_t   disable_sync_bypass_in    : 1;
+-              mmr_t   reserved_3                : 7;
+-              mmr_t   iilb_vcfifo_switch        : 1;
+-              mmr_t   reserved_2                : 7;
+-              mmr_t   md_vcfifo_switch          : 1;
+-              mmr_t   reserved_1                : 7;
+-              mmr_t   pi_vcfifo_switch          : 1;
+-              mmr_t   reserved_0                : 7;
+-              mmr_t   ni_vcfifo_dateline_switch : 1;
+-      } sh_xnni1_vcswitch_flow_s;
+-} sh_xnni1_vcswitch_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNNI1_TIMER_REG"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_timer_reg_u {
+       mmr_t   sh_xnni1_timer_reg_regval;
+       struct {
+@@ -9941,23 +5355,11 @@
+               mmr_t   reserved_1      : 31;
+       } sh_xnni1_timer_reg_s;
+ } sh_xnni1_timer_reg_u_t;
+-#else
+-typedef union sh_xnni1_timer_reg_u {
+-      mmr_t   sh_xnni1_timer_reg_regval;
+-      struct {
+-              mmr_t   reserved_1      : 31;
+-              mmr_t   linkcleanup_reg : 1;
+-              mmr_t   reserved_0      : 8;
+-              mmr_t   timeout_reg     : 24;
+-      } sh_xnni1_timer_reg_s;
+-} sh_xnni1_timer_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI1_FIFO02_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fifo02_flow_u {
+       mmr_t   sh_xnni1_fifo02_flow_regval;
+       struct {
+@@ -9975,31 +5377,11 @@
+               mmr_t   reserved_5      : 20;
+       } sh_xnni1_fifo02_flow_s;
+ } sh_xnni1_fifo02_flow_u_t;
+-#else
+-typedef union sh_xnni1_fifo02_flow_u {
+-      mmr_t   sh_xnni1_fifo02_flow_regval;
+-      struct {
+-              mmr_t   reserved_5      : 20;
+-              mmr_t   count_vc2_cap   : 4;
+-              mmr_t   reserved_4      : 4;
+-              mmr_t   count_vc2_dyn   : 4;
+-              mmr_t   reserved_3      : 4;
+-              mmr_t   count_vc2_limit : 4;
+-              mmr_t   reserved_2      : 4;
+-              mmr_t   count_vc0_cap   : 4;
+-              mmr_t   reserved_1      : 4;
+-              mmr_t   count_vc0_dyn   : 4;
+-              mmr_t   reserved_0      : 4;
+-              mmr_t   count_vc0_limit : 4;
+-      } sh_xnni1_fifo02_flow_s;
+-} sh_xnni1_fifo02_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNNI1_FIFO13_FLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_fifo13_flow_u {
+       mmr_t   sh_xnni1_fifo13_flow_regval;
+       struct {
+@@ -10017,31 +5399,11 @@
+               mmr_t   reserved_5      : 20;
+       } sh_xnni1_fifo13_flow_s;
+ } sh_xnni1_fifo13_flow_u_t;
+-#else
+-typedef union sh_xnni1_fifo13_flow_u {
+-      mmr_t   sh_xnni1_fifo13_flow_regval;
+-      struct {
+-              mmr_t   reserved_5      : 20;
+-              mmr_t   count_vc3_cap   : 4;
+-              mmr_t   reserved_4      : 4;
+-              mmr_t   count_vc3_dyn   : 4;
+-              mmr_t   reserved_3      : 4;
+-              mmr_t   count_vc3_limit : 4;
+-              mmr_t   reserved_2      : 4;
+-              mmr_t   count_vc1_cap   : 4;
+-              mmr_t   reserved_1      : 4;
+-              mmr_t   count_vc1_dyn   : 4;
+-              mmr_t   reserved_0      : 4;
+-              mmr_t   count_vc1_limit : 4;
+-      } sh_xnni1_fifo13_flow_s;
+-} sh_xnni1_fifo13_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_XNNI1_NI_FLOW"                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_ni_flow_u {
+       mmr_t   sh_xnni1_ni_flow_regval;
+       struct {
+@@ -10063,35 +5425,11 @@
+               mmr_t   vc3_cap     : 4;
+       } sh_xnni1_ni_flow_s;
+ } sh_xnni1_ni_flow_u_t;
+-#else
+-typedef union sh_xnni1_ni_flow_u {
+-      mmr_t   sh_xnni1_ni_flow_regval;
+-      struct {
+-              mmr_t   vc3_cap     : 4;
+-              mmr_t   vc3_dyn     : 4;
+-              mmr_t   reserved_3  : 4;
+-              mmr_t   vc3_limit   : 4;
+-              mmr_t   vc2_cap     : 4;
+-              mmr_t   vc2_dyn     : 4;
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   vc2_limit   : 4;
+-              mmr_t   vc1_cap     : 4;
+-              mmr_t   vc1_dyn     : 4;
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   vc1_limit   : 4;
+-              mmr_t   vc0_cap     : 4;
+-              mmr_t   vc0_dyn     : 4;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   vc0_limit   : 4;
+-      } sh_xnni1_ni_flow_s;
+-} sh_xnni1_ni_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNNI1_DEAD_FLOW"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_dead_flow_u {
+       mmr_t   sh_xnni1_dead_flow_regval;
+       struct {
+@@ -10113,35 +5451,11 @@
+               mmr_t   vc3_cap     : 4;
+       } sh_xnni1_dead_flow_s;
+ } sh_xnni1_dead_flow_u_t;
+-#else
+-typedef union sh_xnni1_dead_flow_u {
+-      mmr_t   sh_xnni1_dead_flow_regval;
+-      struct {
+-              mmr_t   vc3_cap     : 4;
+-              mmr_t   vc3_dyn     : 4;
+-              mmr_t   reserved_3  : 4;
+-              mmr_t   vc3_limit   : 4;
+-              mmr_t   vc2_cap     : 4;
+-              mmr_t   vc2_dyn     : 4;
+-              mmr_t   reserved_2  : 4;
+-              mmr_t   vc2_limit   : 4;
+-              mmr_t   vc1_cap     : 4;
+-              mmr_t   vc1_dyn     : 4;
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   vc1_limit   : 4;
+-              mmr_t   vc0_cap     : 4;
+-              mmr_t   vc0_dyn     : 4;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   vc0_limit   : 4;
+-      } sh_xnni1_dead_flow_s;
+-} sh_xnni1_dead_flow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNNI1_INJECT_AGE"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnni1_inject_age_u {
+       mmr_t   sh_xnni1_inject_age_regval;
+       struct {
+@@ -10150,23 +5464,12 @@
+               mmr_t   reserved_0     : 48;
+       } sh_xnni1_inject_age_s;
+ } sh_xnni1_inject_age_u_t;
+-#else
+-typedef union sh_xnni1_inject_age_u {
+-      mmr_t   sh_xnni1_inject_age_regval;
+-      struct {
+-              mmr_t   reserved_0     : 48;
+-              mmr_t   reply_inject   : 8;
+-              mmr_t   request_inject : 8;
+-      } sh_xnni1_inject_age_s;
+-} sh_xnni1_inject_age_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_XN_DEBUG_SEL"                      */
+ /*                         XN Debug Port Select                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_debug_sel_u {
+       mmr_t   sh_xn_debug_sel_regval;
+       struct {
+@@ -10204,52 +5507,12 @@
+               mmr_t   trigger_enable     : 1;
+       } sh_xn_debug_sel_s;
+ } sh_xn_debug_sel_u_t;
+-#else
+-typedef union sh_xn_debug_sel_u {
+-      mmr_t   sh_xn_debug_sel_regval;
+-      struct {
+-              mmr_t   trigger_enable     : 1;
+-              mmr_t   nibble7_nibble_sel : 3;
+-              mmr_t   reserved_14        : 1;
+-              mmr_t   nibble7_rlm_sel    : 3;
+-              mmr_t   reserved_13        : 1;
+-              mmr_t   nibble6_nibble_sel : 3;
+-              mmr_t   reserved_12        : 1;
+-              mmr_t   nibble6_rlm_sel    : 3;
+-              mmr_t   reserved_11        : 1;
+-              mmr_t   nibble5_nibble_sel : 3;
+-              mmr_t   reserved_10        : 1;
+-              mmr_t   nibble5_rlm_sel    : 3;
+-              mmr_t   reserved_9         : 1;
+-              mmr_t   nibble4_nibble_sel : 3;
+-              mmr_t   reserved_8         : 1;
+-              mmr_t   nibble4_rlm_sel    : 3;
+-              mmr_t   reserved_7         : 1;
+-              mmr_t   nibble3_nibble_sel : 3;
+-              mmr_t   reserved_6         : 1;
+-              mmr_t   nibble3_rlm_sel    : 3;
+-              mmr_t   reserved_5         : 1;
+-              mmr_t   nibble2_nibble_sel : 3;
+-              mmr_t   reserved_4         : 1;
+-              mmr_t   nibble2_rlm_sel    : 3;
+-              mmr_t   reserved_3         : 1;
+-              mmr_t   nibble1_nibble_sel : 3;
+-              mmr_t   reserved_2         : 1;
+-              mmr_t   nibble1_rlm_sel    : 3;
+-              mmr_t   reserved_1         : 1;
+-              mmr_t   nibble0_nibble_sel : 3;
+-              mmr_t   reserved_0         : 1;
+-              mmr_t   nibble0_rlm_sel    : 3;
+-      } sh_xn_debug_sel_s;
+-} sh_xn_debug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XN_DEBUG_TRIG_SEL"                    */
+ /*                       XN Debug trigger Select                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_debug_trig_sel_u {
+       mmr_t   sh_xn_debug_trig_sel_regval;
+       struct {
+@@ -10287,52 +5550,12 @@
+               mmr_t   reserved_15         : 1;
+       } sh_xn_debug_trig_sel_s;
+ } sh_xn_debug_trig_sel_u_t;
+-#else
+-typedef union sh_xn_debug_trig_sel_u {
+-      mmr_t   sh_xn_debug_trig_sel_regval;
+-      struct {
+-              mmr_t   reserved_15         : 1;
+-              mmr_t   trigger7_nibble_sel : 3;
+-              mmr_t   reserved_14         : 1;
+-              mmr_t   trigger7_rlm_sel    : 3;
+-              mmr_t   reserved_13         : 1;
+-              mmr_t   trigger6_nibble_sel : 3;
+-              mmr_t   reserved_12         : 1;
+-              mmr_t   trigger6_rlm_sel    : 3;
+-              mmr_t   reserved_11         : 1;
+-              mmr_t   trigger5_nibble_sel : 3;
+-              mmr_t   reserved_10         : 1;
+-              mmr_t   trigger5_rlm_sel    : 3;
+-              mmr_t   reserved_9          : 1;
+-              mmr_t   trigger4_nibble_sel : 3;
+-              mmr_t   reserved_8          : 1;
+-              mmr_t   trigger4_rlm_sel    : 3;
+-              mmr_t   reserved_7          : 1;
+-              mmr_t   trigger3_nibble_sel : 3;
+-              mmr_t   reserved_6          : 1;
+-              mmr_t   trigger3_rlm_sel    : 3;
+-              mmr_t   reserved_5          : 1;
+-              mmr_t   trigger2_nibble_sel : 3;
+-              mmr_t   reserved_4          : 1;
+-              mmr_t   trigger2_rlm_sel    : 3;
+-              mmr_t   reserved_3          : 1;
+-              mmr_t   trigger1_nibble_sel : 3;
+-              mmr_t   reserved_2          : 1;
+-              mmr_t   trigger1_rlm_sel    : 3;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   trigger0_nibble_sel : 3;
+-              mmr_t   reserved_0          : 1;
+-              mmr_t   trigger0_rlm_sel    : 3;
+-      } sh_xn_debug_trig_sel_s;
+-} sh_xn_debug_trig_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XN_TRIGGER_COMPARE"                   */
+ /*                           XN Debug Compare                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_trigger_compare_u {
+       mmr_t   sh_xn_trigger_compare_regval;
+       struct {
+@@ -10340,22 +5563,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_xn_trigger_compare_s;
+ } sh_xn_trigger_compare_u_t;
+-#else
+-typedef union sh_xn_trigger_compare_u {
+-      mmr_t   sh_xn_trigger_compare_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   mask        : 32;
+-      } sh_xn_trigger_compare_s;
+-} sh_xn_trigger_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_TRIGGER_DATA"                     */
+ /*                        XN Debug Compare Data                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_trigger_data_u {
+       mmr_t   sh_xn_trigger_data_regval;
+       struct {
+@@ -10363,22 +5576,12 @@
+               mmr_t   reserved_0      : 32;
+       } sh_xn_trigger_data_s;
+ } sh_xn_trigger_data_u_t;
+-#else
+-typedef union sh_xn_trigger_data_u {
+-      mmr_t   sh_xn_trigger_data_regval;
+-      struct {
+-              mmr_t   reserved_0      : 32;
+-              mmr_t   compare_pattern : 32;
+-      } sh_xn_trigger_data_s;
+-} sh_xn_trigger_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XN_IILB_DEBUG_SEL"                    */
+ /*                      XN IILB Debug Port Select                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_debug_sel_u {
+       mmr_t   sh_xn_iilb_debug_sel_regval;
+       struct {
+@@ -10416,52 +5619,12 @@
+               mmr_t   reserved_15        : 1;
+       } sh_xn_iilb_debug_sel_s;
+ } sh_xn_iilb_debug_sel_u_t;
+-#else
+-typedef union sh_xn_iilb_debug_sel_u {
+-      mmr_t   sh_xn_iilb_debug_sel_regval;
+-      struct {
+-              mmr_t   reserved_15        : 1;
+-              mmr_t   nibble7_nibble_sel : 3;
+-              mmr_t   reserved_14        : 1;
+-              mmr_t   nibble7_input_sel  : 3;
+-              mmr_t   reserved_13        : 1;
+-              mmr_t   nibble6_nibble_sel : 3;
+-              mmr_t   reserved_12        : 1;
+-              mmr_t   nibble6_input_sel  : 3;
+-              mmr_t   reserved_11        : 1;
+-              mmr_t   nibble5_nibble_sel : 3;
+-              mmr_t   reserved_10        : 1;
+-              mmr_t   nibble5_input_sel  : 3;
+-              mmr_t   reserved_9         : 1;
+-              mmr_t   nibble4_nibble_sel : 3;
+-              mmr_t   reserved_8         : 1;
+-              mmr_t   nibble4_input_sel  : 3;
+-              mmr_t   reserved_7         : 1;
+-              mmr_t   nibble3_nibble_sel : 3;
+-              mmr_t   reserved_6         : 1;
+-              mmr_t   nibble3_input_sel  : 3;
+-              mmr_t   reserved_5         : 1;
+-              mmr_t   nibble2_nibble_sel : 3;
+-              mmr_t   reserved_4         : 1;
+-              mmr_t   nibble2_input_sel  : 3;
+-              mmr_t   reserved_3         : 1;
+-              mmr_t   nibble1_nibble_sel : 3;
+-              mmr_t   reserved_2         : 1;
+-              mmr_t   nibble1_input_sel  : 3;
+-              mmr_t   reserved_1         : 1;
+-              mmr_t   nibble0_nibble_sel : 3;
+-              mmr_t   reserved_0         : 1;
+-              mmr_t   nibble0_input_sel  : 3;
+-      } sh_xn_iilb_debug_sel_s;
+-} sh_xn_iilb_debug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_PI_DEBUG_SEL"                     */
+ /*                       XN PI Debug Port Select                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_debug_sel_u {
+       mmr_t   sh_xn_pi_debug_sel_regval;
+       struct {
+@@ -10499,52 +5662,12 @@
+               mmr_t   reserved_15        : 1;
+       } sh_xn_pi_debug_sel_s;
+ } sh_xn_pi_debug_sel_u_t;
+-#else
+-typedef union sh_xn_pi_debug_sel_u {
+-      mmr_t   sh_xn_pi_debug_sel_regval;
+-      struct {
+-              mmr_t   reserved_15        : 1;
+-              mmr_t   nibble7_nibble_sel : 3;
+-              mmr_t   reserved_14        : 1;
+-              mmr_t   nibble7_input_sel  : 3;
+-              mmr_t   reserved_13        : 1;
+-              mmr_t   nibble6_nibble_sel : 3;
+-              mmr_t   reserved_12        : 1;
+-              mmr_t   nibble6_input_sel  : 3;
+-              mmr_t   reserved_11        : 1;
+-              mmr_t   nibble5_nibble_sel : 3;
+-              mmr_t   reserved_10        : 1;
+-              mmr_t   nibble5_input_sel  : 3;
+-              mmr_t   reserved_9         : 1;
+-              mmr_t   nibble4_nibble_sel : 3;
+-              mmr_t   reserved_8         : 1;
+-              mmr_t   nibble4_input_sel  : 3;
+-              mmr_t   reserved_7         : 1;
+-              mmr_t   nibble3_nibble_sel : 3;
+-              mmr_t   reserved_6         : 1;
+-              mmr_t   nibble3_input_sel  : 3;
+-              mmr_t   reserved_5         : 1;
+-              mmr_t   nibble2_nibble_sel : 3;
+-              mmr_t   reserved_4         : 1;
+-              mmr_t   nibble2_input_sel  : 3;
+-              mmr_t   reserved_3         : 1;
+-              mmr_t   nibble1_nibble_sel : 3;
+-              mmr_t   reserved_2         : 1;
+-              mmr_t   nibble1_input_sel  : 3;
+-              mmr_t   reserved_1         : 1;
+-              mmr_t   nibble0_nibble_sel : 3;
+-              mmr_t   reserved_0         : 1;
+-              mmr_t   nibble0_input_sel  : 3;
+-      } sh_xn_pi_debug_sel_s;
+-} sh_xn_pi_debug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_MD_DEBUG_SEL"                     */
+ /*                       XN MD Debug Port Select                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_debug_sel_u {
+       mmr_t   sh_xn_md_debug_sel_regval;
+       struct {
+@@ -10582,54 +5705,14 @@
+               mmr_t   reserved_15        : 1;
+       } sh_xn_md_debug_sel_s;
+ } sh_xn_md_debug_sel_u_t;
+-#else
+-typedef union sh_xn_md_debug_sel_u {
+-      mmr_t   sh_xn_md_debug_sel_regval;
+-      struct {
+-              mmr_t   reserved_15        : 1;
+-              mmr_t   nibble7_nibble_sel : 3;
+-              mmr_t   reserved_14        : 1;
+-              mmr_t   nibble7_input_sel  : 3;
+-              mmr_t   reserved_13        : 1;
+-              mmr_t   nibble6_nibble_sel : 3;
+-              mmr_t   reserved_12        : 1;
+-              mmr_t   nibble6_input_sel  : 3;
+-              mmr_t   reserved_11        : 1;
+-              mmr_t   nibble5_nibble_sel : 3;
+-              mmr_t   reserved_10        : 1;
+-              mmr_t   nibble5_input_sel  : 3;
+-              mmr_t   reserved_9         : 1;
+-              mmr_t   nibble4_nibble_sel : 3;
+-              mmr_t   reserved_8         : 1;
+-              mmr_t   nibble4_input_sel  : 3;
+-              mmr_t   reserved_7         : 1;
+-              mmr_t   nibble3_nibble_sel : 3;
+-              mmr_t   reserved_6         : 1;
+-              mmr_t   nibble3_input_sel  : 3;
+-              mmr_t   reserved_5         : 1;
+-              mmr_t   nibble2_nibble_sel : 3;
+-              mmr_t   reserved_4         : 1;
+-              mmr_t   nibble2_input_sel  : 3;
+-              mmr_t   reserved_3         : 1;
+-              mmr_t   nibble1_nibble_sel : 3;
+-              mmr_t   reserved_2         : 1;
+-              mmr_t   nibble1_input_sel  : 3;
+-              mmr_t   reserved_1         : 1;
+-              mmr_t   nibble0_nibble_sel : 3;
+-              mmr_t   reserved_0         : 1;
+-              mmr_t   nibble0_input_sel  : 3;
+-      } sh_xn_md_debug_sel_s;
+-} sh_xn_md_debug_sel_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                    Register "SH_XN_NI0_DEBUG_SEL"                    */
+-/*                       XN NI0 Debug Port Select                       */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_debug_sel_u {
+-      mmr_t   sh_xn_ni0_debug_sel_regval;
++
++/* ==================================================================== */
++/*                    Register "SH_XN_NI0_DEBUG_SEL"                    */
++/*                       XN NI0 Debug Port Select                       */
++/* ==================================================================== */
++
++typedef union sh_xn_ni0_debug_sel_u {
++      mmr_t   sh_xn_ni0_debug_sel_regval;
+       struct {
+               mmr_t   nibble0_input_sel  : 3;
+               mmr_t   reserved_0         : 1;
+@@ -10665,52 +5748,12 @@
+               mmr_t   reserved_15        : 1;
+       } sh_xn_ni0_debug_sel_s;
+ } sh_xn_ni0_debug_sel_u_t;
+-#else
+-typedef union sh_xn_ni0_debug_sel_u {
+-      mmr_t   sh_xn_ni0_debug_sel_regval;
+-      struct {
+-              mmr_t   reserved_15        : 1;
+-              mmr_t   nibble7_nibble_sel : 3;
+-              mmr_t   reserved_14        : 1;
+-              mmr_t   nibble7_input_sel  : 3;
+-              mmr_t   reserved_13        : 1;
+-              mmr_t   nibble6_nibble_sel : 3;
+-              mmr_t   reserved_12        : 1;
+-              mmr_t   nibble6_input_sel  : 3;
+-              mmr_t   reserved_11        : 1;
+-              mmr_t   nibble5_nibble_sel : 3;
+-              mmr_t   reserved_10        : 1;
+-              mmr_t   nibble5_input_sel  : 3;
+-              mmr_t   reserved_9         : 1;
+-              mmr_t   nibble4_nibble_sel : 3;
+-              mmr_t   reserved_8         : 1;
+-              mmr_t   nibble4_input_sel  : 3;
+-              mmr_t   reserved_7         : 1;
+-              mmr_t   nibble3_nibble_sel : 3;
+-              mmr_t   reserved_6         : 1;
+-              mmr_t   nibble3_input_sel  : 3;
+-              mmr_t   reserved_5         : 1;
+-              mmr_t   nibble2_nibble_sel : 3;
+-              mmr_t   reserved_4         : 1;
+-              mmr_t   nibble2_input_sel  : 3;
+-              mmr_t   reserved_3         : 1;
+-              mmr_t   nibble1_nibble_sel : 3;
+-              mmr_t   reserved_2         : 1;
+-              mmr_t   nibble1_input_sel  : 3;
+-              mmr_t   reserved_1         : 1;
+-              mmr_t   nibble0_nibble_sel : 3;
+-              mmr_t   reserved_0         : 1;
+-              mmr_t   nibble0_input_sel  : 3;
+-      } sh_xn_ni0_debug_sel_s;
+-} sh_xn_ni0_debug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_NI1_DEBUG_SEL"                    */
+ /*                       XN NI1 Debug Port Select                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_debug_sel_u {
+       mmr_t   sh_xn_ni1_debug_sel_regval;
+       struct {
+@@ -10748,829 +5791,456 @@
+               mmr_t   reserved_15        : 1;
+       } sh_xn_ni1_debug_sel_s;
+ } sh_xn_ni1_debug_sel_u_t;
+-#else
+-typedef union sh_xn_ni1_debug_sel_u {
+-      mmr_t   sh_xn_ni1_debug_sel_regval;
+-      struct {
+-              mmr_t   reserved_15        : 1;
+-              mmr_t   nibble7_nibble_sel : 3;
+-              mmr_t   reserved_14        : 1;
+-              mmr_t   nibble7_input_sel  : 3;
+-              mmr_t   reserved_13        : 1;
+-              mmr_t   nibble6_nibble_sel : 3;
+-              mmr_t   reserved_12        : 1;
+-              mmr_t   nibble6_input_sel  : 3;
+-              mmr_t   reserved_11        : 1;
+-              mmr_t   nibble5_nibble_sel : 3;
+-              mmr_t   reserved_10        : 1;
+-              mmr_t   nibble5_input_sel  : 3;
+-              mmr_t   reserved_9         : 1;
+-              mmr_t   nibble4_nibble_sel : 3;
+-              mmr_t   reserved_8         : 1;
+-              mmr_t   nibble4_input_sel  : 3;
+-              mmr_t   reserved_7         : 1;
+-              mmr_t   nibble3_nibble_sel : 3;
+-              mmr_t   reserved_6         : 1;
+-              mmr_t   nibble3_input_sel  : 3;
+-              mmr_t   reserved_5         : 1;
+-              mmr_t   nibble2_nibble_sel : 3;
+-              mmr_t   reserved_4         : 1;
+-              mmr_t   nibble2_input_sel  : 3;
+-              mmr_t   reserved_3         : 1;
+-              mmr_t   nibble1_nibble_sel : 3;
+-              mmr_t   reserved_2         : 1;
+-              mmr_t   nibble1_input_sel  : 3;
+-              mmr_t   reserved_1         : 1;
+-              mmr_t   nibble0_nibble_sel : 3;
+-              mmr_t   reserved_0         : 1;
+-              mmr_t   nibble0_input_sel  : 3;
+-      } sh_xn_ni1_debug_sel_s;
+-} sh_xn_ni1_debug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_LB_CMP_EXP_DATA0"                */
+ /*                 IILB compare LB input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_lb_cmp_exp_data0_u {
+-      mmr_t   sh_xn_iilb_lb_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_lb_cmp_exp_data0_s;
+-} sh_xn_iilb_lb_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_lb_cmp_exp_data0_u {
+       mmr_t   sh_xn_iilb_lb_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_lb_cmp_exp_data0_s;
+ } sh_xn_iilb_lb_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_LB_CMP_EXP_DATA1"                */
+ /*                 IILB compare LB input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_lb_cmp_exp_data1_u {
+-      mmr_t   sh_xn_iilb_lb_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_lb_cmp_exp_data1_s;
+-} sh_xn_iilb_lb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_lb_cmp_exp_data1_u {
+       mmr_t   sh_xn_iilb_lb_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_lb_cmp_exp_data1_s;
+ } sh_xn_iilb_lb_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_LB_CMP_ENABLE0"                 */
+ /*                    IILB compare LB input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_lb_cmp_enable0_u {
+       mmr_t   sh_xn_iilb_lb_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_lb_cmp_enable0_s;
+ } sh_xn_iilb_lb_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_lb_cmp_enable0_u {
+-      mmr_t   sh_xn_iilb_lb_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_lb_cmp_enable0_s;
+-} sh_xn_iilb_lb_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_LB_CMP_ENABLE1"                 */
+ /*                    IILB compare LB input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_lb_cmp_enable1_u {
+-      mmr_t   sh_xn_iilb_lb_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_lb_cmp_enable1_s;
+-} sh_xn_iilb_lb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_lb_cmp_enable1_u {
+       mmr_t   sh_xn_iilb_lb_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_lb_cmp_enable1_s;
+ } sh_xn_iilb_lb_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_II_CMP_EXP_DATA0"                */
+ /*                 IILB compare II input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ii_cmp_exp_data0_u {
+-      mmr_t   sh_xn_iilb_ii_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_ii_cmp_exp_data0_s;
+-} sh_xn_iilb_ii_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_ii_cmp_exp_data0_u {
+       mmr_t   sh_xn_iilb_ii_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_ii_cmp_exp_data0_s;
+ } sh_xn_iilb_ii_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_II_CMP_EXP_DATA1"                */
+ /*                 IILB compare II input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ii_cmp_exp_data1_u {
+-      mmr_t   sh_xn_iilb_ii_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_ii_cmp_exp_data1_s;
+-} sh_xn_iilb_ii_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_ii_cmp_exp_data1_u {
+       mmr_t   sh_xn_iilb_ii_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_ii_cmp_exp_data1_s;
+ } sh_xn_iilb_ii_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_II_CMP_ENABLE0"                 */
+ /*                    IILB compare II input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_ii_cmp_enable0_u {
+       mmr_t   sh_xn_iilb_ii_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_ii_cmp_enable0_s;
+ } sh_xn_iilb_ii_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_ii_cmp_enable0_u {
+-      mmr_t   sh_xn_iilb_ii_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_ii_cmp_enable0_s;
+-} sh_xn_iilb_ii_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_II_CMP_ENABLE1"                 */
+ /*                    IILB compare II input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ii_cmp_enable1_u {
+-      mmr_t   sh_xn_iilb_ii_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_ii_cmp_enable1_s;
+-} sh_xn_iilb_ii_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_ii_cmp_enable1_u {
+       mmr_t   sh_xn_iilb_ii_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_ii_cmp_enable1_s;
+ } sh_xn_iilb_ii_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_MD_CMP_EXP_DATA0"                */
+ /*                 IILB compare MD input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_md_cmp_exp_data0_u {
+-      mmr_t   sh_xn_iilb_md_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_md_cmp_exp_data0_s;
+-} sh_xn_iilb_md_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_md_cmp_exp_data0_u {
+       mmr_t   sh_xn_iilb_md_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_md_cmp_exp_data0_s;
+ } sh_xn_iilb_md_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_MD_CMP_EXP_DATA1"                */
+ /*                 IILB compare MD input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_md_cmp_exp_data1_u {
+-      mmr_t   sh_xn_iilb_md_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_md_cmp_exp_data1_s;
+-} sh_xn_iilb_md_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_md_cmp_exp_data1_u {
+       mmr_t   sh_xn_iilb_md_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_md_cmp_exp_data1_s;
+ } sh_xn_iilb_md_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_MD_CMP_ENABLE0"                 */
+ /*                    IILB compare MD input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_md_cmp_enable0_u {
+       mmr_t   sh_xn_iilb_md_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_md_cmp_enable0_s;
+ } sh_xn_iilb_md_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_md_cmp_enable0_u {
+-      mmr_t   sh_xn_iilb_md_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_md_cmp_enable0_s;
+-} sh_xn_iilb_md_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_MD_CMP_ENABLE1"                 */
+ /*                    IILB compare MD input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_md_cmp_enable1_u {
+-      mmr_t   sh_xn_iilb_md_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_md_cmp_enable1_s;
+-} sh_xn_iilb_md_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_md_cmp_enable1_u {
+       mmr_t   sh_xn_iilb_md_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_md_cmp_enable1_s;
+ } sh_xn_iilb_md_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_PI_CMP_EXP_DATA0"                */
+ /*                 IILB compare PI input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_pi_cmp_exp_data0_u {
+-      mmr_t   sh_xn_iilb_pi_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_pi_cmp_exp_data0_s;
+-} sh_xn_iilb_pi_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_pi_cmp_exp_data0_u {
+       mmr_t   sh_xn_iilb_pi_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_pi_cmp_exp_data0_s;
+ } sh_xn_iilb_pi_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_PI_CMP_EXP_DATA1"                */
+ /*                 IILB compare PI input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_pi_cmp_exp_data1_u {
+-      mmr_t   sh_xn_iilb_pi_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_pi_cmp_exp_data1_s;
+-} sh_xn_iilb_pi_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_pi_cmp_exp_data1_u {
+       mmr_t   sh_xn_iilb_pi_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_pi_cmp_exp_data1_s;
+ } sh_xn_iilb_pi_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_PI_CMP_ENABLE0"                 */
+ /*                    IILB compare PI input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_pi_cmp_enable0_u {
+       mmr_t   sh_xn_iilb_pi_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_pi_cmp_enable0_s;
+ } sh_xn_iilb_pi_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_pi_cmp_enable0_u {
+-      mmr_t   sh_xn_iilb_pi_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_pi_cmp_enable0_s;
+-} sh_xn_iilb_pi_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_IILB_PI_CMP_ENABLE1"                 */
+ /*                    IILB compare PI input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_pi_cmp_enable1_u {
+-      mmr_t   sh_xn_iilb_pi_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_pi_cmp_enable1_s;
+-} sh_xn_iilb_pi_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_pi_cmp_enable1_u {
+       mmr_t   sh_xn_iilb_pi_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_pi_cmp_enable1_s;
+ } sh_xn_iilb_pi_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_IILB_NI0_CMP_EXP_DATA0"                */
+ /*                IILB compare NI0 input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni0_cmp_exp_data0_u {
+-      mmr_t   sh_xn_iilb_ni0_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_ni0_cmp_exp_data0_s;
+-} sh_xn_iilb_ni0_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_ni0_cmp_exp_data0_u {
+       mmr_t   sh_xn_iilb_ni0_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_ni0_cmp_exp_data0_s;
+ } sh_xn_iilb_ni0_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_IILB_NI0_CMP_EXP_DATA1"                */
+ /*                IILB compare NI0 input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni0_cmp_exp_data1_u {
+-      mmr_t   sh_xn_iilb_ni0_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_ni0_cmp_exp_data1_s;
+-} sh_xn_iilb_ni0_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni0_cmp_exp_data1_u {
+       mmr_t   sh_xn_iilb_ni0_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_ni0_cmp_exp_data1_s;
+ } sh_xn_iilb_ni0_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_NI0_CMP_ENABLE0"                 */
+ /*                    IILB compare NI0 input enable0                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_ni0_cmp_enable0_u {
+       mmr_t   sh_xn_iilb_ni0_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_ni0_cmp_enable0_s;
+ } sh_xn_iilb_ni0_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_ni0_cmp_enable0_u {
+-      mmr_t   sh_xn_iilb_ni0_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_ni0_cmp_enable0_s;
+-} sh_xn_iilb_ni0_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_NI0_CMP_ENABLE1"                 */
+ /*                    IILB compare NI0 input enable1                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni0_cmp_enable1_u {
+-      mmr_t   sh_xn_iilb_ni0_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_ni0_cmp_enable1_s;
+-} sh_xn_iilb_ni0_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni0_cmp_enable1_u {
+       mmr_t   sh_xn_iilb_ni0_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_ni0_cmp_enable1_s;
+ } sh_xn_iilb_ni0_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_IILB_NI1_CMP_EXP_DATA0"                */
+ /*                IILB compare NI1 input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni1_cmp_exp_data0_u {
+-      mmr_t   sh_xn_iilb_ni1_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_ni1_cmp_exp_data0_s;
+-} sh_xn_iilb_ni1_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_iilb_ni1_cmp_exp_data0_u {
+       mmr_t   sh_xn_iilb_ni1_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_ni1_cmp_exp_data0_s;
+ } sh_xn_iilb_ni1_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_IILB_NI1_CMP_EXP_DATA1"                */
+ /*                IILB compare NI1 input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni1_cmp_exp_data1_u {
+-      mmr_t   sh_xn_iilb_ni1_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_iilb_ni1_cmp_exp_data1_s;
+-} sh_xn_iilb_ni1_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni1_cmp_exp_data1_u {
+       mmr_t   sh_xn_iilb_ni1_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_iilb_ni1_cmp_exp_data1_s;
+ } sh_xn_iilb_ni1_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_NI1_CMP_ENABLE0"                 */
+ /*                    IILB compare NI1 input enable0                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_iilb_ni1_cmp_enable0_u {
+       mmr_t   sh_xn_iilb_ni1_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_ni1_cmp_enable0_s;
+ } sh_xn_iilb_ni1_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_iilb_ni1_cmp_enable0_u {
+-      mmr_t   sh_xn_iilb_ni1_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_ni1_cmp_enable0_s;
+-} sh_xn_iilb_ni1_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_IILB_NI1_CMP_ENABLE1"                 */
+ /*                    IILB compare NI1 input enable1                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_iilb_ni1_cmp_enable1_u {
+-      mmr_t   sh_xn_iilb_ni1_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_iilb_ni1_cmp_enable1_s;
+-} sh_xn_iilb_ni1_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_iilb_ni1_cmp_enable1_u {
+       mmr_t   sh_xn_iilb_ni1_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_iilb_ni1_cmp_enable1_s;
+ } sh_xn_iilb_ni1_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_MD_IILB_CMP_EXP_DATA0"                */
+ /*                 MD compare IILB input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_iilb_cmp_exp_data0_u {
+-      mmr_t   sh_xn_md_iilb_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_md_iilb_cmp_exp_data0_s;
+-} sh_xn_md_iilb_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_md_iilb_cmp_exp_data0_u {
+       mmr_t   sh_xn_md_iilb_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_md_iilb_cmp_exp_data0_s;
+ } sh_xn_md_iilb_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_MD_IILB_CMP_EXP_DATA1"                */
+ /*                 MD compare IILB input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_iilb_cmp_exp_data1_u {
+-      mmr_t   sh_xn_md_iilb_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_md_iilb_cmp_exp_data1_s;
+-} sh_xn_md_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_md_iilb_cmp_exp_data1_u {
+       mmr_t   sh_xn_md_iilb_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_md_iilb_cmp_exp_data1_s;
+ } sh_xn_md_iilb_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_IILB_CMP_ENABLE0"                 */
+ /*                    MD compare IILB input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_iilb_cmp_enable0_u {
+       mmr_t   sh_xn_md_iilb_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_md_iilb_cmp_enable0_s;
+ } sh_xn_md_iilb_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_md_iilb_cmp_enable0_u {
+-      mmr_t   sh_xn_md_iilb_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_md_iilb_cmp_enable0_s;
+-} sh_xn_md_iilb_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_IILB_CMP_ENABLE1"                 */
+ /*                    MD compare IILB input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_iilb_cmp_enable1_u {
+-      mmr_t   sh_xn_md_iilb_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_md_iilb_cmp_enable1_s;
+-} sh_xn_md_iilb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_md_iilb_cmp_enable1_u {
+       mmr_t   sh_xn_md_iilb_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_md_iilb_cmp_enable1_s;
+ } sh_xn_md_iilb_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_MD_NI0_CMP_EXP_DATA0"                 */
+ /*                 MD compare NI0 input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni0_cmp_exp_data0_u {
+-      mmr_t   sh_xn_md_ni0_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_md_ni0_cmp_exp_data0_s;
+-} sh_xn_md_ni0_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_md_ni0_cmp_exp_data0_u {
+       mmr_t   sh_xn_md_ni0_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_md_ni0_cmp_exp_data0_s;
+ } sh_xn_md_ni0_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_MD_NI0_CMP_EXP_DATA1"                 */
+ /*                 MD compare NI0 input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni0_cmp_exp_data1_u {
+-      mmr_t   sh_xn_md_ni0_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_md_ni0_cmp_exp_data1_s;
+-} sh_xn_md_ni0_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_md_ni0_cmp_exp_data1_u {
+       mmr_t   sh_xn_md_ni0_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_md_ni0_cmp_exp_data1_s;
+ } sh_xn_md_ni0_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_NI0_CMP_ENABLE0"                  */
+ /*                     MD compare NI0 input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_ni0_cmp_enable0_u {
+       mmr_t   sh_xn_md_ni0_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_md_ni0_cmp_enable0_s;
+ } sh_xn_md_ni0_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_md_ni0_cmp_enable0_u {
+-      mmr_t   sh_xn_md_ni0_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_md_ni0_cmp_enable0_s;
+-} sh_xn_md_ni0_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_NI0_CMP_ENABLE1"                  */
+ /*                     MD compare NI0 input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni0_cmp_enable1_u {
+-      mmr_t   sh_xn_md_ni0_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_md_ni0_cmp_enable1_s;
+-} sh_xn_md_ni0_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_md_ni0_cmp_enable1_u {
+       mmr_t   sh_xn_md_ni0_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_md_ni0_cmp_enable1_s;
+ } sh_xn_md_ni0_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_MD_NI1_CMP_EXP_DATA0"                 */
+ /*                 MD compare NI1 input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni1_cmp_exp_data0_u {
+-      mmr_t   sh_xn_md_ni1_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_md_ni1_cmp_exp_data0_s;
+-} sh_xn_md_ni1_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_md_ni1_cmp_exp_data0_u {
+       mmr_t   sh_xn_md_ni1_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_md_ni1_cmp_exp_data0_s;
+ } sh_xn_md_ni1_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_MD_NI1_CMP_EXP_DATA1"                 */
+ /*                 MD compare NI1 input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni1_cmp_exp_data1_u {
+-      mmr_t   sh_xn_md_ni1_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_md_ni1_cmp_exp_data1_s;
+-} sh_xn_md_ni1_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_md_ni1_cmp_exp_data1_u {
+       mmr_t   sh_xn_md_ni1_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_md_ni1_cmp_exp_data1_s;
+ } sh_xn_md_ni1_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_NI1_CMP_ENABLE0"                  */
+ /*                     MD compare NI1 input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_ni1_cmp_enable0_u {
+       mmr_t   sh_xn_md_ni1_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_md_ni1_cmp_enable0_s;
+ } sh_xn_md_ni1_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_md_ni1_cmp_enable0_u {
+-      mmr_t   sh_xn_md_ni1_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_md_ni1_cmp_enable0_s;
+-} sh_xn_md_ni1_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_NI1_CMP_ENABLE1"                  */
+ /*                     MD compare NI1 input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_ni1_cmp_enable1_u {
+-      mmr_t   sh_xn_md_ni1_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_md_ni1_cmp_enable1_s;
+-} sh_xn_md_ni1_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_md_ni1_cmp_enable1_u {
+       mmr_t   sh_xn_md_ni1_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_md_ni1_cmp_enable1_s;
+ } sh_xn_md_ni1_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_SIC_CMP_EXP_HDR0"                 */
+ /*                MD compare SIC input expected header0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_exp_hdr0_u {
+-      mmr_t   sh_xn_md_sic_cmp_exp_hdr0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_md_sic_cmp_exp_hdr0_s;
+-} sh_xn_md_sic_cmp_exp_hdr0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_exp_hdr0_u {
+       mmr_t   sh_xn_md_sic_cmp_exp_hdr0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_md_sic_cmp_exp_hdr0_s;
+ } sh_xn_md_sic_cmp_exp_hdr0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_MD_SIC_CMP_EXP_HDR1"                 */
+ /*                MD compare SIC input expected header1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_exp_hdr1_u {
+       mmr_t   sh_xn_md_sic_cmp_exp_hdr1_regval;
+       struct {
+@@ -11578,43 +6248,24 @@
+               mmr_t   reserved_0  : 22;
+       } sh_xn_md_sic_cmp_exp_hdr1_s;
+ } sh_xn_md_sic_cmp_exp_hdr1_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_exp_hdr1_u {
+-      mmr_t   sh_xn_md_sic_cmp_exp_hdr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   data        : 42;
+-      } sh_xn_md_sic_cmp_exp_hdr1_s;
+-} sh_xn_md_sic_cmp_exp_hdr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_MD_SIC_CMP_HDR_ENABLE0"                */
+ /*                    MD compare SIC header enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_hdr_enable0_u {
+-      mmr_t   sh_xn_md_sic_cmp_hdr_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_md_sic_cmp_hdr_enable0_s;
+-} sh_xn_md_sic_cmp_hdr_enable0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_hdr_enable0_u {
+       mmr_t   sh_xn_md_sic_cmp_hdr_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_md_sic_cmp_hdr_enable0_s;
+ } sh_xn_md_sic_cmp_hdr_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_MD_SIC_CMP_HDR_ENABLE1"                */
+ /*                    MD compare SIC header enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_hdr_enable1_u {
+       mmr_t   sh_xn_md_sic_cmp_hdr_enable1_regval;
+       struct {
+@@ -11622,463 +6273,264 @@
+               mmr_t   reserved_0  : 22;
+       } sh_xn_md_sic_cmp_hdr_enable1_s;
+ } sh_xn_md_sic_cmp_hdr_enable1_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_hdr_enable1_u {
+-      mmr_t   sh_xn_md_sic_cmp_hdr_enable1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   enable      : 42;
+-      } sh_xn_md_sic_cmp_hdr_enable1_s;
+-} sh_xn_md_sic_cmp_hdr_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_MD_SIC_CMP_DATA0"                   */
+ /*                         MD compare SIC data0                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data0_u {
+-      mmr_t   sh_xn_md_sic_cmp_data0_regval;
+-      struct {
+-              mmr_t   data0       : 64;
+-      } sh_xn_md_sic_cmp_data0_s;
+-} sh_xn_md_sic_cmp_data0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data0_u {
+       mmr_t   sh_xn_md_sic_cmp_data0_regval;
+       struct {
+               mmr_t   data0       : 64;
+       } sh_xn_md_sic_cmp_data0_s;
+ } sh_xn_md_sic_cmp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_MD_SIC_CMP_DATA1"                   */
+ /*                         MD compare SIC data1                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data1_u {
+-      mmr_t   sh_xn_md_sic_cmp_data1_regval;
+-      struct {
+-              mmr_t   data1       : 64;
+-      } sh_xn_md_sic_cmp_data1_s;
+-} sh_xn_md_sic_cmp_data1_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data1_u {
+       mmr_t   sh_xn_md_sic_cmp_data1_regval;
+       struct {
+               mmr_t   data1       : 64;
+       } sh_xn_md_sic_cmp_data1_s;
+ } sh_xn_md_sic_cmp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_MD_SIC_CMP_DATA2"                   */
+ /*                         MD compare SIC data2                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data2_u {
+-      mmr_t   sh_xn_md_sic_cmp_data2_regval;
+-      struct {
+-              mmr_t   data2       : 64;
+-      } sh_xn_md_sic_cmp_data2_s;
+-} sh_xn_md_sic_cmp_data2_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data2_u {
+       mmr_t   sh_xn_md_sic_cmp_data2_regval;
+       struct {
+               mmr_t   data2       : 64;
+       } sh_xn_md_sic_cmp_data2_s;
+ } sh_xn_md_sic_cmp_data2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_MD_SIC_CMP_DATA3"                   */
+ /*                         MD compare SIC data3                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_data3_u {
+       mmr_t   sh_xn_md_sic_cmp_data3_regval;
+       struct {
+               mmr_t   data3       : 64;
+       } sh_xn_md_sic_cmp_data3_s;
+ } sh_xn_md_sic_cmp_data3_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_data3_u {
+-      mmr_t   sh_xn_md_sic_cmp_data3_regval;
+-      struct {
+-              mmr_t   data3       : 64;
+-      } sh_xn_md_sic_cmp_data3_s;
+-} sh_xn_md_sic_cmp_data3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE0"               */
+ /*                     MD enable compare SIC data0                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data_enable0_u {
+-      mmr_t   sh_xn_md_sic_cmp_data_enable0_regval;
+-      struct {
+-              mmr_t   data_enable0 : 64;
+-      } sh_xn_md_sic_cmp_data_enable0_s;
+-} sh_xn_md_sic_cmp_data_enable0_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data_enable0_u {
+       mmr_t   sh_xn_md_sic_cmp_data_enable0_regval;
+       struct {
+               mmr_t   data_enable0 : 64;
+       } sh_xn_md_sic_cmp_data_enable0_s;
+ } sh_xn_md_sic_cmp_data_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE1"               */
+ /*                     MD enable compare SIC data1                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data_enable1_u {
+-      mmr_t   sh_xn_md_sic_cmp_data_enable1_regval;
+-      struct {
+-              mmr_t   data_enable1 : 64;
+-      } sh_xn_md_sic_cmp_data_enable1_s;
+-} sh_xn_md_sic_cmp_data_enable1_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data_enable1_u {
+       mmr_t   sh_xn_md_sic_cmp_data_enable1_regval;
+       struct {
+               mmr_t   data_enable1 : 64;
+       } sh_xn_md_sic_cmp_data_enable1_s;
+ } sh_xn_md_sic_cmp_data_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE2"               */
+ /*                     MD enable compare SIC data2                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_md_sic_cmp_data_enable2_u {
+-      mmr_t   sh_xn_md_sic_cmp_data_enable2_regval;
+-      struct {
+-              mmr_t   data_enable2 : 64;
+-      } sh_xn_md_sic_cmp_data_enable2_s;
+-} sh_xn_md_sic_cmp_data_enable2_u_t;
+-#else
+ typedef union sh_xn_md_sic_cmp_data_enable2_u {
+       mmr_t   sh_xn_md_sic_cmp_data_enable2_regval;
+       struct {
+               mmr_t   data_enable2 : 64;
+       } sh_xn_md_sic_cmp_data_enable2_s;
+ } sh_xn_md_sic_cmp_data_enable2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_MD_SIC_CMP_DATA_ENABLE3"               */
+ /*                     MD enable compare SIC data3                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_sic_cmp_data_enable3_u {
+       mmr_t   sh_xn_md_sic_cmp_data_enable3_regval;
+       struct {
+               mmr_t   data_enable3 : 64;
+       } sh_xn_md_sic_cmp_data_enable3_s;
+ } sh_xn_md_sic_cmp_data_enable3_u_t;
+-#else
+-typedef union sh_xn_md_sic_cmp_data_enable3_u {
+-      mmr_t   sh_xn_md_sic_cmp_data_enable3_regval;
+-      struct {
+-              mmr_t   data_enable3 : 64;
+-      } sh_xn_md_sic_cmp_data_enable3_s;
+-} sh_xn_md_sic_cmp_data_enable3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_PI_IILB_CMP_EXP_DATA0"                */
+ /*                 PI compare IILB input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_iilb_cmp_exp_data0_u {
+-      mmr_t   sh_xn_pi_iilb_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_pi_iilb_cmp_exp_data0_s;
+-} sh_xn_pi_iilb_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_pi_iilb_cmp_exp_data0_u {
+       mmr_t   sh_xn_pi_iilb_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_pi_iilb_cmp_exp_data0_s;
+ } sh_xn_pi_iilb_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_PI_IILB_CMP_EXP_DATA1"                */
+ /*                 PI compare IILB input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_iilb_cmp_exp_data1_u {
+-      mmr_t   sh_xn_pi_iilb_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_pi_iilb_cmp_exp_data1_s;
+-} sh_xn_pi_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_iilb_cmp_exp_data1_u {
+       mmr_t   sh_xn_pi_iilb_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_pi_iilb_cmp_exp_data1_s;
+ } sh_xn_pi_iilb_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_IILB_CMP_ENABLE0"                 */
+ /*                    PI compare IILB input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_iilb_cmp_enable0_u {
+-      mmr_t   sh_xn_pi_iilb_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_pi_iilb_cmp_enable0_s;
+-} sh_xn_pi_iilb_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_iilb_cmp_enable0_u {
+       mmr_t   sh_xn_pi_iilb_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_pi_iilb_cmp_enable0_s;
+ } sh_xn_pi_iilb_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_IILB_CMP_ENABLE1"                 */
+ /*                    PI compare IILB input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_iilb_cmp_enable1_u {
+       mmr_t   sh_xn_pi_iilb_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_pi_iilb_cmp_enable1_s;
+ } sh_xn_pi_iilb_cmp_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_iilb_cmp_enable1_u {
+-      mmr_t   sh_xn_pi_iilb_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_pi_iilb_cmp_enable1_s;
+-} sh_xn_pi_iilb_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_PI_NI0_CMP_EXP_DATA0"                 */
+ /*                 PI compare NI0 input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni0_cmp_exp_data0_u {
+-      mmr_t   sh_xn_pi_ni0_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_pi_ni0_cmp_exp_data0_s;
+-} sh_xn_pi_ni0_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_pi_ni0_cmp_exp_data0_u {
+       mmr_t   sh_xn_pi_ni0_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_pi_ni0_cmp_exp_data0_s;
+ } sh_xn_pi_ni0_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_PI_NI0_CMP_EXP_DATA1"                 */
+ /*                 PI compare NI0 input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni0_cmp_exp_data1_u {
+-      mmr_t   sh_xn_pi_ni0_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_pi_ni0_cmp_exp_data1_s;
+-} sh_xn_pi_ni0_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_ni0_cmp_exp_data1_u {
+       mmr_t   sh_xn_pi_ni0_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_pi_ni0_cmp_exp_data1_s;
+ } sh_xn_pi_ni0_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_NI0_CMP_ENABLE0"                  */
+ /*                     PI compare NI0 input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni0_cmp_enable0_u {
+-      mmr_t   sh_xn_pi_ni0_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_pi_ni0_cmp_enable0_s;
+-} sh_xn_pi_ni0_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_ni0_cmp_enable0_u {
+       mmr_t   sh_xn_pi_ni0_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_pi_ni0_cmp_enable0_s;
+ } sh_xn_pi_ni0_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_NI0_CMP_ENABLE1"                  */
+ /*                     PI compare NI0 input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_ni0_cmp_enable1_u {
+       mmr_t   sh_xn_pi_ni0_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_pi_ni0_cmp_enable1_s;
+ } sh_xn_pi_ni0_cmp_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_ni0_cmp_enable1_u {
+-      mmr_t   sh_xn_pi_ni0_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_pi_ni0_cmp_enable1_s;
+-} sh_xn_pi_ni0_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_PI_NI1_CMP_EXP_DATA0"                 */
+ /*                 PI compare NI1 input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni1_cmp_exp_data0_u {
+-      mmr_t   sh_xn_pi_ni1_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_pi_ni1_cmp_exp_data0_s;
+-} sh_xn_pi_ni1_cmp_exp_data0_u_t;
+-#else
+ typedef union sh_xn_pi_ni1_cmp_exp_data0_u {
+       mmr_t   sh_xn_pi_ni1_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_pi_ni1_cmp_exp_data0_s;
+ } sh_xn_pi_ni1_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_PI_NI1_CMP_EXP_DATA1"                 */
+ /*                 PI compare NI1 input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni1_cmp_exp_data1_u {
+-      mmr_t   sh_xn_pi_ni1_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_pi_ni1_cmp_exp_data1_s;
+-} sh_xn_pi_ni1_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_ni1_cmp_exp_data1_u {
+       mmr_t   sh_xn_pi_ni1_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_pi_ni1_cmp_exp_data1_s;
+ } sh_xn_pi_ni1_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_NI1_CMP_ENABLE0"                  */
+ /*                     PI compare NI1 input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_ni1_cmp_enable0_u {
+-      mmr_t   sh_xn_pi_ni1_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_pi_ni1_cmp_enable0_s;
+-} sh_xn_pi_ni1_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_ni1_cmp_enable0_u {
+       mmr_t   sh_xn_pi_ni1_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_pi_ni1_cmp_enable0_s;
+ } sh_xn_pi_ni1_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_NI1_CMP_ENABLE1"                  */
+ /*                     PI compare NI1 input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_ni1_cmp_enable1_u {
+       mmr_t   sh_xn_pi_ni1_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_pi_ni1_cmp_enable1_s;
+ } sh_xn_pi_ni1_cmp_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_ni1_cmp_enable1_u {
+-      mmr_t   sh_xn_pi_ni1_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_pi_ni1_cmp_enable1_s;
+-} sh_xn_pi_ni1_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_SIC_CMP_EXP_HDR0"                 */
+ /*                PI compare SIC input expected header0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_exp_hdr0_u {
+-      mmr_t   sh_xn_pi_sic_cmp_exp_hdr0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_pi_sic_cmp_exp_hdr0_s;
+-} sh_xn_pi_sic_cmp_exp_hdr0_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_exp_hdr0_u {
+       mmr_t   sh_xn_pi_sic_cmp_exp_hdr0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_pi_sic_cmp_exp_hdr0_s;
+ } sh_xn_pi_sic_cmp_exp_hdr0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_PI_SIC_CMP_EXP_HDR1"                 */
+ /*                PI compare SIC input expected header1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_exp_hdr1_u {
+       mmr_t   sh_xn_pi_sic_cmp_exp_hdr1_regval;
+       struct {
+@@ -12086,43 +6538,24 @@
+               mmr_t   reserved_0  : 22;
+       } sh_xn_pi_sic_cmp_exp_hdr1_s;
+ } sh_xn_pi_sic_cmp_exp_hdr1_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_exp_hdr1_u {
+-      mmr_t   sh_xn_pi_sic_cmp_exp_hdr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   data        : 42;
+-      } sh_xn_pi_sic_cmp_exp_hdr1_s;
+-} sh_xn_pi_sic_cmp_exp_hdr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_PI_SIC_CMP_HDR_ENABLE0"                */
+ /*                    PI compare SIC header enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_hdr_enable0_u {
+-      mmr_t   sh_xn_pi_sic_cmp_hdr_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_pi_sic_cmp_hdr_enable0_s;
+-} sh_xn_pi_sic_cmp_hdr_enable0_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_hdr_enable0_u {
+       mmr_t   sh_xn_pi_sic_cmp_hdr_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_pi_sic_cmp_hdr_enable0_s;
+ } sh_xn_pi_sic_cmp_hdr_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_PI_SIC_CMP_HDR_ENABLE1"                */
+ /*                    PI compare SIC header enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_hdr_enable1_u {
+       mmr_t   sh_xn_pi_sic_cmp_hdr_enable1_regval;
+       struct {
+@@ -12130,1029 +6563,587 @@
+               mmr_t   reserved_0  : 22;
+       } sh_xn_pi_sic_cmp_hdr_enable1_s;
+ } sh_xn_pi_sic_cmp_hdr_enable1_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_hdr_enable1_u {
+-      mmr_t   sh_xn_pi_sic_cmp_hdr_enable1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   enable      : 42;
+-      } sh_xn_pi_sic_cmp_hdr_enable1_s;
+-} sh_xn_pi_sic_cmp_hdr_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_PI_SIC_CMP_DATA0"                   */
+ /*                         PI compare SIC data0                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_data0_u {
+       mmr_t   sh_xn_pi_sic_cmp_data0_regval;
+       struct {
+               mmr_t   data0       : 64;
+       } sh_xn_pi_sic_cmp_data0_s;
+ } sh_xn_pi_sic_cmp_data0_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_data0_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data0_regval;
+-      struct {
+-              mmr_t   data0       : 64;
+-      } sh_xn_pi_sic_cmp_data0_s;
+-} sh_xn_pi_sic_cmp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_PI_SIC_CMP_DATA1"                   */
+ /*                         PI compare SIC data1                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data1_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data1_regval;
+-      struct {
+-              mmr_t   data1       : 64;
+-      } sh_xn_pi_sic_cmp_data1_s;
+-} sh_xn_pi_sic_cmp_data1_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data1_u {
+       mmr_t   sh_xn_pi_sic_cmp_data1_regval;
+       struct {
+               mmr_t   data1       : 64;
+       } sh_xn_pi_sic_cmp_data1_s;
+ } sh_xn_pi_sic_cmp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_PI_SIC_CMP_DATA2"                   */
+ /*                         PI compare SIC data2                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data2_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data2_regval;
+-      struct {
+-              mmr_t   data2       : 64;
+-      } sh_xn_pi_sic_cmp_data2_s;
+-} sh_xn_pi_sic_cmp_data2_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data2_u {
+       mmr_t   sh_xn_pi_sic_cmp_data2_regval;
+       struct {
+               mmr_t   data2       : 64;
+       } sh_xn_pi_sic_cmp_data2_s;
+ } sh_xn_pi_sic_cmp_data2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_PI_SIC_CMP_DATA3"                   */
+ /*                         PI compare SIC data3                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data3_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data3_regval;
+-      struct {
+-              mmr_t   data3       : 64;
+-      } sh_xn_pi_sic_cmp_data3_s;
+-} sh_xn_pi_sic_cmp_data3_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data3_u {
+       mmr_t   sh_xn_pi_sic_cmp_data3_regval;
+       struct {
+               mmr_t   data3       : 64;
+       } sh_xn_pi_sic_cmp_data3_s;
+ } sh_xn_pi_sic_cmp_data3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE0"               */
+ /*                     PI enable compare SIC data0                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_pi_sic_cmp_data_enable0_u {
+       mmr_t   sh_xn_pi_sic_cmp_data_enable0_regval;
+       struct {
+               mmr_t   data_enable0 : 64;
+       } sh_xn_pi_sic_cmp_data_enable0_s;
+ } sh_xn_pi_sic_cmp_data_enable0_u_t;
+-#else
+-typedef union sh_xn_pi_sic_cmp_data_enable0_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data_enable0_regval;
+-      struct {
+-              mmr_t   data_enable0 : 64;
+-      } sh_xn_pi_sic_cmp_data_enable0_s;
+-} sh_xn_pi_sic_cmp_data_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE1"               */
+ /*                     PI enable compare SIC data1                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data_enable1_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data_enable1_regval;
+-      struct {
+-              mmr_t   data_enable1 : 64;
+-      } sh_xn_pi_sic_cmp_data_enable1_s;
+-} sh_xn_pi_sic_cmp_data_enable1_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data_enable1_u {
+       mmr_t   sh_xn_pi_sic_cmp_data_enable1_regval;
+       struct {
+               mmr_t   data_enable1 : 64;
+       } sh_xn_pi_sic_cmp_data_enable1_s;
+ } sh_xn_pi_sic_cmp_data_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE2"               */
+ /*                     PI enable compare SIC data2                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data_enable2_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data_enable2_regval;
+-      struct {
+-              mmr_t   data_enable2 : 64;
+-      } sh_xn_pi_sic_cmp_data_enable2_s;
+-} sh_xn_pi_sic_cmp_data_enable2_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data_enable2_u {
+       mmr_t   sh_xn_pi_sic_cmp_data_enable2_regval;
+       struct {
+               mmr_t   data_enable2 : 64;
+       } sh_xn_pi_sic_cmp_data_enable2_s;
+ } sh_xn_pi_sic_cmp_data_enable2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_PI_SIC_CMP_DATA_ENABLE3"               */
+ /*                     PI enable compare SIC data3                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_pi_sic_cmp_data_enable3_u {
+-      mmr_t   sh_xn_pi_sic_cmp_data_enable3_regval;
+-      struct {
+-              mmr_t   data_enable3 : 64;
+-      } sh_xn_pi_sic_cmp_data_enable3_s;
+-} sh_xn_pi_sic_cmp_data_enable3_u_t;
+-#else
+ typedef union sh_xn_pi_sic_cmp_data_enable3_u {
+       mmr_t   sh_xn_pi_sic_cmp_data_enable3_regval;
+       struct {
+               mmr_t   data_enable3 : 64;
+       } sh_xn_pi_sic_cmp_data_enable3_s;
+ } sh_xn_pi_sic_cmp_data_enable3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_NI0_IILB_CMP_EXP_DATA0"                */
+ /*                NI0 compare IILB input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_iilb_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni0_iilb_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_iilb_cmp_exp_data0_s;
+ } sh_xn_ni0_iilb_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_iilb_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni0_iilb_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_iilb_cmp_exp_data0_s;
+-} sh_xn_ni0_iilb_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_NI0_IILB_CMP_EXP_DATA1"                */
+ /*                NI0 compare IILB input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_iilb_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni0_iilb_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_iilb_cmp_exp_data1_s;
+-} sh_xn_ni0_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_iilb_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni0_iilb_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_iilb_cmp_exp_data1_s;
+ } sh_xn_ni0_iilb_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_IILB_CMP_ENABLE0"                 */
+ /*                    NI0 compare IILB input enable0                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_iilb_cmp_enable0_u {
+-      mmr_t   sh_xn_ni0_iilb_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_iilb_cmp_enable0_s;
+-} sh_xn_ni0_iilb_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_iilb_cmp_enable0_u {
+       mmr_t   sh_xn_ni0_iilb_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_iilb_cmp_enable0_s;
+ } sh_xn_ni0_iilb_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_IILB_CMP_ENABLE1"                 */
+ /*                    NI0 compare IILB input enable1                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_iilb_cmp_enable1_u {
+-      mmr_t   sh_xn_ni0_iilb_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_iilb_cmp_enable1_s;
+-} sh_xn_ni0_iilb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_iilb_cmp_enable1_u {
+       mmr_t   sh_xn_ni0_iilb_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_iilb_cmp_enable1_s;
+ } sh_xn_ni0_iilb_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_PI_CMP_EXP_DATA0"                 */
+ /*                 NI0 compare PI input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_pi_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni0_pi_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_pi_cmp_exp_data0_s;
+ } sh_xn_ni0_pi_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_pi_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni0_pi_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_pi_cmp_exp_data0_s;
+-} sh_xn_ni0_pi_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_PI_CMP_EXP_DATA1"                 */
+ /*                 NI0 compare PI input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_pi_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni0_pi_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_pi_cmp_exp_data1_s;
+-} sh_xn_ni0_pi_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_pi_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni0_pi_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_pi_cmp_exp_data1_s;
+ } sh_xn_ni0_pi_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_PI_CMP_ENABLE0"                  */
+ /*                     NI0 compare PI input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_pi_cmp_enable0_u {
+-      mmr_t   sh_xn_ni0_pi_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_pi_cmp_enable0_s;
+-} sh_xn_ni0_pi_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_pi_cmp_enable0_u {
+       mmr_t   sh_xn_ni0_pi_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_pi_cmp_enable0_s;
+ } sh_xn_ni0_pi_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_PI_CMP_ENABLE1"                  */
+ /*                     NI0 compare PI input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_pi_cmp_enable1_u {
+-      mmr_t   sh_xn_ni0_pi_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_pi_cmp_enable1_s;
+-} sh_xn_ni0_pi_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_pi_cmp_enable1_u {
+       mmr_t   sh_xn_ni0_pi_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_pi_cmp_enable1_s;
+ } sh_xn_ni0_pi_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_MD_CMP_EXP_DATA0"                 */
+ /*                 NI0 compare MD input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_md_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni0_md_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_md_cmp_exp_data0_s;
+ } sh_xn_ni0_md_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_md_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni0_md_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_md_cmp_exp_data0_s;
+-} sh_xn_ni0_md_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_MD_CMP_EXP_DATA1"                 */
+ /*                 NI0 compare MD input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_md_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni0_md_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_md_cmp_exp_data1_s;
+-} sh_xn_ni0_md_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_md_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni0_md_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_md_cmp_exp_data1_s;
+ } sh_xn_ni0_md_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_MD_CMP_ENABLE0"                  */
+ /*                     NI0 compare MD input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_md_cmp_enable0_u {
+-      mmr_t   sh_xn_ni0_md_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_md_cmp_enable0_s;
+-} sh_xn_ni0_md_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_md_cmp_enable0_u {
+       mmr_t   sh_xn_ni0_md_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_md_cmp_enable0_s;
+ } sh_xn_ni0_md_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_MD_CMP_ENABLE1"                  */
+ /*                     NI0 compare MD input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_md_cmp_enable1_u {
+-      mmr_t   sh_xn_ni0_md_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_md_cmp_enable1_s;
+-} sh_xn_ni0_md_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_md_cmp_enable1_u {
+       mmr_t   sh_xn_ni0_md_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_md_cmp_enable1_s;
+ } sh_xn_ni0_md_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_NI_CMP_EXP_DATA0"                 */
+ /*                 NI0 compare NI input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_ni_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni0_ni_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_ni_cmp_exp_data0_s;
+ } sh_xn_ni0_ni_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_ni_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni0_ni_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_ni_cmp_exp_data0_s;
+-} sh_xn_ni0_ni_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_NI_CMP_EXP_DATA1"                 */
+ /*                 NI0 compare NI input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_ni_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni0_ni_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_ni_cmp_exp_data1_s;
+-} sh_xn_ni0_ni_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_ni_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni0_ni_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_ni_cmp_exp_data1_s;
+ } sh_xn_ni0_ni_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_NI_CMP_ENABLE0"                  */
+ /*                     NI0 compare NI input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_ni_cmp_enable0_u {
+-      mmr_t   sh_xn_ni0_ni_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_ni_cmp_enable0_s;
+-} sh_xn_ni0_ni_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_ni_cmp_enable0_u {
+       mmr_t   sh_xn_ni0_ni_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_ni_cmp_enable0_s;
+ } sh_xn_ni0_ni_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_NI_CMP_ENABLE1"                  */
+ /*                     NI0 compare NI input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_ni_cmp_enable1_u {
+-      mmr_t   sh_xn_ni0_ni_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_ni_cmp_enable1_s;
+-} sh_xn_ni0_ni_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_ni_cmp_enable1_u {
+       mmr_t   sh_xn_ni0_ni_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_ni_cmp_enable1_s;
+ } sh_xn_ni0_ni_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_LLP_CMP_EXP_DATA0"                */
+ /*                 NI0 compare LLP input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni0_llp_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni0_llp_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_llp_cmp_exp_data0_s;
+ } sh_xn_ni0_llp_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni0_llp_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni0_llp_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_llp_cmp_exp_data0_s;
+-} sh_xn_ni0_llp_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI0_LLP_CMP_EXP_DATA1"                */
+ /*                 NI0 compare LLP input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_llp_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni0_llp_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni0_llp_cmp_exp_data1_s;
+-} sh_xn_ni0_llp_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni0_llp_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni0_llp_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni0_llp_cmp_exp_data1_s;
+ } sh_xn_ni0_llp_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_LLP_CMP_ENABLE0"                 */
+ /*                    NI0 compare LLP input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_llp_cmp_enable0_u {
+-      mmr_t   sh_xn_ni0_llp_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_llp_cmp_enable0_s;
+-} sh_xn_ni0_llp_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni0_llp_cmp_enable0_u {
+       mmr_t   sh_xn_ni0_llp_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_llp_cmp_enable0_s;
+ } sh_xn_ni0_llp_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI0_LLP_CMP_ENABLE1"                 */
+ /*                    NI0 compare LLP input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni0_llp_cmp_enable1_u {
+-      mmr_t   sh_xn_ni0_llp_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni0_llp_cmp_enable1_s;
+-} sh_xn_ni0_llp_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni0_llp_cmp_enable1_u {
+       mmr_t   sh_xn_ni0_llp_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni0_llp_cmp_enable1_s;
+ } sh_xn_ni0_llp_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_NI1_IILB_CMP_EXP_DATA0"                */
+ /*                NI1 compare IILB input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_iilb_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni1_iilb_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_iilb_cmp_exp_data0_s;
+ } sh_xn_ni1_iilb_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_iilb_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni1_iilb_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_iilb_cmp_exp_data0_s;
+-} sh_xn_ni1_iilb_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_XN_NI1_IILB_CMP_EXP_DATA1"                */
+ /*                NI1 compare IILB input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_iilb_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni1_iilb_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_iilb_cmp_exp_data1_s;
+-} sh_xn_ni1_iilb_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_iilb_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni1_iilb_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_iilb_cmp_exp_data1_s;
+ } sh_xn_ni1_iilb_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_IILB_CMP_ENABLE0"                 */
+ /*                    NI1 compare IILB input enable0                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_iilb_cmp_enable0_u {
+-      mmr_t   sh_xn_ni1_iilb_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_iilb_cmp_enable0_s;
+-} sh_xn_ni1_iilb_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_iilb_cmp_enable0_u {
+       mmr_t   sh_xn_ni1_iilb_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_iilb_cmp_enable0_s;
+ } sh_xn_ni1_iilb_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_IILB_CMP_ENABLE1"                 */
+ /*                    NI1 compare IILB input enable1                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_iilb_cmp_enable1_u {
+-      mmr_t   sh_xn_ni1_iilb_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_iilb_cmp_enable1_s;
+-} sh_xn_ni1_iilb_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_iilb_cmp_enable1_u {
+       mmr_t   sh_xn_ni1_iilb_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_iilb_cmp_enable1_s;
+ } sh_xn_ni1_iilb_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_PI_CMP_EXP_DATA0"                 */
+ /*                 NI1 compare PI input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_pi_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni1_pi_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_pi_cmp_exp_data0_s;
+ } sh_xn_ni1_pi_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_pi_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni1_pi_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_pi_cmp_exp_data0_s;
+-} sh_xn_ni1_pi_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_PI_CMP_EXP_DATA1"                 */
+ /*                 NI1 compare PI input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_pi_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni1_pi_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_pi_cmp_exp_data1_s;
+-} sh_xn_ni1_pi_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_pi_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni1_pi_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_pi_cmp_exp_data1_s;
+ } sh_xn_ni1_pi_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_PI_CMP_ENABLE0"                  */
+ /*                     NI1 compare PI input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_pi_cmp_enable0_u {
+-      mmr_t   sh_xn_ni1_pi_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_pi_cmp_enable0_s;
+-} sh_xn_ni1_pi_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_pi_cmp_enable0_u {
+       mmr_t   sh_xn_ni1_pi_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_pi_cmp_enable0_s;
+ } sh_xn_ni1_pi_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_PI_CMP_ENABLE1"                  */
+ /*                     NI1 compare PI input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_pi_cmp_enable1_u {
+-      mmr_t   sh_xn_ni1_pi_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_pi_cmp_enable1_s;
+-} sh_xn_ni1_pi_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_pi_cmp_enable1_u {
+       mmr_t   sh_xn_ni1_pi_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_pi_cmp_enable1_s;
+ } sh_xn_ni1_pi_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_MD_CMP_EXP_DATA0"                 */
+ /*                 NI1 compare MD input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_md_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni1_md_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_md_cmp_exp_data0_s;
+ } sh_xn_ni1_md_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_md_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni1_md_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_md_cmp_exp_data0_s;
+-} sh_xn_ni1_md_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_MD_CMP_EXP_DATA1"                 */
+ /*                 NI1 compare MD input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_md_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni1_md_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_md_cmp_exp_data1_s;
+-} sh_xn_ni1_md_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_md_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni1_md_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_md_cmp_exp_data1_s;
+ } sh_xn_ni1_md_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_MD_CMP_ENABLE0"                  */
+ /*                     NI1 compare MD input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_md_cmp_enable0_u {
+-      mmr_t   sh_xn_ni1_md_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_md_cmp_enable0_s;
+-} sh_xn_ni1_md_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_md_cmp_enable0_u {
+       mmr_t   sh_xn_ni1_md_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_md_cmp_enable0_s;
+ } sh_xn_ni1_md_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_MD_CMP_ENABLE1"                  */
+ /*                     NI1 compare MD input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_md_cmp_enable1_u {
+-      mmr_t   sh_xn_ni1_md_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_md_cmp_enable1_s;
+-} sh_xn_ni1_md_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_md_cmp_enable1_u {
+       mmr_t   sh_xn_ni1_md_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_md_cmp_enable1_s;
+ } sh_xn_ni1_md_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_NI_CMP_EXP_DATA0"                 */
+ /*                 NI1 compare NI input expected data0                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_ni_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni1_ni_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_ni_cmp_exp_data0_s;
+ } sh_xn_ni1_ni_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_ni_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni1_ni_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_ni_cmp_exp_data0_s;
+-} sh_xn_ni1_ni_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_NI_CMP_EXP_DATA1"                 */
+ /*                 NI1 compare NI input expected data1                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_ni_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni1_ni_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_ni_cmp_exp_data1_s;
+-} sh_xn_ni1_ni_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_ni_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni1_ni_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_ni_cmp_exp_data1_s;
+ } sh_xn_ni1_ni_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_NI_CMP_ENABLE0"                  */
+ /*                     NI1 compare NI input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_ni_cmp_enable0_u {
+-      mmr_t   sh_xn_ni1_ni_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_ni_cmp_enable0_s;
+-} sh_xn_ni1_ni_cmp_enable0_u_t;
+-#else
+ typedef union sh_xn_ni1_ni_cmp_enable0_u {
+       mmr_t   sh_xn_ni1_ni_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_ni_cmp_enable0_s;
+ } sh_xn_ni1_ni_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_NI_CMP_ENABLE1"                  */
+ /*                     NI1 compare NI input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_ni_cmp_enable1_u {
+-      mmr_t   sh_xn_ni1_ni_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_ni_cmp_enable1_s;
+-} sh_xn_ni1_ni_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_ni_cmp_enable1_u {
+       mmr_t   sh_xn_ni1_ni_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_ni_cmp_enable1_s;
+ } sh_xn_ni1_ni_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_LLP_CMP_EXP_DATA0"                */
+ /*                 NI1 compare LLP input expected data0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_llp_cmp_exp_data0_u {
+       mmr_t   sh_xn_ni1_llp_cmp_exp_data0_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_llp_cmp_exp_data0_s;
+ } sh_xn_ni1_llp_cmp_exp_data0_u_t;
+-#else
+-typedef union sh_xn_ni1_llp_cmp_exp_data0_u {
+-      mmr_t   sh_xn_ni1_llp_cmp_exp_data0_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_llp_cmp_exp_data0_s;
+-} sh_xn_ni1_llp_cmp_exp_data0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_NI1_LLP_CMP_EXP_DATA1"                */
+ /*                 NI1 compare LLP input expected data1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_llp_cmp_exp_data1_u {
+-      mmr_t   sh_xn_ni1_llp_cmp_exp_data1_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_ni1_llp_cmp_exp_data1_s;
+-} sh_xn_ni1_llp_cmp_exp_data1_u_t;
+-#else
+ typedef union sh_xn_ni1_llp_cmp_exp_data1_u {
+       mmr_t   sh_xn_ni1_llp_cmp_exp_data1_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_ni1_llp_cmp_exp_data1_s;
+ } sh_xn_ni1_llp_cmp_exp_data1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_LLP_CMP_ENABLE0"                 */
+ /*                    NI1 compare LLP input enable0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_ni1_llp_cmp_enable0_u {
+       mmr_t   sh_xn_ni1_llp_cmp_enable0_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_llp_cmp_enable0_s;
+ } sh_xn_ni1_llp_cmp_enable0_u_t;
+-#else
+-typedef union sh_xn_ni1_llp_cmp_enable0_u {
+-      mmr_t   sh_xn_ni1_llp_cmp_enable0_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_llp_cmp_enable0_s;
+-} sh_xn_ni1_llp_cmp_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_NI1_LLP_CMP_ENABLE1"                 */
+ /*                    NI1 compare LLP input enable1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_ni1_llp_cmp_enable1_u {
+-      mmr_t   sh_xn_ni1_llp_cmp_enable1_regval;
+-      struct {
+-              mmr_t   enable      : 64;
+-      } sh_xn_ni1_llp_cmp_enable1_s;
+-} sh_xn_ni1_llp_cmp_enable1_u_t;
+-#else
+ typedef union sh_xn_ni1_llp_cmp_enable1_u {
+       mmr_t   sh_xn_ni1_llp_cmp_enable1_regval;
+       struct {
+               mmr_t   enable      : 64;
+       } sh_xn_ni1_llp_cmp_enable1_s;
+ } sh_xn_ni1_llp_cmp_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNPI_ECC_INJ_REG"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_ecc_inj_reg_u {
+       mmr_t   sh_xnpi_ecc_inj_reg_regval;
+       struct {
+@@ -13182,123 +7173,55 @@
+               mmr_t   data_cb_cont3  : 1;
+       } sh_xnpi_ecc_inj_reg_s;
+ } sh_xnpi_ecc_inj_reg_u_t;
+-#else
+-typedef union sh_xnpi_ecc_inj_reg_u {
+-      mmr_t   sh_xnpi_ecc_inj_reg_regval;
+-      struct {
+-              mmr_t   data_cb_cont3  : 1;
+-              mmr_t   data_cb_1shot3 : 1;
+-              mmr_t   data_cont3     : 1;
+-              mmr_t   data_1shot3    : 1;
+-              mmr_t   reserved_3     : 4;
+-              mmr_t   byte3          : 8;
+-              mmr_t   data_cb_cont2  : 1;
+-              mmr_t   data_cb_1shot2 : 1;
+-              mmr_t   data_cont2     : 1;
+-              mmr_t   data_1shot2    : 1;
+-              mmr_t   reserved_2     : 4;
+-              mmr_t   byte2          : 8;
+-              mmr_t   data_cb_cont1  : 1;
+-              mmr_t   data_cb_1shot1 : 1;
+-              mmr_t   data_cont1     : 1;
+-              mmr_t   data_1shot1    : 1;
+-              mmr_t   reserved_1     : 4;
+-              mmr_t   byte1          : 8;
+-              mmr_t   data_cb_cont0  : 1;
+-              mmr_t   data_cb_1shot0 : 1;
+-              mmr_t   data_cont0     : 1;
+-              mmr_t   data_1shot0    : 1;
+-              mmr_t   reserved_0     : 4;
+-              mmr_t   byte0          : 8;
+-      } sh_xnpi_ecc_inj_reg_s;
+-} sh_xnpi_ecc_inj_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNPI_ECC0_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc0_inj_mask_reg_u {
+-      mmr_t   sh_xnpi_ecc0_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc0   : 64;
+-      } sh_xnpi_ecc0_inj_mask_reg_s;
+-} sh_xnpi_ecc0_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc0_inj_mask_reg_u {
+       mmr_t   sh_xnpi_ecc0_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc0   : 64;
+       } sh_xnpi_ecc0_inj_mask_reg_s;
+ } sh_xnpi_ecc0_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNPI_ECC1_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc1_inj_mask_reg_u {
+-      mmr_t   sh_xnpi_ecc1_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc1   : 64;
+-      } sh_xnpi_ecc1_inj_mask_reg_s;
+-} sh_xnpi_ecc1_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc1_inj_mask_reg_u {
+       mmr_t   sh_xnpi_ecc1_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc1   : 64;
+       } sh_xnpi_ecc1_inj_mask_reg_s;
+ } sh_xnpi_ecc1_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNPI_ECC2_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc2_inj_mask_reg_u {
+-      mmr_t   sh_xnpi_ecc2_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc2   : 64;
+-      } sh_xnpi_ecc2_inj_mask_reg_s;
+-} sh_xnpi_ecc2_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc2_inj_mask_reg_u {
+       mmr_t   sh_xnpi_ecc2_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc2   : 64;
+       } sh_xnpi_ecc2_inj_mask_reg_s;
+ } sh_xnpi_ecc2_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNPI_ECC3_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_ecc3_inj_mask_reg_u {
+-      mmr_t   sh_xnpi_ecc3_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc3   : 64;
+-      } sh_xnpi_ecc3_inj_mask_reg_s;
+-} sh_xnpi_ecc3_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnpi_ecc3_inj_mask_reg_u {
+       mmr_t   sh_xnpi_ecc3_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc3   : 64;
+       } sh_xnpi_ecc3_inj_mask_reg_s;
+ } sh_xnpi_ecc3_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNMD_ECC_INJ_REG"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_ecc_inj_reg_u {
+       mmr_t   sh_xnmd_ecc_inj_reg_regval;
+       struct {
+@@ -13328,123 +7251,55 @@
+               mmr_t   data_cb_cont3  : 1;
+       } sh_xnmd_ecc_inj_reg_s;
+ } sh_xnmd_ecc_inj_reg_u_t;
+-#else
+-typedef union sh_xnmd_ecc_inj_reg_u {
+-      mmr_t   sh_xnmd_ecc_inj_reg_regval;
+-      struct {
+-              mmr_t   data_cb_cont3  : 1;
+-              mmr_t   data_cb_1shot3 : 1;
+-              mmr_t   data_cont3     : 1;
+-              mmr_t   data_1shot3    : 1;
+-              mmr_t   reserved_3     : 4;
+-              mmr_t   byte3          : 8;
+-              mmr_t   data_cb_cont2  : 1;
+-              mmr_t   data_cb_1shot2 : 1;
+-              mmr_t   data_cont2     : 1;
+-              mmr_t   data_1shot2    : 1;
+-              mmr_t   reserved_2     : 4;
+-              mmr_t   byte2          : 8;
+-              mmr_t   data_cb_cont1  : 1;
+-              mmr_t   data_cb_1shot1 : 1;
+-              mmr_t   data_cont1     : 1;
+-              mmr_t   data_1shot1    : 1;
+-              mmr_t   reserved_1     : 4;
+-              mmr_t   byte1          : 8;
+-              mmr_t   data_cb_cont0  : 1;
+-              mmr_t   data_cb_1shot0 : 1;
+-              mmr_t   data_cont0     : 1;
+-              mmr_t   data_1shot0    : 1;
+-              mmr_t   reserved_0     : 4;
+-              mmr_t   byte0          : 8;
+-      } sh_xnmd_ecc_inj_reg_s;
+-} sh_xnmd_ecc_inj_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNMD_ECC0_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_ecc0_inj_mask_reg_u {
+-      mmr_t   sh_xnmd_ecc0_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc0   : 64;
+-      } sh_xnmd_ecc0_inj_mask_reg_s;
+-} sh_xnmd_ecc0_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnmd_ecc0_inj_mask_reg_u {
+       mmr_t   sh_xnmd_ecc0_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc0   : 64;
+       } sh_xnmd_ecc0_inj_mask_reg_s;
+ } sh_xnmd_ecc0_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNMD_ECC1_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_ecc1_inj_mask_reg_u {
+       mmr_t   sh_xnmd_ecc1_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc1   : 64;
+       } sh_xnmd_ecc1_inj_mask_reg_s;
+ } sh_xnmd_ecc1_inj_mask_reg_u_t;
+-#else
+-typedef union sh_xnmd_ecc1_inj_mask_reg_u {
+-      mmr_t   sh_xnmd_ecc1_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc1   : 64;
+-      } sh_xnmd_ecc1_inj_mask_reg_s;
+-} sh_xnmd_ecc1_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNMD_ECC2_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_ecc2_inj_mask_reg_u {
+-      mmr_t   sh_xnmd_ecc2_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc2   : 64;
+-      } sh_xnmd_ecc2_inj_mask_reg_s;
+-} sh_xnmd_ecc2_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnmd_ecc2_inj_mask_reg_u {
+       mmr_t   sh_xnmd_ecc2_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc2   : 64;
+       } sh_xnmd_ecc2_inj_mask_reg_s;
+ } sh_xnmd_ecc2_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNMD_ECC3_INJ_MASK_REG"                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_ecc3_inj_mask_reg_u {
+-      mmr_t   sh_xnmd_ecc3_inj_mask_reg_regval;
+-      struct {
+-              mmr_t   mask_ecc3   : 64;
+-      } sh_xnmd_ecc3_inj_mask_reg_s;
+-} sh_xnmd_ecc3_inj_mask_reg_u_t;
+-#else
+ typedef union sh_xnmd_ecc3_inj_mask_reg_u {
+       mmr_t   sh_xnmd_ecc3_inj_mask_reg_regval;
+       struct {
+               mmr_t   mask_ecc3   : 64;
+       } sh_xnmd_ecc3_inj_mask_reg_s;
+ } sh_xnmd_ecc3_inj_mask_reg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNMD_ECC_ERR_REPORT"                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_ecc_err_report_u {
+       mmr_t   sh_xnmd_ecc_err_report_regval;
+       struct {
+@@ -13458,28 +7313,12 @@
+               mmr_t   reserved_3   : 15;
+       } sh_xnmd_ecc_err_report_s;
+ } sh_xnmd_ecc_err_report_u_t;
+-#else
+-typedef union sh_xnmd_ecc_err_report_u {
+-      mmr_t   sh_xnmd_ecc_err_report_regval;
+-      struct {
+-              mmr_t   reserved_3   : 15;
+-              mmr_t   ecc_disable3 : 1;
+-              mmr_t   reserved_2   : 15;
+-              mmr_t   ecc_disable2 : 1;
+-              mmr_t   reserved_1   : 15;
+-              mmr_t   ecc_disable1 : 1;
+-              mmr_t   reserved_0   : 15;
+-              mmr_t   ecc_disable0 : 1;
+-      } sh_xnmd_ecc_err_report_s;
+-} sh_xnmd_ecc_err_report_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI0_ERROR_SUMMARY_1"                   */
+ /*                       ni0  Error Summary Bits                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_summary_1_u {
+       mmr_t   sh_ni0_error_summary_1_regval;
+       struct {
+@@ -13549,84 +7388,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni0_error_summary_1_s;
+ } sh_ni0_error_summary_1_u_t;
+-#else
+-typedef union sh_ni0_error_summary_1_u {
+-      mmr_t   sh_ni0_error_summary_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni0_error_summary_1_s;
+-} sh_ni0_error_summary_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI0_ERROR_SUMMARY_2"                   */
+ /*                       ni0  Error Summary Bits                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_summary_2_u {
+       mmr_t   sh_ni0_error_summary_2_regval;
+       struct {
+@@ -13687,75 +7454,12 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni0_error_summary_2_s;
+ } sh_ni0_error_summary_2_u_t;
+-#else
+-typedef union sh_ni0_error_summary_2_u {
+-      mmr_t   sh_ni0_error_summary_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni0_error_summary_2_s;
+-} sh_ni0_error_summary_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI0_ERROR_OVERFLOW_1"                  */
+ /*                       ni0  Error Overflow Bits                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_overflow_1_u {
+       mmr_t   sh_ni0_error_overflow_1_regval;
+       struct {
+@@ -13825,84 +7529,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni0_error_overflow_1_s;
+ } sh_ni0_error_overflow_1_u_t;
+-#else
+-typedef union sh_ni0_error_overflow_1_u {
+-      mmr_t   sh_ni0_error_overflow_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni0_error_overflow_1_s;
+-} sh_ni0_error_overflow_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI0_ERROR_OVERFLOW_2"                  */
+ /*                       ni0  Error Overflow Bits                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_overflow_2_u {
+       mmr_t   sh_ni0_error_overflow_2_regval;
+       struct {
+@@ -13963,75 +7595,12 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni0_error_overflow_2_s;
+ } sh_ni0_error_overflow_2_u_t;
+-#else
+-typedef union sh_ni0_error_overflow_2_u {
+-      mmr_t   sh_ni0_error_overflow_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni0_error_overflow_2_s;
+-} sh_ni0_error_overflow_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_ERROR_MASK_1"                    */
+ /*                         ni0  Error Mask Bits                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_mask_1_u {
+       mmr_t   sh_ni0_error_mask_1_regval;
+       struct {
+@@ -14101,84 +7670,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni0_error_mask_1_s;
+ } sh_ni0_error_mask_1_u_t;
+-#else
+-typedef union sh_ni0_error_mask_1_u {
+-      mmr_t   sh_ni0_error_mask_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni0_error_mask_1_s;
+-} sh_ni0_error_mask_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI0_ERROR_MASK_2"                    */
+ /*                         ni0  Error Mask Bits                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_mask_2_u {
+       mmr_t   sh_ni0_error_mask_2_regval;
+       struct {
+@@ -14239,77 +7736,14 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni0_error_mask_2_s;
+ } sh_ni0_error_mask_2_u_t;
+-#else
+-typedef union sh_ni0_error_mask_2_u {
+-      mmr_t   sh_ni0_error_mask_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni0_error_mask_2_s;
+-} sh_ni0_error_mask_2_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                   Register "SH_NI0_FIRST_ERROR_1"                    */
+-/*                        ni0  First Error Bits                         */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_first_error_1_u {
+-      mmr_t   sh_ni0_first_error_1_regval;
++
++/* ==================================================================== */
++/*                   Register "SH_NI0_FIRST_ERROR_1"                    */
++/*                        ni0  First Error Bits                         */
++/* ==================================================================== */
++
++typedef union sh_ni0_first_error_1_u {
++      mmr_t   sh_ni0_first_error_1_regval;
+       struct {
+               mmr_t   overflow_fifo02_debit0        : 1;
+               mmr_t   overflow_fifo02_debit2        : 1;
+@@ -14377,84 +7811,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni0_first_error_1_s;
+ } sh_ni0_first_error_1_u_t;
+-#else
+-typedef union sh_ni0_first_error_1_u {
+-      mmr_t   sh_ni0_first_error_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni0_first_error_1_s;
+-} sh_ni0_first_error_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI0_FIRST_ERROR_2"                    */
+ /*                         ni0 First Error Bits                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_first_error_2_u {
+       mmr_t   sh_ni0_first_error_2_regval;
+       struct {
+@@ -14515,117 +7877,36 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni0_first_error_2_s;
+ } sh_ni0_first_error_2_u_t;
+-#else
+-typedef union sh_ni0_first_error_2_u {
+-      mmr_t   sh_ni0_first_error_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni0_first_error_2_s;
+-} sh_ni0_first_error_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI0_ERROR_DETAIL_1"                   */
+ /*                ni0 Chiplet no match header bits 63:0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_error_detail_1_u {
+-      mmr_t   sh_ni0_error_detail_1_regval;
+-      struct {
+-              mmr_t   header      : 64;
+-      } sh_ni0_error_detail_1_s;
+-} sh_ni0_error_detail_1_u_t;
+-#else
+ typedef union sh_ni0_error_detail_1_u {
+       mmr_t   sh_ni0_error_detail_1_regval;
+       struct {
+               mmr_t   header      : 64;
+       } sh_ni0_error_detail_1_s;
+ } sh_ni0_error_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI0_ERROR_DETAIL_2"                   */
+ /*               ni0 Chiplet no match header bits 127:64                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni0_error_detail_2_u {
+-      mmr_t   sh_ni0_error_detail_2_regval;
+-      struct {
+-              mmr_t   header      : 64;
+-      } sh_ni0_error_detail_2_s;
+-} sh_ni0_error_detail_2_u_t;
+-#else
+ typedef union sh_ni0_error_detail_2_u {
+       mmr_t   sh_ni0_error_detail_2_regval;
+       struct {
+               mmr_t   header      : 64;
+       } sh_ni0_error_detail_2_s;
+ } sh_ni0_error_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI1_ERROR_SUMMARY_1"                   */
+ /*                       ni1  Error Summary Bits                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_summary_1_u {
+       mmr_t   sh_ni1_error_summary_1_regval;
+       struct {
+@@ -14695,84 +7976,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni1_error_summary_1_s;
+ } sh_ni1_error_summary_1_u_t;
+-#else
+-typedef union sh_ni1_error_summary_1_u {
+-      mmr_t   sh_ni1_error_summary_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni1_error_summary_1_s;
+-} sh_ni1_error_summary_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI1_ERROR_SUMMARY_2"                   */
+ /*                       ni1  Error Summary Bits                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_summary_2_u {
+       mmr_t   sh_ni1_error_summary_2_regval;
+       struct {
+@@ -14833,77 +8042,14 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni1_error_summary_2_s;
+ } sh_ni1_error_summary_2_u_t;
+-#else
+-typedef union sh_ni1_error_summary_2_u {
+-      mmr_t   sh_ni1_error_summary_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni1_error_summary_2_s;
+-} sh_ni1_error_summary_2_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                  Register "SH_NI1_ERROR_OVERFLOW_1"                  */
+-/*                       ni1  Error Overflow Bits                       */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_error_overflow_1_u {
+-      mmr_t   sh_ni1_error_overflow_1_regval;
++
++/* ==================================================================== */
++/*                  Register "SH_NI1_ERROR_OVERFLOW_1"                  */
++/*                       ni1  Error Overflow Bits                       */
++/* ==================================================================== */
++
++typedef union sh_ni1_error_overflow_1_u {
++      mmr_t   sh_ni1_error_overflow_1_regval;
+       struct {
+               mmr_t   overflow_fifo02_debit0        : 1;
+               mmr_t   overflow_fifo02_debit2        : 1;
+@@ -14971,84 +8117,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni1_error_overflow_1_s;
+ } sh_ni1_error_overflow_1_u_t;
+-#else
+-typedef union sh_ni1_error_overflow_1_u {
+-      mmr_t   sh_ni1_error_overflow_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni1_error_overflow_1_s;
+-} sh_ni1_error_overflow_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_NI1_ERROR_OVERFLOW_2"                  */
+ /*                       ni1  Error Overflow Bits                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_overflow_2_u {
+       mmr_t   sh_ni1_error_overflow_2_regval;
+       struct {
+@@ -15109,75 +8183,12 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni1_error_overflow_2_s;
+ } sh_ni1_error_overflow_2_u_t;
+-#else
+-typedef union sh_ni1_error_overflow_2_u {
+-      mmr_t   sh_ni1_error_overflow_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni1_error_overflow_2_s;
+-} sh_ni1_error_overflow_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_ERROR_MASK_1"                    */
+ /*                         ni1  Error Mask Bits                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_mask_1_u {
+       mmr_t   sh_ni1_error_mask_1_regval;
+       struct {
+@@ -15247,84 +8258,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni1_error_mask_1_s;
+ } sh_ni1_error_mask_1_u_t;
+-#else
+-typedef union sh_ni1_error_mask_1_u {
+-      mmr_t   sh_ni1_error_mask_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni1_error_mask_1_s;
+-} sh_ni1_error_mask_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_NI1_ERROR_MASK_2"                    */
+ /*                         ni1  Error Mask Bits                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_mask_2_u {
+       mmr_t   sh_ni1_error_mask_2_regval;
+       struct {
+@@ -15385,77 +8324,14 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni1_error_mask_2_s;
+ } sh_ni1_error_mask_2_u_t;
+-#else
+-typedef union sh_ni1_error_mask_2_u {
+-      mmr_t   sh_ni1_error_mask_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni1_error_mask_2_s;
+-} sh_ni1_error_mask_2_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                   Register "SH_NI1_FIRST_ERROR_1"                    */
+-/*                        ni1  First Error Bits                         */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_first_error_1_u {
+-      mmr_t   sh_ni1_first_error_1_regval;
++
++/* ==================================================================== */
++/*                   Register "SH_NI1_FIRST_ERROR_1"                    */
++/*                        ni1  First Error Bits                         */
++/* ==================================================================== */
++
++typedef union sh_ni1_first_error_1_u {
++      mmr_t   sh_ni1_first_error_1_regval;
+       struct {
+               mmr_t   overflow_fifo02_debit0        : 1;
+               mmr_t   overflow_fifo02_debit2        : 1;
+@@ -15523,84 +8399,12 @@
+               mmr_t   tail_timeout_ni_vc3           : 1;
+       } sh_ni1_first_error_1_s;
+ } sh_ni1_first_error_1_u_t;
+-#else
+-typedef union sh_ni1_first_error_1_u {
+-      mmr_t   sh_ni1_first_error_1_regval;
+-      struct {
+-              mmr_t   tail_timeout_ni_vc3           : 1;
+-              mmr_t   tail_timeout_ni_vc2           : 1;
+-              mmr_t   tail_timeout_ni_vc1           : 1;
+-              mmr_t   tail_timeout_ni_vc0           : 1;
+-              mmr_t   tail_timeout_fifo13_vc3       : 1;
+-              mmr_t   tail_timeout_fifo13_vc1       : 1;
+-              mmr_t   tail_timeout_fifo02_vc2       : 1;
+-              mmr_t   tail_timeout_fifo02_vc0       : 1;
+-              mmr_t   overflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   overflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   overflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   overflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   overflow_md_fifo_vc2_push     : 1;
+-              mmr_t   overflow_md_fifo_vc0_push     : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   overflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   overflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   overflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   overflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   overflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   overflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   overflow_ni_fifo_debit3       : 1;
+-              mmr_t   overflow_ni_fifo_debit2       : 1;
+-              mmr_t   overflow_ni_fifo_debit1       : 1;
+-              mmr_t   overflow_ni_fifo_debit0       : 1;
+-              mmr_t   overflow_md_fifo_debit2       : 1;
+-              mmr_t   overflow_md_fifo_debit0       : 1;
+-              mmr_t   overflow_iilb_fifo_debit2     : 1;
+-              mmr_t   overflow_iilb_fifo_debit0     : 1;
+-              mmr_t   overflow_pi_fifo_debit2       : 1;
+-              mmr_t   overflow_pi_fifo_debit0       : 1;
+-              mmr_t   overflow2_vc2_credit          : 1;
+-              mmr_t   overflow1_vc2_credit          : 1;
+-              mmr_t   overflow0_vc2_credit          : 1;
+-              mmr_t   overflow2_vc0_credit          : 1;
+-              mmr_t   overflow1_vc0_credit          : 1;
+-              mmr_t   overflow0_vc0_credit          : 1;
+-              mmr_t   overflow_fifo13_vc2_credit    : 1;
+-              mmr_t   overflow_fifo13_vc0_credit    : 1;
+-              mmr_t   overflow_fifo02_vc2_credit    : 1;
+-              mmr_t   overflow_fifo02_vc0_credit    : 1;
+-              mmr_t   overflow_fifo13_vc3_push      : 1;
+-              mmr_t   overflow_fifo13_vc1_push      : 1;
+-              mmr_t   overflow_fifo02_vc2_push      : 1;
+-              mmr_t   overflow_fifo02_vc0_push      : 1;
+-              mmr_t   overflow_fifo13_vc3_pop       : 1;
+-              mmr_t   overflow_fifo13_vc1_pop       : 1;
+-              mmr_t   overflow_fifo02_vc2_pop       : 1;
+-              mmr_t   overflow_fifo02_vc0_pop       : 1;
+-              mmr_t   overflow_fifo13_debit2        : 1;
+-              mmr_t   overflow_fifo13_debit0        : 1;
+-              mmr_t   overflow_fifo02_debit2        : 1;
+-              mmr_t   overflow_fifo02_debit0        : 1;
+-      } sh_ni1_first_error_1_s;
+-} sh_ni1_first_error_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI1_FIRST_ERROR_2"                    */
+ /*                         ni1 First Error Bits                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_first_error_2_u {
+       mmr_t   sh_ni1_first_error_2_regval;
+       struct {
+@@ -15661,117 +8465,36 @@
+               mmr_t   reserved_1                     : 1;
+       } sh_ni1_first_error_2_s;
+ } sh_ni1_first_error_2_u_t;
+-#else
+-typedef union sh_ni1_first_error_2_u {
+-      mmr_t   sh_ni1_first_error_2_regval;
+-      struct {
+-              mmr_t   reserved_1                     : 1;
+-              mmr_t   retry_timeout_error            : 1;
+-              mmr_t   lut_read_error                 : 1;
+-              mmr_t   chiplet_nomatch                : 1;
+-              mmr_t   llp_deadlock_vc3               : 1;
+-              mmr_t   llp_deadlock_vc2               : 1;
+-              mmr_t   llp_deadlock_vc1               : 1;
+-              mmr_t   llp_deadlock_vc0               : 1;
+-              mmr_t   underflow_ni_fifo_vc3_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc1_credit   : 1;
+-              mmr_t   underflow_ni_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_credit : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_credit : 1;
+-              mmr_t   underflow_pi_fifo_vc2_credit   : 1;
+-              mmr_t   underflow_pi_fifo_vc0_credit   : 1;
+-              mmr_t   underflow_md_fifo_vc2_push     : 1;
+-              mmr_t   underflow_md_fifo_vc0_push     : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_push   : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_push   : 1;
+-              mmr_t   underflow_pi_fifo_vc2_push     : 1;
+-              mmr_t   underflow_pi_fifo_vc0_push     : 1;
+-              mmr_t   underflow_ni_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_ni_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_md_fifo_vc0_pop      : 1;
+-              mmr_t   underflow_iilb_fifo_vc2_pop    : 1;
+-              mmr_t   underflow_iilb_fifo_vc0_pop    : 1;
+-              mmr_t   underflow_pi_fifo_vc2_pop      : 1;
+-              mmr_t   underflow_pi_fifo_vc0_pop      : 1;
+-              mmr_t   reserved_0                     : 10;
+-              mmr_t   underflow2_vc2_credit          : 1;
+-              mmr_t   underflow1_vc2_credit          : 1;
+-              mmr_t   underflow0_vc2_credit          : 1;
+-              mmr_t   underflow2_vc0_credit          : 1;
+-              mmr_t   underflow1_vc0_credit          : 1;
+-              mmr_t   underflow0_vc0_credit          : 1;
+-              mmr_t   underflow_fifo13_vc2_credit    : 1;
+-              mmr_t   underflow_fifo13_vc0_credit    : 1;
+-              mmr_t   underflow_fifo02_vc2_credit    : 1;
+-              mmr_t   underflow_fifo02_vc0_credit    : 1;
+-              mmr_t   underflow_fifo13_vc3_push      : 1;
+-              mmr_t   underflow_fifo13_vc1_push      : 1;
+-              mmr_t   underflow_fifo02_vc2_push      : 1;
+-              mmr_t   underflow_fifo02_vc0_push      : 1;
+-              mmr_t   underflow_fifo13_vc3_pop       : 1;
+-              mmr_t   underflow_fifo13_vc1_pop       : 1;
+-              mmr_t   underflow_fifo02_vc2_pop       : 1;
+-              mmr_t   underflow_fifo02_vc0_pop       : 1;
+-              mmr_t   illegal_vciilb                 : 1;
+-              mmr_t   illegal_vcmd                   : 1;
+-              mmr_t   illegal_vcpi                   : 1;
+-              mmr_t   illegal_vcni                   : 1;
+-      } sh_ni1_first_error_2_s;
+-} sh_ni1_first_error_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI1_ERROR_DETAIL_1"                   */
+ /*                ni1 Chiplet no match header bits 63:0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_error_detail_1_u {
+-      mmr_t   sh_ni1_error_detail_1_regval;
+-      struct {
+-              mmr_t   header      : 64;
+-      } sh_ni1_error_detail_1_s;
+-} sh_ni1_error_detail_1_u_t;
+-#else
+ typedef union sh_ni1_error_detail_1_u {
+       mmr_t   sh_ni1_error_detail_1_regval;
+       struct {
+               mmr_t   header      : 64;
+       } sh_ni1_error_detail_1_s;
+ } sh_ni1_error_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI1_ERROR_DETAIL_2"                   */
+ /*               ni1 Chiplet no match header bits 127:64                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ni1_error_detail_2_u {
+-      mmr_t   sh_ni1_error_detail_2_regval;
+-      struct {
+-              mmr_t   header      : 64;
+-      } sh_ni1_error_detail_2_s;
+-} sh_ni1_error_detail_2_u_t;
+-#else
+ typedef union sh_ni1_error_detail_2_u {
+       mmr_t   sh_ni1_error_detail_2_regval;
+       struct {
+               mmr_t   header      : 64;
+       } sh_ni1_error_detail_2_s;
+ } sh_ni1_error_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_CORRECTED_DETAIL_1"                  */
+ /*                       Corrected error details                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_corrected_detail_1_u {
+       mmr_t   sh_xn_corrected_detail_1_regval;
+       struct {
+@@ -15793,78 +8516,36 @@
+               mmr_t   reserved_3    : 4;
+       } sh_xn_corrected_detail_1_s;
+ } sh_xn_corrected_detail_1_u_t;
+-#else
+-typedef union sh_xn_corrected_detail_1_u {
+-      mmr_t   sh_xn_corrected_detail_1_regval;
+-      struct {
+-              mmr_t   reserved_3    : 4;
+-              mmr_t   ecc3_vc       : 2;
+-              mmr_t   ecc3_wc       : 2;
+-              mmr_t   ecc3_syndrome : 8;
+-              mmr_t   reserved_2    : 4;
+-              mmr_t   ecc2_vc       : 2;
+-              mmr_t   ecc2_wc       : 2;
+-              mmr_t   ecc2_syndrome : 8;
+-              mmr_t   reserved_1    : 4;
+-              mmr_t   ecc1_vc       : 2;
+-              mmr_t   ecc1_wc       : 2;
+-              mmr_t   ecc1_syndrome : 8;
+-              mmr_t   reserved_0    : 4;
+-              mmr_t   ecc0_vc       : 2;
+-              mmr_t   ecc0_wc       : 2;
+-              mmr_t   ecc0_syndrome : 8;
+-      } sh_xn_corrected_detail_1_s;
+-} sh_xn_corrected_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_CORRECTED_DETAIL_2"                  */
+ /*                         Corrected error data                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_corrected_detail_2_u {
+-      mmr_t   sh_xn_corrected_detail_2_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_corrected_detail_2_s;
+-} sh_xn_corrected_detail_2_u_t;
+-#else
+ typedef union sh_xn_corrected_detail_2_u {
+       mmr_t   sh_xn_corrected_detail_2_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_corrected_detail_2_s;
+ } sh_xn_corrected_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_CORRECTED_DETAIL_3"                  */
+ /*                       Corrected error header0                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_corrected_detail_3_u {
+-      mmr_t   sh_xn_corrected_detail_3_regval;
+-      struct {
+-              mmr_t   header0     : 64;
+-      } sh_xn_corrected_detail_3_s;
+-} sh_xn_corrected_detail_3_u_t;
+-#else
+ typedef union sh_xn_corrected_detail_3_u {
+       mmr_t   sh_xn_corrected_detail_3_regval;
+       struct {
+               mmr_t   header0     : 64;
+       } sh_xn_corrected_detail_3_s;
+ } sh_xn_corrected_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XN_CORRECTED_DETAIL_4"                  */
+ /*                       Corrected error header1                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_corrected_detail_4_u {
+       mmr_t   sh_xn_corrected_detail_4_regval;
+       struct {
+@@ -15873,23 +8554,12 @@
+               mmr_t   err_group   : 2;
+       } sh_xn_corrected_detail_4_s;
+ } sh_xn_corrected_detail_4_u_t;
+-#else
+-typedef union sh_xn_corrected_detail_4_u {
+-      mmr_t   sh_xn_corrected_detail_4_regval;
+-      struct {
+-              mmr_t   err_group   : 2;
+-              mmr_t   reserved_0  : 20;
+-              mmr_t   header1     : 42;
+-      } sh_xn_corrected_detail_4_s;
+-} sh_xn_corrected_detail_4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_UNCORRECTED_DETAIL_1"                 */
+ /*                      Uncorrected error details                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_uncorrected_detail_1_u {
+       mmr_t   sh_xn_uncorrected_detail_1_regval;
+       struct {
+@@ -15911,78 +8581,36 @@
+               mmr_t   reserved_3    : 4;
+       } sh_xn_uncorrected_detail_1_s;
+ } sh_xn_uncorrected_detail_1_u_t;
+-#else
+-typedef union sh_xn_uncorrected_detail_1_u {
+-      mmr_t   sh_xn_uncorrected_detail_1_regval;
+-      struct {
+-              mmr_t   reserved_3    : 4;
+-              mmr_t   ecc3_vc       : 2;
+-              mmr_t   ecc3_wc       : 2;
+-              mmr_t   ecc3_syndrome : 8;
+-              mmr_t   reserved_2    : 4;
+-              mmr_t   ecc2_vc       : 2;
+-              mmr_t   ecc2_wc       : 2;
+-              mmr_t   ecc2_syndrome : 8;
+-              mmr_t   reserved_1    : 4;
+-              mmr_t   ecc1_vc       : 2;
+-              mmr_t   ecc1_wc       : 2;
+-              mmr_t   ecc1_syndrome : 8;
+-              mmr_t   reserved_0    : 4;
+-              mmr_t   ecc0_vc       : 2;
+-              mmr_t   ecc0_wc       : 2;
+-              mmr_t   ecc0_syndrome : 8;
+-      } sh_xn_uncorrected_detail_1_s;
+-} sh_xn_uncorrected_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_UNCORRECTED_DETAIL_2"                 */
+ /*                        Uncorrected error data                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_uncorrected_detail_2_u {
+-      mmr_t   sh_xn_uncorrected_detail_2_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_xn_uncorrected_detail_2_s;
+-} sh_xn_uncorrected_detail_2_u_t;
+-#else
+ typedef union sh_xn_uncorrected_detail_2_u {
+       mmr_t   sh_xn_uncorrected_detail_2_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_xn_uncorrected_detail_2_s;
+ } sh_xn_uncorrected_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_UNCORRECTED_DETAIL_3"                 */
+ /*                      Uncorrected error header0                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xn_uncorrected_detail_3_u {
+-      mmr_t   sh_xn_uncorrected_detail_3_regval;
+-      struct {
+-              mmr_t   header0     : 64;
+-      } sh_xn_uncorrected_detail_3_s;
+-} sh_xn_uncorrected_detail_3_u_t;
+-#else
+ typedef union sh_xn_uncorrected_detail_3_u {
+       mmr_t   sh_xn_uncorrected_detail_3_regval;
+       struct {
+               mmr_t   header0     : 64;
+       } sh_xn_uncorrected_detail_3_s;
+ } sh_xn_uncorrected_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_XN_UNCORRECTED_DETAIL_4"                 */
+ /*                      Uncorrected error header1                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_uncorrected_detail_4_u {
+       mmr_t   sh_xn_uncorrected_detail_4_regval;
+       struct {
+@@ -15991,23 +8619,12 @@
+               mmr_t   err_group   : 2;
+       } sh_xn_uncorrected_detail_4_s;
+ } sh_xn_uncorrected_detail_4_u_t;
+-#else
+-typedef union sh_xn_uncorrected_detail_4_u {
+-      mmr_t   sh_xn_uncorrected_detail_4_regval;
+-      struct {
+-              mmr_t   err_group   : 2;
+-              mmr_t   reserved_0  : 20;
+-              mmr_t   header1     : 42;
+-      } sh_xn_uncorrected_detail_4_s;
+-} sh_xn_uncorrected_detail_4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNMD_ERROR_DETAIL_1"                   */
+ /*                      Look Up Table Address (md)                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_error_detail_1_u {
+       mmr_t   sh_xnmd_error_detail_1_regval;
+       struct {
+@@ -16015,22 +8632,12 @@
+               mmr_t   reserved_0  : 53;
+       } sh_xnmd_error_detail_1_s;
+ } sh_xnmd_error_detail_1_u_t;
+-#else
+-typedef union sh_xnmd_error_detail_1_u {
+-      mmr_t   sh_xnmd_error_detail_1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 53;
+-              mmr_t   lut_addr    : 11;
+-      } sh_xnmd_error_detail_1_s;
+-} sh_xnmd_error_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNPI_ERROR_DETAIL_1"                   */
+ /*                      Look Up Table Address (pi)                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_error_detail_1_u {
+       mmr_t   sh_xnpi_error_detail_1_regval;
+       struct {
+@@ -16038,64 +8645,36 @@
+               mmr_t   reserved_0  : 53;
+       } sh_xnpi_error_detail_1_s;
+ } sh_xnpi_error_detail_1_u_t;
+-#else
+-typedef union sh_xnpi_error_detail_1_u {
+-      mmr_t   sh_xnpi_error_detail_1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 53;
+-              mmr_t   lut_addr    : 11;
+-      } sh_xnpi_error_detail_1_s;
+-} sh_xnpi_error_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNIILB_ERROR_DETAIL_1"                  */
+ /*                    Chiplet NoMatch header [63:0]                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xniilb_error_detail_1_u {
+-      mmr_t   sh_xniilb_error_detail_1_regval;
+-      struct {
+-              mmr_t   header      : 64;
+-      } sh_xniilb_error_detail_1_s;
+-} sh_xniilb_error_detail_1_u_t;
+-#else
+ typedef union sh_xniilb_error_detail_1_u {
+       mmr_t   sh_xniilb_error_detail_1_regval;
+       struct {
+               mmr_t   header      : 64;
+       } sh_xniilb_error_detail_1_s;
+ } sh_xniilb_error_detail_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNIILB_ERROR_DETAIL_2"                  */
+ /*                   Chiplet NoMatch header [127:64]                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xniilb_error_detail_2_u {
+-      mmr_t   sh_xniilb_error_detail_2_regval;
+-      struct {
+-              mmr_t   header      : 64;
+-      } sh_xniilb_error_detail_2_s;
+-} sh_xniilb_error_detail_2_u_t;
+-#else
+ typedef union sh_xniilb_error_detail_2_u {
+       mmr_t   sh_xniilb_error_detail_2_regval;
+       struct {
+               mmr_t   header      : 64;
+       } sh_xniilb_error_detail_2_s;
+ } sh_xniilb_error_detail_2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNIILB_ERROR_DETAIL_3"                  */
+ /*                     Look Up Table Address (iilb)                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_detail_3_u {
+       mmr_t   sh_xniilb_error_detail_3_regval;
+       struct {
+@@ -16103,22 +8682,12 @@
+               mmr_t   reserved_0  : 53;
+       } sh_xniilb_error_detail_3_s;
+ } sh_xniilb_error_detail_3_u_t;
+-#else
+-typedef union sh_xniilb_error_detail_3_u {
+-      mmr_t   sh_xniilb_error_detail_3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 53;
+-              mmr_t   lut_addr    : 11;
+-      } sh_xniilb_error_detail_3_s;
+-} sh_xniilb_error_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI0_ERROR_DETAIL_3"                   */
+ /*                     Look Up Table Address (ni0)                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni0_error_detail_3_u {
+       mmr_t   sh_ni0_error_detail_3_regval;
+       struct {
+@@ -16126,22 +8695,12 @@
+               mmr_t   reserved_0  : 53;
+       } sh_ni0_error_detail_3_s;
+ } sh_ni0_error_detail_3_u_t;
+-#else
+-typedef union sh_ni0_error_detail_3_u {
+-      mmr_t   sh_ni0_error_detail_3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 53;
+-              mmr_t   lut_addr    : 11;
+-      } sh_ni0_error_detail_3_s;
+-} sh_ni0_error_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_NI1_ERROR_DETAIL_3"                   */
+ /*                     Look Up Table Address (ni1)                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ni1_error_detail_3_u {
+       mmr_t   sh_ni1_error_detail_3_regval;
+       struct {
+@@ -16149,21 +8708,11 @@
+               mmr_t   reserved_0  : 53;
+       } sh_ni1_error_detail_3_s;
+ } sh_ni1_error_detail_3_u_t;
+-#else
+-typedef union sh_ni1_error_detail_3_u {
+-      mmr_t   sh_ni1_error_detail_3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 53;
+-              mmr_t   lut_addr    : 11;
+-      } sh_ni1_error_detail_3_s;
+-} sh_ni1_error_detail_3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_ERROR_SUMMARY"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_error_summary_u {
+       mmr_t   sh_xn_error_summary_regval;
+       struct {
+@@ -16208,58 +8757,11 @@
+               mmr_t   reserved_0              : 26;
+       } sh_xn_error_summary_s;
+ } sh_xn_error_summary_u_t;
+-#else
+-typedef union sh_xn_error_summary_u {
+-      mmr_t   sh_xn_error_summary_regval;
+-      struct {
+-              mmr_t   reserved_0              : 26;
+-              mmr_t   iilb_chiplet_or_lut     : 1;
+-              mmr_t   iilb_fifo_underflow     : 1;
+-              mmr_t   iilb_credit_underflow   : 1;
+-              mmr_t   iilb_fifo_overflow      : 1;
+-              mmr_t   iilb_credit_overflow    : 1;
+-              mmr_t   iilb_debit_overflow     : 1;
+-              mmr_t   xnpi_lut_error          : 1;
+-              mmr_t   xnpi_uce_error          : 1;
+-              mmr_t   xnpi_sbe_error          : 1;
+-              mmr_t   xnpi_credit_underflow   : 1;
+-              mmr_t   xnpi_data_buff_overflow : 1;
+-              mmr_t   xnpi_debit_overflow     : 1;
+-              mmr_t   xnpi_credit_overflow    : 1;
+-              mmr_t   xnmd_lut_error          : 1;
+-              mmr_t   xnmd_uce_error          : 1;
+-              mmr_t   xnmd_sbe_error          : 1;
+-              mmr_t   xnmd_credit_underflow   : 1;
+-              mmr_t   xnmd_data_buff_overflow : 1;
+-              mmr_t   xnmd_debit_overflow     : 1;
+-              mmr_t   xnmd_credit_overflow    : 1;
+-              mmr_t   ni1_pipe_error          : 1;
+-              mmr_t   ni1_llp_error           : 1;
+-              mmr_t   ni1_credit_underflow    : 1;
+-              mmr_t   ni1_push_underflow      : 1;
+-              mmr_t   ni1_pop_underflow       : 1;
+-              mmr_t   ni1_debit_overflow      : 1;
+-              mmr_t   ni1_credit_overflow     : 1;
+-              mmr_t   ni1_push_overflow       : 1;
+-              mmr_t   ni1_pop_overflow        : 1;
+-              mmr_t   ni0_pipe_error          : 1;
+-              mmr_t   ni0_llp_error           : 1;
+-              mmr_t   ni0_credit_underflow    : 1;
+-              mmr_t   ni0_push_underflow      : 1;
+-              mmr_t   ni0_pop_underflow       : 1;
+-              mmr_t   ni0_debit_overflow      : 1;
+-              mmr_t   ni0_credit_overflow     : 1;
+-              mmr_t   ni0_push_overflow       : 1;
+-              mmr_t   ni0_pop_overflow        : 1;
+-      } sh_xn_error_summary_s;
+-} sh_xn_error_summary_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XN_ERROR_OVERFLOW"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_error_overflow_u {
+       mmr_t   sh_xn_error_overflow_regval;
+       struct {
+@@ -16304,58 +8806,11 @@
+               mmr_t   reserved_0              : 26;
+       } sh_xn_error_overflow_s;
+ } sh_xn_error_overflow_u_t;
+-#else
+-typedef union sh_xn_error_overflow_u {
+-      mmr_t   sh_xn_error_overflow_regval;
+-      struct {
+-              mmr_t   reserved_0              : 26;
+-              mmr_t   iilb_chiplet_or_lut     : 1;
+-              mmr_t   iilb_fifo_underflow     : 1;
+-              mmr_t   iilb_credit_underflow   : 1;
+-              mmr_t   iilb_fifo_overflow      : 1;
+-              mmr_t   iilb_credit_overflow    : 1;
+-              mmr_t   iilb_debit_overflow     : 1;
+-              mmr_t   xnpi_lut_error          : 1;
+-              mmr_t   xnpi_uce_error          : 1;
+-              mmr_t   xnpi_sbe_error          : 1;
+-              mmr_t   xnpi_credit_underflow   : 1;
+-              mmr_t   xnpi_data_buff_overflow : 1;
+-              mmr_t   xnpi_debit_overflow     : 1;
+-              mmr_t   xnpi_credit_overflow    : 1;
+-              mmr_t   xnmd_lut_error          : 1;
+-              mmr_t   xnmd_uce_error          : 1;
+-              mmr_t   xnmd_sbe_error          : 1;
+-              mmr_t   xnmd_credit_underflow   : 1;
+-              mmr_t   xnmd_data_buff_overflow : 1;
+-              mmr_t   xnmd_debit_overflow     : 1;
+-              mmr_t   xnmd_credit_overflow    : 1;
+-              mmr_t   ni1_pipe_error          : 1;
+-              mmr_t   ni1_llp_error           : 1;
+-              mmr_t   ni1_credit_underflow    : 1;
+-              mmr_t   ni1_push_underflow      : 1;
+-              mmr_t   ni1_pop_underflow       : 1;
+-              mmr_t   ni1_debit_overflow      : 1;
+-              mmr_t   ni1_credit_overflow     : 1;
+-              mmr_t   ni1_push_overflow       : 1;
+-              mmr_t   ni1_pop_overflow        : 1;
+-              mmr_t   ni0_pipe_error          : 1;
+-              mmr_t   ni0_llp_error           : 1;
+-              mmr_t   ni0_credit_underflow    : 1;
+-              mmr_t   ni0_push_underflow      : 1;
+-              mmr_t   ni0_pop_underflow       : 1;
+-              mmr_t   ni0_debit_overflow      : 1;
+-              mmr_t   ni0_credit_overflow     : 1;
+-              mmr_t   ni0_push_overflow       : 1;
+-              mmr_t   ni0_pop_overflow        : 1;
+-      } sh_xn_error_overflow_s;
+-} sh_xn_error_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_XN_ERROR_MASK"                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_error_mask_u {
+       mmr_t   sh_xn_error_mask_regval;
+       struct {
+@@ -16400,58 +8855,11 @@
+               mmr_t   reserved_0              : 26;
+       } sh_xn_error_mask_s;
+ } sh_xn_error_mask_u_t;
+-#else
+-typedef union sh_xn_error_mask_u {
+-      mmr_t   sh_xn_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_0              : 26;
+-              mmr_t   iilb_chiplet_or_lut     : 1;
+-              mmr_t   iilb_fifo_underflow     : 1;
+-              mmr_t   iilb_credit_underflow   : 1;
+-              mmr_t   iilb_fifo_overflow      : 1;
+-              mmr_t   iilb_credit_overflow    : 1;
+-              mmr_t   iilb_debit_overflow     : 1;
+-              mmr_t   xnpi_lut_error          : 1;
+-              mmr_t   xnpi_uce_error          : 1;
+-              mmr_t   xnpi_sbe_error          : 1;
+-              mmr_t   xnpi_credit_underflow   : 1;
+-              mmr_t   xnpi_data_buff_overflow : 1;
+-              mmr_t   xnpi_debit_overflow     : 1;
+-              mmr_t   xnpi_credit_overflow    : 1;
+-              mmr_t   xnmd_lut_error          : 1;
+-              mmr_t   xnmd_uce_error          : 1;
+-              mmr_t   xnmd_sbe_error          : 1;
+-              mmr_t   xnmd_credit_underflow   : 1;
+-              mmr_t   xnmd_data_buff_overflow : 1;
+-              mmr_t   xnmd_debit_overflow     : 1;
+-              mmr_t   xnmd_credit_overflow    : 1;
+-              mmr_t   ni1_pipe_error          : 1;
+-              mmr_t   ni1_llp_error           : 1;
+-              mmr_t   ni1_credit_underflow    : 1;
+-              mmr_t   ni1_push_underflow      : 1;
+-              mmr_t   ni1_pop_underflow       : 1;
+-              mmr_t   ni1_debit_overflow      : 1;
+-              mmr_t   ni1_credit_overflow     : 1;
+-              mmr_t   ni1_push_overflow       : 1;
+-              mmr_t   ni1_pop_overflow        : 1;
+-              mmr_t   ni0_pipe_error          : 1;
+-              mmr_t   ni0_llp_error           : 1;
+-              mmr_t   ni0_credit_underflow    : 1;
+-              mmr_t   ni0_push_underflow      : 1;
+-              mmr_t   ni0_pop_underflow       : 1;
+-              mmr_t   ni0_debit_overflow      : 1;
+-              mmr_t   ni0_credit_overflow     : 1;
+-              mmr_t   ni0_push_overflow       : 1;
+-              mmr_t   ni0_pop_overflow        : 1;
+-      } sh_xn_error_mask_s;
+-} sh_xn_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_XN_FIRST_ERROR"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_first_error_u {
+       mmr_t   sh_xn_first_error_regval;
+       struct {
+@@ -16496,58 +8904,11 @@
+               mmr_t   reserved_0              : 26;
+       } sh_xn_first_error_s;
+ } sh_xn_first_error_u_t;
+-#else
+-typedef union sh_xn_first_error_u {
+-      mmr_t   sh_xn_first_error_regval;
+-      struct {
+-              mmr_t   reserved_0              : 26;
+-              mmr_t   iilb_chiplet_or_lut     : 1;
+-              mmr_t   iilb_fifo_underflow     : 1;
+-              mmr_t   iilb_credit_underflow   : 1;
+-              mmr_t   iilb_fifo_overflow      : 1;
+-              mmr_t   iilb_credit_overflow    : 1;
+-              mmr_t   iilb_debit_overflow     : 1;
+-              mmr_t   xnpi_lut_error          : 1;
+-              mmr_t   xnpi_uce_error          : 1;
+-              mmr_t   xnpi_sbe_error          : 1;
+-              mmr_t   xnpi_credit_underflow   : 1;
+-              mmr_t   xnpi_data_buff_overflow : 1;
+-              mmr_t   xnpi_debit_overflow     : 1;
+-              mmr_t   xnpi_credit_overflow    : 1;
+-              mmr_t   xnmd_lut_error          : 1;
+-              mmr_t   xnmd_uce_error          : 1;
+-              mmr_t   xnmd_sbe_error          : 1;
+-              mmr_t   xnmd_credit_underflow   : 1;
+-              mmr_t   xnmd_data_buff_overflow : 1;
+-              mmr_t   xnmd_debit_overflow     : 1;
+-              mmr_t   xnmd_credit_overflow    : 1;
+-              mmr_t   ni1_pipe_error          : 1;
+-              mmr_t   ni1_llp_error           : 1;
+-              mmr_t   ni1_credit_underflow    : 1;
+-              mmr_t   ni1_push_underflow      : 1;
+-              mmr_t   ni1_pop_underflow       : 1;
+-              mmr_t   ni1_debit_overflow      : 1;
+-              mmr_t   ni1_credit_overflow     : 1;
+-              mmr_t   ni1_push_overflow       : 1;
+-              mmr_t   ni1_pop_overflow        : 1;
+-              mmr_t   ni0_pipe_error          : 1;
+-              mmr_t   ni0_llp_error           : 1;
+-              mmr_t   ni0_credit_underflow    : 1;
+-              mmr_t   ni0_push_underflow      : 1;
+-              mmr_t   ni0_pop_underflow       : 1;
+-              mmr_t   ni0_debit_overflow      : 1;
+-              mmr_t   ni0_credit_overflow     : 1;
+-              mmr_t   ni0_push_overflow       : 1;
+-              mmr_t   ni0_pop_overflow        : 1;
+-      } sh_xn_first_error_s;
+-} sh_xn_first_error_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNIILB_ERROR_SUMMARY"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_summary_u {
+       mmr_t   sh_xniilb_error_summary_regval;
+       struct {
+@@ -16617,83 +8978,11 @@
+               mmr_t   lut_read_error                : 1;
+       } sh_xniilb_error_summary_s;
+ } sh_xniilb_error_summary_u_t;
+-#else
+-typedef union sh_xniilb_error_summary_u {
+-      mmr_t   sh_xniilb_error_summary_regval;
+-      struct {
+-              mmr_t   lut_read_error                : 1;
+-              mmr_t   chiplet_nomatch               : 1;
+-              mmr_t   underflow_ni1_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni1_vc0_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc0_credit_out  : 1;
+-              mmr_t   underflow_iilb_vc2_credit_out : 1;
+-              mmr_t   underflow_iilb_vc0_credit_out : 1;
+-              mmr_t   underflow_md_vc2_credit_out   : 1;
+-              mmr_t   underflow_md_vc0_credit_out   : 1;
+-              mmr_t   underflow_pi_vc2_credit_out   : 1;
+-              mmr_t   underflow_pi_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc0_credit_out   : 1;
+-              mmr_t   overflow_iilb_vc2_credit_out  : 1;
+-              mmr_t   overflow_iilb_vc0_credit_out  : 1;
+-              mmr_t   overflow_md_vc2_credit_out    : 1;
+-              mmr_t   overflow_md_vc0_credit_out    : 1;
+-              mmr_t   overflow_pi_vc2_credit_out    : 1;
+-              mmr_t   overflow_pi_vc0_credit_out    : 1;
+-              mmr_t   overflow_ni1_debit2           : 1;
+-              mmr_t   overflow_ni1_debit0           : 1;
+-              mmr_t   overflow_ni0_debit2           : 1;
+-              mmr_t   overflow_ni0_debit0           : 1;
+-              mmr_t   overflow_md_debit2            : 1;
+-              mmr_t   overflow_md_debit0            : 1;
+-              mmr_t   overflow_iilb_debit2          : 1;
+-              mmr_t   overflow_iilb_debit0          : 1;
+-              mmr_t   overflow_pi_debit2            : 1;
+-              mmr_t   overflow_pi_debit0            : 1;
+-              mmr_t   underflow_ni1_vc2_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc2_credit_in   : 1;
+-              mmr_t   underflow_md_vc2_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc2_credit_in  : 1;
+-              mmr_t   underflow_pi_vc2_credit_in    : 1;
+-              mmr_t   underflow_ni1_vc0_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc0_credit_in   : 1;
+-              mmr_t   underflow_md_vc0_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc0_credit_in  : 1;
+-              mmr_t   underflow_pi_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni1_vc2_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc2_credit_in    : 1;
+-              mmr_t   overflow_md_vc2_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc2_credit_in   : 1;
+-              mmr_t   overflow_pi_vc2_credit_in     : 1;
+-              mmr_t   overflow_ni1_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc0_credit_in    : 1;
+-              mmr_t   overflow_md_vc0_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc0_credit_in   : 1;
+-              mmr_t   overflow_pi_vc0_credit_in     : 1;
+-              mmr_t   underflow_lb_vc2              : 1;
+-              mmr_t   underflow_lb_vc0              : 1;
+-              mmr_t   overflow_lb_vc2               : 1;
+-              mmr_t   overflow_lb_vc0               : 1;
+-              mmr_t   underflow_ii_vc2              : 1;
+-              mmr_t   underflow_ii_vc0              : 1;
+-              mmr_t   overflow_ii_vc2               : 1;
+-              mmr_t   overflow_ii_vc0               : 1;
+-              mmr_t   overflow_lb_debit2            : 1;
+-              mmr_t   overflow_lb_debit0            : 1;
+-              mmr_t   overflow_ii_debit2            : 1;
+-              mmr_t   overflow_ii_debit0            : 1;
+-      } sh_xniilb_error_summary_s;
+-} sh_xniilb_error_summary_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_XNIILB_ERROR_OVERFLOW"                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_overflow_u {
+       mmr_t   sh_xniilb_error_overflow_regval;
+       struct {
+@@ -16763,83 +9052,11 @@
+               mmr_t   lut_read_error                : 1;
+       } sh_xniilb_error_overflow_s;
+ } sh_xniilb_error_overflow_u_t;
+-#else
+-typedef union sh_xniilb_error_overflow_u {
+-      mmr_t   sh_xniilb_error_overflow_regval;
+-      struct {
+-              mmr_t   lut_read_error                : 1;
+-              mmr_t   chiplet_nomatch               : 1;
+-              mmr_t   underflow_ni1_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni1_vc0_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc0_credit_out  : 1;
+-              mmr_t   underflow_iilb_vc2_credit_out : 1;
+-              mmr_t   underflow_iilb_vc0_credit_out : 1;
+-              mmr_t   underflow_md_vc2_credit_out   : 1;
+-              mmr_t   underflow_md_vc0_credit_out   : 1;
+-              mmr_t   underflow_pi_vc2_credit_out   : 1;
+-              mmr_t   underflow_pi_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc0_credit_out   : 1;
+-              mmr_t   overflow_iilb_vc2_credit_out  : 1;
+-              mmr_t   overflow_iilb_vc0_credit_out  : 1;
+-              mmr_t   overflow_md_vc2_credit_out    : 1;
+-              mmr_t   overflow_md_vc0_credit_out    : 1;
+-              mmr_t   overflow_pi_vc2_credit_out    : 1;
+-              mmr_t   overflow_pi_vc0_credit_out    : 1;
+-              mmr_t   overflow_ni1_debit2           : 1;
+-              mmr_t   overflow_ni1_debit0           : 1;
+-              mmr_t   overflow_ni0_debit2           : 1;
+-              mmr_t   overflow_ni0_debit0           : 1;
+-              mmr_t   overflow_md_debit2            : 1;
+-              mmr_t   overflow_md_debit0            : 1;
+-              mmr_t   overflow_iilb_debit2          : 1;
+-              mmr_t   overflow_iilb_debit0          : 1;
+-              mmr_t   overflow_pi_debit2            : 1;
+-              mmr_t   overflow_pi_debit0            : 1;
+-              mmr_t   underflow_ni1_vc2_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc2_credit_in   : 1;
+-              mmr_t   underflow_md_vc2_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc2_credit_in  : 1;
+-              mmr_t   underflow_pi_vc2_credit_in    : 1;
+-              mmr_t   underflow_ni1_vc0_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc0_credit_in   : 1;
+-              mmr_t   underflow_md_vc0_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc0_credit_in  : 1;
+-              mmr_t   underflow_pi_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni1_vc2_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc2_credit_in    : 1;
+-              mmr_t   overflow_md_vc2_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc2_credit_in   : 1;
+-              mmr_t   overflow_pi_vc2_credit_in     : 1;
+-              mmr_t   overflow_ni1_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc0_credit_in    : 1;
+-              mmr_t   overflow_md_vc0_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc0_credit_in   : 1;
+-              mmr_t   overflow_pi_vc0_credit_in     : 1;
+-              mmr_t   underflow_lb_vc2              : 1;
+-              mmr_t   underflow_lb_vc0              : 1;
+-              mmr_t   overflow_lb_vc2               : 1;
+-              mmr_t   overflow_lb_vc0               : 1;
+-              mmr_t   underflow_ii_vc2              : 1;
+-              mmr_t   underflow_ii_vc0              : 1;
+-              mmr_t   overflow_ii_vc2               : 1;
+-              mmr_t   overflow_ii_vc0               : 1;
+-              mmr_t   overflow_lb_debit2            : 1;
+-              mmr_t   overflow_lb_debit0            : 1;
+-              mmr_t   overflow_ii_debit2            : 1;
+-              mmr_t   overflow_ii_debit0            : 1;
+-      } sh_xniilb_error_overflow_s;
+-} sh_xniilb_error_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNIILB_ERROR_MASK"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_error_mask_u {
+       mmr_t   sh_xniilb_error_mask_regval;
+       struct {
+@@ -16909,83 +9126,11 @@
+               mmr_t   lut_read_error                : 1;
+       } sh_xniilb_error_mask_s;
+ } sh_xniilb_error_mask_u_t;
+-#else
+-typedef union sh_xniilb_error_mask_u {
+-      mmr_t   sh_xniilb_error_mask_regval;
+-      struct {
+-              mmr_t   lut_read_error                : 1;
+-              mmr_t   chiplet_nomatch               : 1;
+-              mmr_t   underflow_ni1_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni1_vc0_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc0_credit_out  : 1;
+-              mmr_t   underflow_iilb_vc2_credit_out : 1;
+-              mmr_t   underflow_iilb_vc0_credit_out : 1;
+-              mmr_t   underflow_md_vc2_credit_out   : 1;
+-              mmr_t   underflow_md_vc0_credit_out   : 1;
+-              mmr_t   underflow_pi_vc2_credit_out   : 1;
+-              mmr_t   underflow_pi_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc0_credit_out   : 1;
+-              mmr_t   overflow_iilb_vc2_credit_out  : 1;
+-              mmr_t   overflow_iilb_vc0_credit_out  : 1;
+-              mmr_t   overflow_md_vc2_credit_out    : 1;
+-              mmr_t   overflow_md_vc0_credit_out    : 1;
+-              mmr_t   overflow_pi_vc2_credit_out    : 1;
+-              mmr_t   overflow_pi_vc0_credit_out    : 1;
+-              mmr_t   overflow_ni1_debit2           : 1;
+-              mmr_t   overflow_ni1_debit0           : 1;
+-              mmr_t   overflow_ni0_debit2           : 1;
+-              mmr_t   overflow_ni0_debit0           : 1;
+-              mmr_t   overflow_md_debit2            : 1;
+-              mmr_t   overflow_md_debit0            : 1;
+-              mmr_t   overflow_iilb_debit2          : 1;
+-              mmr_t   overflow_iilb_debit0          : 1;
+-              mmr_t   overflow_pi_debit2            : 1;
+-              mmr_t   overflow_pi_debit0            : 1;
+-              mmr_t   underflow_ni1_vc2_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc2_credit_in   : 1;
+-              mmr_t   underflow_md_vc2_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc2_credit_in  : 1;
+-              mmr_t   underflow_pi_vc2_credit_in    : 1;
+-              mmr_t   underflow_ni1_vc0_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc0_credit_in   : 1;
+-              mmr_t   underflow_md_vc0_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc0_credit_in  : 1;
+-              mmr_t   underflow_pi_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni1_vc2_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc2_credit_in    : 1;
+-              mmr_t   overflow_md_vc2_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc2_credit_in   : 1;
+-              mmr_t   overflow_pi_vc2_credit_in     : 1;
+-              mmr_t   overflow_ni1_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc0_credit_in    : 1;
+-              mmr_t   overflow_md_vc0_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc0_credit_in   : 1;
+-              mmr_t   overflow_pi_vc0_credit_in     : 1;
+-              mmr_t   underflow_lb_vc2              : 1;
+-              mmr_t   underflow_lb_vc0              : 1;
+-              mmr_t   overflow_lb_vc2               : 1;
+-              mmr_t   overflow_lb_vc0               : 1;
+-              mmr_t   underflow_ii_vc2              : 1;
+-              mmr_t   underflow_ii_vc0              : 1;
+-              mmr_t   overflow_ii_vc2               : 1;
+-              mmr_t   overflow_ii_vc0               : 1;
+-              mmr_t   overflow_lb_debit2            : 1;
+-              mmr_t   overflow_lb_debit0            : 1;
+-              mmr_t   overflow_ii_debit2            : 1;
+-              mmr_t   overflow_ii_debit0            : 1;
+-      } sh_xniilb_error_mask_s;
+-} sh_xniilb_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XNIILB_FIRST_ERROR"                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xniilb_first_error_u {
+       mmr_t   sh_xniilb_first_error_regval;
+       struct {
+@@ -17055,85 +9200,13 @@
+               mmr_t   lut_read_error                : 1;
+       } sh_xniilb_first_error_s;
+ } sh_xniilb_first_error_u_t;
+-#else
+-typedef union sh_xniilb_first_error_u {
+-      mmr_t   sh_xniilb_first_error_regval;
+-      struct {
+-              mmr_t   lut_read_error                : 1;
+-              mmr_t   chiplet_nomatch               : 1;
+-              mmr_t   underflow_ni1_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni1_vc0_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc2_credit_out  : 1;
+-              mmr_t   underflow_ni0_vc0_credit_out  : 1;
+-              mmr_t   underflow_iilb_vc2_credit_out : 1;
+-              mmr_t   underflow_iilb_vc0_credit_out : 1;
+-              mmr_t   underflow_md_vc2_credit_out   : 1;
+-              mmr_t   underflow_md_vc0_credit_out   : 1;
+-              mmr_t   underflow_pi_vc2_credit_out   : 1;
+-              mmr_t   underflow_pi_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni1_vc0_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc2_credit_out   : 1;
+-              mmr_t   overflow_ni0_vc0_credit_out   : 1;
+-              mmr_t   overflow_iilb_vc2_credit_out  : 1;
+-              mmr_t   overflow_iilb_vc0_credit_out  : 1;
+-              mmr_t   overflow_md_vc2_credit_out    : 1;
+-              mmr_t   overflow_md_vc0_credit_out    : 1;
+-              mmr_t   overflow_pi_vc2_credit_out    : 1;
+-              mmr_t   overflow_pi_vc0_credit_out    : 1;
+-              mmr_t   overflow_ni1_debit2           : 1;
+-              mmr_t   overflow_ni1_debit0           : 1;
+-              mmr_t   overflow_ni0_debit2           : 1;
+-              mmr_t   overflow_ni0_debit0           : 1;
+-              mmr_t   overflow_md_debit2            : 1;
+-              mmr_t   overflow_md_debit0            : 1;
+-              mmr_t   overflow_iilb_debit2          : 1;
+-              mmr_t   overflow_iilb_debit0          : 1;
+-              mmr_t   overflow_pi_debit2            : 1;
+-              mmr_t   overflow_pi_debit0            : 1;
+-              mmr_t   underflow_ni1_vc2_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc2_credit_in   : 1;
+-              mmr_t   underflow_md_vc2_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc2_credit_in  : 1;
+-              mmr_t   underflow_pi_vc2_credit_in    : 1;
+-              mmr_t   underflow_ni1_vc0_credit_in   : 1;
+-              mmr_t   underflow_ni0_vc0_credit_in   : 1;
+-              mmr_t   underflow_md_vc0_credit_in    : 1;
+-              mmr_t   underflow_iilb_vc0_credit_in  : 1;
+-              mmr_t   underflow_pi_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni1_vc2_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc2_credit_in    : 1;
+-              mmr_t   overflow_md_vc2_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc2_credit_in   : 1;
+-              mmr_t   overflow_pi_vc2_credit_in     : 1;
+-              mmr_t   overflow_ni1_vc0_credit_in    : 1;
+-              mmr_t   overflow_ni0_vc0_credit_in    : 1;
+-              mmr_t   overflow_md_vc0_credit_in     : 1;
+-              mmr_t   overflow_iilb_vc0_credit_in   : 1;
+-              mmr_t   overflow_pi_vc0_credit_in     : 1;
+-              mmr_t   underflow_lb_vc2              : 1;
+-              mmr_t   underflow_lb_vc0              : 1;
+-              mmr_t   overflow_lb_vc2               : 1;
+-              mmr_t   overflow_lb_vc0               : 1;
+-              mmr_t   underflow_ii_vc2              : 1;
+-              mmr_t   underflow_ii_vc0              : 1;
+-              mmr_t   overflow_ii_vc2               : 1;
+-              mmr_t   overflow_ii_vc0               : 1;
+-              mmr_t   overflow_lb_debit2            : 1;
+-              mmr_t   overflow_lb_debit0            : 1;
+-              mmr_t   overflow_ii_debit2            : 1;
+-              mmr_t   overflow_ii_debit0            : 1;
+-      } sh_xniilb_first_error_s;
+-} sh_xniilb_first_error_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                   Register "SH_XNPI_ERROR_SUMMARY"                   */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnpi_error_summary_u {
+-      mmr_t   sh_xnpi_error_summary_regval;
++
++/* ==================================================================== */
++/*                   Register "SH_XNPI_ERROR_SUMMARY"                   */
++/* ==================================================================== */
++
++typedef union sh_xnpi_error_summary_u {
++      mmr_t   sh_xnpi_error_summary_regval;
+       struct {
+               mmr_t   underflow_ni0_vc0           : 1;
+               mmr_t   overflow_ni0_vc0            : 1;
+@@ -17188,70 +9261,11 @@
+               mmr_t   reserved_0                  : 14;
+       } sh_xnpi_error_summary_s;
+ } sh_xnpi_error_summary_u_t;
+-#else
+-typedef union sh_xnpi_error_summary_u {
+-      mmr_t   sh_xnpi_error_summary_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
+-      } sh_xnpi_error_summary_s;
+-} sh_xnpi_error_summary_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNPI_ERROR_OVERFLOW"                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_error_overflow_u {
+       mmr_t   sh_xnpi_error_overflow_regval;
+       struct {
+@@ -17308,70 +9322,11 @@
+               mmr_t   reserved_0                  : 14;
+       } sh_xnpi_error_overflow_s;
+ } sh_xnpi_error_overflow_u_t;
+-#else
+-typedef union sh_xnpi_error_overflow_u {
+-      mmr_t   sh_xnpi_error_overflow_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
+-      } sh_xnpi_error_overflow_s;
+-} sh_xnpi_error_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNPI_ERROR_MASK"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_error_mask_u {
+       mmr_t   sh_xnpi_error_mask_regval;
+       struct {
+@@ -17428,70 +9383,11 @@
+               mmr_t   reserved_0                  : 14;
+       } sh_xnpi_error_mask_s;
+ } sh_xnpi_error_mask_u_t;
+-#else
+-typedef union sh_xnpi_error_mask_u {
+-      mmr_t   sh_xnpi_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
+-      } sh_xnpi_error_mask_s;
+-} sh_xnpi_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNPI_FIRST_ERROR"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnpi_first_error_u {
+       mmr_t   sh_xnpi_first_error_regval;
+       struct {
+@@ -17548,72 +9444,13 @@
+               mmr_t   reserved_0                  : 14;
+       } sh_xnpi_first_error_s;
+ } sh_xnpi_first_error_u_t;
+-#else
+-typedef union sh_xnpi_first_error_u {
+-      mmr_t   sh_xnpi_first_error_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
+-      } sh_xnpi_first_error_s;
+-} sh_xnpi_first_error_u_t;
+-#endif
+-
+-/* ==================================================================== */
+-/*                   Register "SH_XNMD_ERROR_SUMMARY"                   */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_xnmd_error_summary_u {
+-      mmr_t   sh_xnmd_error_summary_regval;
++
++/* ==================================================================== */
++/*                   Register "SH_XNMD_ERROR_SUMMARY"                   */
++/* ==================================================================== */
++
++typedef union sh_xnmd_error_summary_u {
++      mmr_t   sh_xnmd_error_summary_regval;
+       struct {
+               mmr_t   underflow_ni0_vc0           : 1;
+               mmr_t   overflow_ni0_vc0            : 1;
+@@ -17668,70 +9505,11 @@
+               mmr_t   reserved_0                  : 14;
+       } sh_xnmd_error_summary_s;
+ } sh_xnmd_error_summary_u_t;
+-#else
+-typedef union sh_xnmd_error_summary_u {
+-      mmr_t   sh_xnmd_error_summary_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
+-      } sh_xnmd_error_summary_s;
+-} sh_xnmd_error_summary_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XNMD_ERROR_OVERFLOW"                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_error_overflow_u {
+       mmr_t   sh_xnmd_error_overflow_regval;
+       struct {
+@@ -17788,70 +9566,11 @@
+               mmr_t   reserved_0                  : 14;
+       } sh_xnmd_error_overflow_s;
+ } sh_xnmd_error_overflow_u_t;
+-#else
+-typedef union sh_xnmd_error_overflow_u {
+-      mmr_t   sh_xnmd_error_overflow_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
+-      } sh_xnmd_error_overflow_s;
+-} sh_xnmd_error_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNMD_ERROR_MASK"                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_error_mask_u {
+       mmr_t   sh_xnmd_error_mask_regval;
+       struct {
+@@ -17908,70 +9627,11 @@
+               mmr_t   reserved_0                  : 14;
+       } sh_xnmd_error_mask_s;
+ } sh_xnmd_error_mask_u_t;
+-#else
+-typedef union sh_xnmd_error_mask_u {
+-      mmr_t   sh_xnmd_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
+-      } sh_xnmd_error_mask_s;
+-} sh_xnmd_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XNMD_FIRST_ERROR"                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xnmd_first_error_u {
+       mmr_t   sh_xnmd_first_error_regval;
+       struct {
+@@ -17981,202 +9641,107 @@
+               mmr_t   overflow_ni0_vc2            : 1;
+               mmr_t   underflow_ni1_vc0           : 1;
+               mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   reserved_0                  : 14;
+-      } sh_xnmd_first_error_s;
+-} sh_xnmd_first_error_u_t;
+-#else
+-typedef union sh_xnmd_first_error_u {
+-      mmr_t   sh_xnmd_first_error_regval;
+-      struct {
+-              mmr_t   reserved_0                  : 14;
+-              mmr_t   overflow_header_cancel_fifo : 1;
+-              mmr_t   overflow_iilb_vc2_credit    : 1;
+-              mmr_t   underflow_iilb_vc2_credit   : 1;
+-              mmr_t   overflow_iilb_vc0_credit    : 1;
+-              mmr_t   underflow_iilb_vc0_credit   : 1;
+-              mmr_t   overflow_ni1_vc2_credit     : 1;
+-              mmr_t   underflow_ni1_vc2_credit    : 1;
+-              mmr_t   overflow_ni1_vc0_credit     : 1;
+-              mmr_t   underflow_ni1_vc0_credit    : 1;
+-              mmr_t   overflow_ni0_vc2_credit     : 1;
+-              mmr_t   underflow_ni0_vc2_credit    : 1;
+-              mmr_t   overflow_ni0_vc0_credit     : 1;
+-              mmr_t   underflow_ni0_vc0_credit    : 1;
+-              mmr_t   overflow_iilb_debit2        : 1;
+-              mmr_t   overflow_iilb_debit0        : 1;
+-              mmr_t   overflow_ni1_debit2         : 1;
+-              mmr_t   overflow_ni1_debit0         : 1;
+-              mmr_t   overflow_ni0_debit2         : 1;
+-              mmr_t   overflow_ni0_debit0         : 1;
+-              mmr_t   overflow_sic_cntr2          : 1;
+-              mmr_t   underflow_sic_cntr2         : 1;
+-              mmr_t   overflow_sic_cntr0          : 1;
+-              mmr_t   underflow_sic_cntr0         : 1;
+-              mmr_t   uncor_error3                : 1;
+-              mmr_t   uncor_error2                : 1;
+-              mmr_t   uncor_error1                : 1;
+-              mmr_t   uncor_error0                : 1;
+-              mmr_t   single_bit_error3           : 1;
+-              mmr_t   single_bit_error2           : 1;
+-              mmr_t   single_bit_error1           : 1;
+-              mmr_t   single_bit_error0           : 1;
+-              mmr_t   lut_read_error              : 1;
+-              mmr_t   overflow_databuff_vc2       : 1;
+-              mmr_t   overflow_databuff_vc0       : 1;
+-              mmr_t   overflow_vc2_credit         : 1;
+-              mmr_t   underflow_vc2_credit        : 1;
+-              mmr_t   overflow_vc0_credit         : 1;
+-              mmr_t   underflow_vc0_credit        : 1;
+-              mmr_t   overflow_iilb_vc2           : 1;
+-              mmr_t   underflow_iilb_vc2          : 1;
+-              mmr_t   overflow_iilb_vc0           : 1;
+-              mmr_t   underflow_iilb_vc0          : 1;
+-              mmr_t   overflow_ni1_vc2            : 1;
+-              mmr_t   underflow_ni1_vc2           : 1;
+-              mmr_t   overflow_ni1_vc0            : 1;
+-              mmr_t   underflow_ni1_vc0           : 1;
+-              mmr_t   overflow_ni0_vc2            : 1;
+-              mmr_t   underflow_ni0_vc2           : 1;
+-              mmr_t   overflow_ni0_vc0            : 1;
+-              mmr_t   underflow_ni0_vc0           : 1;
++              mmr_t   underflow_ni1_vc2           : 1;
++              mmr_t   overflow_ni1_vc2            : 1;
++              mmr_t   underflow_iilb_vc0          : 1;
++              mmr_t   overflow_iilb_vc0           : 1;
++              mmr_t   underflow_iilb_vc2          : 1;
++              mmr_t   overflow_iilb_vc2           : 1;
++              mmr_t   underflow_vc0_credit        : 1;
++              mmr_t   overflow_vc0_credit         : 1;
++              mmr_t   underflow_vc2_credit        : 1;
++              mmr_t   overflow_vc2_credit         : 1;
++              mmr_t   overflow_databuff_vc0       : 1;
++              mmr_t   overflow_databuff_vc2       : 1;
++              mmr_t   lut_read_error              : 1;
++              mmr_t   single_bit_error0           : 1;
++              mmr_t   single_bit_error1           : 1;
++              mmr_t   single_bit_error2           : 1;
++              mmr_t   single_bit_error3           : 1;
++              mmr_t   uncor_error0                : 1;
++              mmr_t   uncor_error1                : 1;
++              mmr_t   uncor_error2                : 1;
++              mmr_t   uncor_error3                : 1;
++              mmr_t   underflow_sic_cntr0         : 1;
++              mmr_t   overflow_sic_cntr0          : 1;
++              mmr_t   underflow_sic_cntr2         : 1;
++              mmr_t   overflow_sic_cntr2          : 1;
++              mmr_t   overflow_ni0_debit0         : 1;
++              mmr_t   overflow_ni0_debit2         : 1;
++              mmr_t   overflow_ni1_debit0         : 1;
++              mmr_t   overflow_ni1_debit2         : 1;
++              mmr_t   overflow_iilb_debit0        : 1;
++              mmr_t   overflow_iilb_debit2        : 1;
++              mmr_t   underflow_ni0_vc0_credit    : 1;
++              mmr_t   overflow_ni0_vc0_credit     : 1;
++              mmr_t   underflow_ni0_vc2_credit    : 1;
++              mmr_t   overflow_ni0_vc2_credit     : 1;
++              mmr_t   underflow_ni1_vc0_credit    : 1;
++              mmr_t   overflow_ni1_vc0_credit     : 1;
++              mmr_t   underflow_ni1_vc2_credit    : 1;
++              mmr_t   overflow_ni1_vc2_credit     : 1;
++              mmr_t   underflow_iilb_vc0_credit   : 1;
++              mmr_t   overflow_iilb_vc0_credit    : 1;
++              mmr_t   underflow_iilb_vc2_credit   : 1;
++              mmr_t   overflow_iilb_vc2_credit    : 1;
++              mmr_t   overflow_header_cancel_fifo : 1;
++              mmr_t   reserved_0                  : 14;
+       } sh_xnmd_first_error_s;
+ } sh_xnmd_first_error_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_AUTO_REPLY_ENABLE0"                   */
+ /*                 Automatic Maintenance Reply Enable 0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_enable0_u {
+-      mmr_t   sh_auto_reply_enable0_regval;
+-      struct {
+-              mmr_t   enable0     : 64;
+-      } sh_auto_reply_enable0_s;
+-} sh_auto_reply_enable0_u_t;
+-#else
+ typedef union sh_auto_reply_enable0_u {
+       mmr_t   sh_auto_reply_enable0_regval;
+       struct {
+               mmr_t   enable0     : 64;
+       } sh_auto_reply_enable0_s;
+ } sh_auto_reply_enable0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_AUTO_REPLY_ENABLE1"                   */
+ /*                 Automatic Maintenance Reply Enable 1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_enable1_u {
+-      mmr_t   sh_auto_reply_enable1_regval;
+-      struct {
+-              mmr_t   enable1     : 64;
+-      } sh_auto_reply_enable1_s;
+-} sh_auto_reply_enable1_u_t;
+-#else
+ typedef union sh_auto_reply_enable1_u {
+       mmr_t   sh_auto_reply_enable1_regval;
+       struct {
+               mmr_t   enable1     : 64;
+       } sh_auto_reply_enable1_s;
+ } sh_auto_reply_enable1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_AUTO_REPLY_HEADER0"                   */
+ /*                 Automatic Maintenance Reply Header 0                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_header0_u {
+-      mmr_t   sh_auto_reply_header0_regval;
+-      struct {
+-              mmr_t   header0     : 64;
+-      } sh_auto_reply_header0_s;
+-} sh_auto_reply_header0_u_t;
+-#else
+ typedef union sh_auto_reply_header0_u {
+       mmr_t   sh_auto_reply_header0_regval;
+       struct {
+               mmr_t   header0     : 64;
+       } sh_auto_reply_header0_s;
+ } sh_auto_reply_header0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_AUTO_REPLY_HEADER1"                   */
+ /*                 Automatic Maintenance Reply Header 1                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_auto_reply_header1_u {
+-      mmr_t   sh_auto_reply_header1_regval;
+-      struct {
+-              mmr_t   header1     : 64;
+-      } sh_auto_reply_header1_s;
+-} sh_auto_reply_header1_u_t;
+-#else
+ typedef union sh_auto_reply_header1_u {
+       mmr_t   sh_auto_reply_header1_regval;
+       struct {
+               mmr_t   header1     : 64;
+       } sh_auto_reply_header1_s;
+ } sh_auto_reply_header1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_ENABLE_RP_AUTO_REPLY"                  */
+ /*         Enable Automatic Maintenance Reply From Reply Queue          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_enable_rp_auto_reply_u {
+       mmr_t   sh_enable_rp_auto_reply_regval;
+       struct {
+@@ -18184,22 +9749,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_enable_rp_auto_reply_s;
+ } sh_enable_rp_auto_reply_u_t;
+-#else
+-typedef union sh_enable_rp_auto_reply_u {
+-      mmr_t   sh_enable_rp_auto_reply_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   enable      : 1;
+-      } sh_enable_rp_auto_reply_s;
+-} sh_enable_rp_auto_reply_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_ENABLE_RQ_AUTO_REPLY"                  */
+ /*        Enable Automatic Maintenance Reply From Request Queue         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_enable_rq_auto_reply_u {
+       mmr_t   sh_enable_rq_auto_reply_regval;
+       struct {
+@@ -18207,22 +9762,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_enable_rq_auto_reply_s;
+ } sh_enable_rq_auto_reply_u_t;
+-#else
+-typedef union sh_enable_rq_auto_reply_u {
+-      mmr_t   sh_enable_rq_auto_reply_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   enable      : 1;
+-      } sh_enable_rq_auto_reply_s;
+-} sh_enable_rq_auto_reply_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_REDIRECT_INVAL"                     */
+ /*               Redirect invalidate to LB instead of PI                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_redirect_inval_u {
+       mmr_t   sh_redirect_inval_regval;
+       struct {
+@@ -18230,22 +9775,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_redirect_inval_s;
+ } sh_redirect_inval_u_t;
+-#else
+-typedef union sh_redirect_inval_u {
+-      mmr_t   sh_redirect_inval_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   redirect    : 1;
+-      } sh_redirect_inval_s;
+-} sh_redirect_inval_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_DIAG_MSG_CNTRL"                     */
+ /*                 Diagnostic Message Control Register                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_cntrl_u {
+       mmr_t   sh_diag_msg_cntrl_regval;
+       struct {
+@@ -18258,447 +9793,252 @@
+               mmr_t   busy                : 1;
+       } sh_diag_msg_cntrl_s;
+ } sh_diag_msg_cntrl_u_t;
+-#else
+-typedef union sh_diag_msg_cntrl_u {
+-      mmr_t   sh_diag_msg_cntrl_regval;
+-      struct {
+-              mmr_t   busy                : 1;
+-              mmr_t   start               : 1;
+-              mmr_t   reserved_0          : 48;
+-              mmr_t   port                : 1;
+-              mmr_t   error_inject_enable : 1;
+-              mmr_t   error_inject_point  : 6;
+-              mmr_t   msg_length          : 6;
+-      } sh_diag_msg_cntrl_s;
+-} sh_diag_msg_cntrl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA0L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data0l_u {
+-      mmr_t   sh_diag_msg_data0l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data0l_s;
+-} sh_diag_msg_data0l_u_t;
+-#else
+ typedef union sh_diag_msg_data0l_u {
+       mmr_t   sh_diag_msg_data0l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data0l_s;
+ } sh_diag_msg_data0l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA0U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data0u_u {
+-      mmr_t   sh_diag_msg_data0u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data0u_s;
+-} sh_diag_msg_data0u_u_t;
+-#else
+ typedef union sh_diag_msg_data0u_u {
+       mmr_t   sh_diag_msg_data0u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data0u_s;
+ } sh_diag_msg_data0u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA1L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data1l_u {
+-      mmr_t   sh_diag_msg_data1l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data1l_s;
+-} sh_diag_msg_data1l_u_t;
+-#else
+ typedef union sh_diag_msg_data1l_u {
+       mmr_t   sh_diag_msg_data1l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data1l_s;
+ } sh_diag_msg_data1l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA1U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data1u_u {
+       mmr_t   sh_diag_msg_data1u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data1u_s;
+ } sh_diag_msg_data1u_u_t;
+-#else
+-typedef union sh_diag_msg_data1u_u {
+-      mmr_t   sh_diag_msg_data1u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data1u_s;
+-} sh_diag_msg_data1u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA2L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data2l_u {
+-      mmr_t   sh_diag_msg_data2l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data2l_s;
+-} sh_diag_msg_data2l_u_t;
+-#else
+ typedef union sh_diag_msg_data2l_u {
+       mmr_t   sh_diag_msg_data2l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data2l_s;
+ } sh_diag_msg_data2l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA2U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data2u_u {
+-      mmr_t   sh_diag_msg_data2u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data2u_s;
+-} sh_diag_msg_data2u_u_t;
+-#else
+ typedef union sh_diag_msg_data2u_u {
+       mmr_t   sh_diag_msg_data2u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data2u_s;
+ } sh_diag_msg_data2u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA3L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data3l_u {
+-      mmr_t   sh_diag_msg_data3l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data3l_s;
+-} sh_diag_msg_data3l_u_t;
+-#else
+ typedef union sh_diag_msg_data3l_u {
+       mmr_t   sh_diag_msg_data3l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data3l_s;
+ } sh_diag_msg_data3l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA3U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data3u_u {
+       mmr_t   sh_diag_msg_data3u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data3u_s;
+ } sh_diag_msg_data3u_u_t;
+-#else
+-typedef union sh_diag_msg_data3u_u {
+-      mmr_t   sh_diag_msg_data3u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data3u_s;
+-} sh_diag_msg_data3u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA4L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data4l_u {
+-      mmr_t   sh_diag_msg_data4l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data4l_s;
+-} sh_diag_msg_data4l_u_t;
+-#else
+ typedef union sh_diag_msg_data4l_u {
+       mmr_t   sh_diag_msg_data4l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data4l_s;
+ } sh_diag_msg_data4l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA4U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data4u_u {
+-      mmr_t   sh_diag_msg_data4u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data4u_s;
+-} sh_diag_msg_data4u_u_t;
+-#else
+ typedef union sh_diag_msg_data4u_u {
+       mmr_t   sh_diag_msg_data4u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data4u_s;
+ } sh_diag_msg_data4u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA5L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data5l_u {
+-      mmr_t   sh_diag_msg_data5l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data5l_s;
+-} sh_diag_msg_data5l_u_t;
+-#else
+ typedef union sh_diag_msg_data5l_u {
+       mmr_t   sh_diag_msg_data5l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data5l_s;
+ } sh_diag_msg_data5l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA5U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data5u_u {
+       mmr_t   sh_diag_msg_data5u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data5u_s;
+ } sh_diag_msg_data5u_u_t;
+-#else
+-typedef union sh_diag_msg_data5u_u {
+-      mmr_t   sh_diag_msg_data5u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data5u_s;
+-} sh_diag_msg_data5u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA6L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data6l_u {
+-      mmr_t   sh_diag_msg_data6l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data6l_s;
+-} sh_diag_msg_data6l_u_t;
+-#else
+ typedef union sh_diag_msg_data6l_u {
+       mmr_t   sh_diag_msg_data6l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data6l_s;
+ } sh_diag_msg_data6l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA6U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data6u_u {
+-      mmr_t   sh_diag_msg_data6u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data6u_s;
+-} sh_diag_msg_data6u_u_t;
+-#else
+ typedef union sh_diag_msg_data6u_u {
+       mmr_t   sh_diag_msg_data6u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data6u_s;
+ } sh_diag_msg_data6u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA7L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data7l_u {
+-      mmr_t   sh_diag_msg_data7l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data7l_s;
+-} sh_diag_msg_data7l_u_t;
+-#else
+ typedef union sh_diag_msg_data7l_u {
+       mmr_t   sh_diag_msg_data7l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data7l_s;
+ } sh_diag_msg_data7l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA7U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_data7u_u {
+       mmr_t   sh_diag_msg_data7u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data7u_s;
+ } sh_diag_msg_data7u_u_t;
+-#else
+-typedef union sh_diag_msg_data7u_u {
+-      mmr_t   sh_diag_msg_data7u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data7u_s;
+-} sh_diag_msg_data7u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA8L"                     */
+ /*                    Diagnostic Data, lower 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data8l_u {
+-      mmr_t   sh_diag_msg_data8l_regval;
+-      struct {
+-              mmr_t   data_lower  : 64;
+-      } sh_diag_msg_data8l_s;
+-} sh_diag_msg_data8l_u_t;
+-#else
+ typedef union sh_diag_msg_data8l_u {
+       mmr_t   sh_diag_msg_data8l_regval;
+       struct {
+               mmr_t   data_lower  : 64;
+       } sh_diag_msg_data8l_s;
+ } sh_diag_msg_data8l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_DIAG_MSG_DATA8U"                     */
+ /*                   Diagnostice Data, upper 64 bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_data8u_u {
+-      mmr_t   sh_diag_msg_data8u_regval;
+-      struct {
+-              mmr_t   data_upper  : 64;
+-      } sh_diag_msg_data8u_s;
+-} sh_diag_msg_data8u_u_t;
+-#else
+ typedef union sh_diag_msg_data8u_u {
+       mmr_t   sh_diag_msg_data8u_regval;
+       struct {
+               mmr_t   data_upper  : 64;
+       } sh_diag_msg_data8u_s;
+ } sh_diag_msg_data8u_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_DIAG_MSG_HDR0"                      */
+ /*              Diagnostice Data, lower 64 bits of header               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_diag_msg_hdr0_u {
+-      mmr_t   sh_diag_msg_hdr0_regval;
+-      struct {
+-              mmr_t   header0     : 64;
+-      } sh_diag_msg_hdr0_s;
+-} sh_diag_msg_hdr0_u_t;
+-#else
+ typedef union sh_diag_msg_hdr0_u {
+       mmr_t   sh_diag_msg_hdr0_regval;
+       struct {
+               mmr_t   header0     : 64;
+       } sh_diag_msg_hdr0_s;
+ } sh_diag_msg_hdr0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_DIAG_MSG_HDR1"                      */
+ /*              Diagnostice Data, upper 64 bits of header               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_diag_msg_hdr1_u {
+       mmr_t   sh_diag_msg_hdr1_regval;
+       struct {
+               mmr_t   header1     : 64;
+       } sh_diag_msg_hdr1_s;
+ } sh_diag_msg_hdr1_u_t;
+-#else
+-typedef union sh_diag_msg_hdr1_u {
+-      mmr_t   sh_diag_msg_hdr1_regval;
+-      struct {
+-              mmr_t   header1     : 64;
+-      } sh_diag_msg_hdr1_s;
+-} sh_diag_msg_hdr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_DEBUG_SELECT"                      */
+ /*                        SHub Debug Port Select                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_debug_select_u {
+       mmr_t   sh_debug_select_regval;
+       struct {
+@@ -18713,51 +10053,23 @@
+               mmr_t   nibble4_nibble_sel  : 3;
+               mmr_t   nibble4_chiplet_sel : 3;
+               mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   nibble5_chiplet_sel : 3;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   nibble6_chiplet_sel : 3;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   nibble7_chiplet_sel : 3;
+-              mmr_t   debug_ii_sel        : 3;
+-              mmr_t   sel_ii              : 9;
+-              mmr_t   reserved_0          : 3;
+-              mmr_t   trigger_enable      : 1;
+-      } sh_debug_select_s;
+-} sh_debug_select_u_t;
+-#else
+-typedef union sh_debug_select_u {
+-      mmr_t   sh_debug_select_regval;
+-      struct {
+-              mmr_t   trigger_enable      : 1;
+-              mmr_t   reserved_0          : 3;
+-              mmr_t   sel_ii              : 9;
+-              mmr_t   debug_ii_sel        : 3;
+-              mmr_t   nibble7_chiplet_sel : 3;
+-              mmr_t   nibble7_nibble_sel  : 3;
+-              mmr_t   nibble6_chiplet_sel : 3;
+-              mmr_t   nibble6_nibble_sel  : 3;
+-              mmr_t   nibble5_chiplet_sel : 3;
+-              mmr_t   nibble5_nibble_sel  : 3;
+-              mmr_t   nibble4_chiplet_sel : 3;
+-              mmr_t   nibble4_nibble_sel  : 3;
+-              mmr_t   nibble3_chiplet_sel : 3;
+-              mmr_t   nibble3_nibble_sel  : 3;
+-              mmr_t   nibble2_chiplet_sel : 3;
+-              mmr_t   nibble2_nibble_sel  : 3;
+-              mmr_t   nibble1_chiplet_sel : 3;
+-              mmr_t   nibble1_nibble_sel  : 3;
+-              mmr_t   nibble0_chiplet_sel : 3;
+-              mmr_t   nibble0_nibble_sel  : 3;
++              mmr_t   nibble5_chiplet_sel : 3;
++              mmr_t   nibble6_nibble_sel  : 3;
++              mmr_t   nibble6_chiplet_sel : 3;
++              mmr_t   nibble7_nibble_sel  : 3;
++              mmr_t   nibble7_chiplet_sel : 3;
++              mmr_t   debug_ii_sel        : 3;
++              mmr_t   sel_ii              : 9;
++              mmr_t   reserved_0          : 3;
++              mmr_t   trigger_enable      : 1;
+       } sh_debug_select_s;
+ } sh_debug_select_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_TRIGGER_COMPARE_MASK"                  */
+ /*                      SHub Trigger Compare Mask                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_trigger_compare_mask_u {
+       mmr_t   sh_trigger_compare_mask_regval;
+       struct {
+@@ -18765,22 +10077,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_trigger_compare_mask_s;
+ } sh_trigger_compare_mask_u_t;
+-#else
+-typedef union sh_trigger_compare_mask_u {
+-      mmr_t   sh_trigger_compare_mask_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   mask        : 32;
+-      } sh_trigger_compare_mask_s;
+-} sh_trigger_compare_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_TRIGGER_COMPARE_PATTERN"                 */
+ /*                     SHub Trigger Compare Pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_trigger_compare_pattern_u {
+       mmr_t   sh_trigger_compare_pattern_regval;
+       struct {
+@@ -18788,22 +10090,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_trigger_compare_pattern_s;
+ } sh_trigger_compare_pattern_u_t;
+-#else
+-typedef union sh_trigger_compare_pattern_u {
+-      mmr_t   sh_trigger_compare_pattern_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   data        : 32;
+-      } sh_trigger_compare_pattern_s;
+-} sh_trigger_compare_pattern_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_TRIGGER_SEL"                       */
+ /*                  Trigger select for SHUB debug port                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_trigger_sel_u {
+       mmr_t   sh_trigger_sel_regval;
+       struct {
+@@ -18841,52 +10133,12 @@
+               mmr_t   reserved_15        : 1;
+       } sh_trigger_sel_s;
+ } sh_trigger_sel_u_t;
+-#else
+-typedef union sh_trigger_sel_u {
+-      mmr_t   sh_trigger_sel_regval;
+-      struct {
+-              mmr_t   reserved_15        : 1;
+-              mmr_t   nibble7_nibble_sel : 3;
+-              mmr_t   reserved_14        : 1;
+-              mmr_t   nibble7_input_sel  : 3;
+-              mmr_t   reserved_13        : 1;
+-              mmr_t   nibble6_nibble_sel : 3;
+-              mmr_t   reserved_12        : 1;
+-              mmr_t   nibble6_input_sel  : 3;
+-              mmr_t   reserved_11        : 1;
+-              mmr_t   nibble5_nibble_sel : 3;
+-              mmr_t   reserved_10        : 1;
+-              mmr_t   nibble5_input_sel  : 3;
+-              mmr_t   reserved_9         : 1;
+-              mmr_t   nibble4_nibble_sel : 3;
+-              mmr_t   reserved_8         : 1;
+-              mmr_t   nibble4_input_sel  : 3;
+-              mmr_t   reserved_7         : 1;
+-              mmr_t   nibble3_nibble_sel : 3;
+-              mmr_t   reserved_6         : 1;
+-              mmr_t   nibble3_input_sel  : 3;
+-              mmr_t   reserved_5         : 1;
+-              mmr_t   nibble2_nibble_sel : 3;
+-              mmr_t   reserved_4         : 1;
+-              mmr_t   nibble2_input_sel  : 3;
+-              mmr_t   reserved_3         : 1;
+-              mmr_t   nibble1_nibble_sel : 3;
+-              mmr_t   reserved_2         : 1;
+-              mmr_t   nibble1_input_sel  : 3;
+-              mmr_t   reserved_1         : 1;
+-              mmr_t   nibble0_nibble_sel : 3;
+-              mmr_t   reserved_0         : 1;
+-              mmr_t   nibble0_input_sel  : 3;
+-      } sh_trigger_sel_s;
+-} sh_trigger_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_STOP_CLK_CONTROL"                    */
+ /*                          Stop Clock Control                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_stop_clk_control_u {
+       mmr_t   sh_stop_clk_control_regval;
+       struct {
+@@ -18897,25 +10149,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_stop_clk_control_s;
+ } sh_stop_clk_control_u_t;
+-#else
+-typedef union sh_stop_clk_control_u {
+-      mmr_t   sh_stop_clk_control_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   mode        : 1;
+-              mmr_t   polarity    : 1;
+-              mmr_t   event       : 1;
+-              mmr_t   stimulus    : 5;
+-      } sh_stop_clk_control_s;
+-} sh_stop_clk_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_STOP_CLK_DELAY_PHASE"                  */
+ /*                        Stop Clock Delay Phase                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_stop_clk_delay_phase_u {
+       mmr_t   sh_stop_clk_delay_phase_regval;
+       struct {
+@@ -18923,43 +10162,24 @@
+               mmr_t   reserved_0  : 56;
+       } sh_stop_clk_delay_phase_s;
+ } sh_stop_clk_delay_phase_u_t;
+-#else
+-typedef union sh_stop_clk_delay_phase_u {
+-      mmr_t   sh_stop_clk_delay_phase_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   delay       : 8;
+-      } sh_stop_clk_delay_phase_s;
+-} sh_stop_clk_delay_phase_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_TSF_ARM_MASK"                      */
+ /*                 Trigger sequencing facility arm mask                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_tsf_arm_mask_u {
+-      mmr_t   sh_tsf_arm_mask_regval;
+-      struct {
+-              mmr_t   mask        : 64;
+-      } sh_tsf_arm_mask_s;
+-} sh_tsf_arm_mask_u_t;
+-#else
+ typedef union sh_tsf_arm_mask_u {
+       mmr_t   sh_tsf_arm_mask_regval;
+       struct {
+               mmr_t   mask        : 64;
+       } sh_tsf_arm_mask_s;
+ } sh_tsf_arm_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_TSF_COUNTER_PRESETS"                   */
+ /*             Trigger sequencing facility counter presets              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_counter_presets_u {
+       mmr_t   sh_tsf_counter_presets_regval;
+       struct {
+@@ -18969,24 +10189,12 @@
+               mmr_t   count_8a    : 8;
+       } sh_tsf_counter_presets_s;
+ } sh_tsf_counter_presets_u_t;
+-#else
+-typedef union sh_tsf_counter_presets_u {
+-      mmr_t   sh_tsf_counter_presets_regval;
+-      struct {
+-              mmr_t   count_8a    : 8;
+-              mmr_t   count_8b    : 8;
+-              mmr_t   count_16    : 16;
+-              mmr_t   count_32    : 32;
+-      } sh_tsf_counter_presets_s;
+-} sh_tsf_counter_presets_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_TSF_DECREMENT_CTL"                    */
+ /*        Trigger sequencing facility counter decrement control         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_decrement_ctl_u {
+       mmr_t   sh_tsf_decrement_ctl_regval;
+       struct {
+@@ -18994,22 +10202,12 @@
+               mmr_t   reserved_0  : 48;
+       } sh_tsf_decrement_ctl_s;
+ } sh_tsf_decrement_ctl_u_t;
+-#else
+-typedef union sh_tsf_decrement_ctl_u {
+-      mmr_t   sh_tsf_decrement_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 48;
+-              mmr_t   ctl         : 16;
+-      } sh_tsf_decrement_ctl_s;
+-} sh_tsf_decrement_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_TSF_DIAG_MSG_CTL"                    */
+ /*        Trigger sequencing facility diagnostic message control        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_diag_msg_ctl_u {
+       mmr_t   sh_tsf_diag_msg_ctl_regval;
+       struct {
+@@ -19017,43 +10215,24 @@
+               mmr_t   reserved_0  : 56;
+       } sh_tsf_diag_msg_ctl_s;
+ } sh_tsf_diag_msg_ctl_u_t;
+-#else
+-typedef union sh_tsf_diag_msg_ctl_u {
+-      mmr_t   sh_tsf_diag_msg_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   enable      : 8;
+-      } sh_tsf_diag_msg_ctl_s;
+-} sh_tsf_diag_msg_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_TSF_DISARM_MASK"                     */
+ /*               Trigger sequencing facility disarm mask                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_tsf_disarm_mask_u {
+-      mmr_t   sh_tsf_disarm_mask_regval;
+-      struct {
+-              mmr_t   mask        : 64;
+-      } sh_tsf_disarm_mask_s;
+-} sh_tsf_disarm_mask_u_t;
+-#else
+ typedef union sh_tsf_disarm_mask_u {
+       mmr_t   sh_tsf_disarm_mask_regval;
+       struct {
+               mmr_t   mask        : 64;
+       } sh_tsf_disarm_mask_s;
+ } sh_tsf_disarm_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_TSF_ENABLE_CTL"                     */
+ /*          Trigger sequencing facility counter enable control          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_enable_ctl_u {
+       mmr_t   sh_tsf_enable_ctl_regval;
+       struct {
+@@ -19061,22 +10240,12 @@
+               mmr_t   reserved_0  : 48;
+       } sh_tsf_enable_ctl_s;
+ } sh_tsf_enable_ctl_u_t;
+-#else
+-typedef union sh_tsf_enable_ctl_u {
+-      mmr_t   sh_tsf_enable_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 48;
+-              mmr_t   ctl         : 16;
+-      } sh_tsf_enable_ctl_s;
+-} sh_tsf_enable_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_TSF_SOFTWARE_ARM"                    */
+ /*               Trigger sequencing facility software arm               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_software_arm_u {
+       mmr_t   sh_tsf_software_arm_regval;
+       struct {
+@@ -19091,29 +10260,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_tsf_software_arm_s;
+ } sh_tsf_software_arm_u_t;
+-#else
+-typedef union sh_tsf_software_arm_u {
+-      mmr_t   sh_tsf_software_arm_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   bit7        : 1;
+-              mmr_t   bit6        : 1;
+-              mmr_t   bit5        : 1;
+-              mmr_t   bit4        : 1;
+-              mmr_t   bit3        : 1;
+-              mmr_t   bit2        : 1;
+-              mmr_t   bit1        : 1;
+-              mmr_t   bit0        : 1;
+-      } sh_tsf_software_arm_s;
+-} sh_tsf_software_arm_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_TSF_SOFTWARE_DISARM"                   */
+ /*             Trigger sequencing facility software disarm              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_software_disarm_u {
+       mmr_t   sh_tsf_software_disarm_regval;
+       struct {
+@@ -19128,29 +10280,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_tsf_software_disarm_s;
+ } sh_tsf_software_disarm_u_t;
+-#else
+-typedef union sh_tsf_software_disarm_u {
+-      mmr_t   sh_tsf_software_disarm_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   bit7        : 1;
+-              mmr_t   bit6        : 1;
+-              mmr_t   bit5        : 1;
+-              mmr_t   bit4        : 1;
+-              mmr_t   bit3        : 1;
+-              mmr_t   bit2        : 1;
+-              mmr_t   bit1        : 1;
+-              mmr_t   bit0        : 1;
+-      } sh_tsf_software_disarm_s;
+-} sh_tsf_software_disarm_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_TSF_SOFTWARE_TRIGGERED"                 */
+ /*            Trigger sequencing facility software triggered            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_software_triggered_u {
+       mmr_t   sh_tsf_software_triggered_regval;
+       struct {
+@@ -19165,71 +10300,36 @@
+               mmr_t   reserved_0  : 56;
+       } sh_tsf_software_triggered_s;
+ } sh_tsf_software_triggered_u_t;
+-#else
+-typedef union sh_tsf_software_triggered_u {
+-      mmr_t   sh_tsf_software_triggered_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   bit7        : 1;
+-              mmr_t   bit6        : 1;
+-              mmr_t   bit5        : 1;
+-              mmr_t   bit4        : 1;
+-              mmr_t   bit3        : 1;
+-              mmr_t   bit2        : 1;
+-              mmr_t   bit1        : 1;
+-              mmr_t   bit0        : 1;
+-      } sh_tsf_software_triggered_s;
+-} sh_tsf_software_triggered_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_TSF_TRIGGER_MASK"                    */
+ /*               Trigger sequencing facility trigger mask               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_tsf_trigger_mask_u {
+-      mmr_t   sh_tsf_trigger_mask_regval;
+-      struct {
+-              mmr_t   mask        : 64;
+-      } sh_tsf_trigger_mask_s;
+-} sh_tsf_trigger_mask_u_t;
+-#else
+ typedef union sh_tsf_trigger_mask_u {
+       mmr_t   sh_tsf_trigger_mask_regval;
+       struct {
+               mmr_t   mask        : 64;
+       } sh_tsf_trigger_mask_s;
+ } sh_tsf_trigger_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_VEC_DATA"                        */
+ /*                  Vector Write Request Message Data                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_data_u {
+-      mmr_t   sh_vec_data_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_vec_data_s;
+-} sh_vec_data_u_t;
+-#else
+ typedef union sh_vec_data_u {
+       mmr_t   sh_vec_data_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_vec_data_s;
+ } sh_vec_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_VEC_PARMS"                        */
+ /*                  Vector Message Parameters Register                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_vec_parms_u {
+       mmr_t   sh_vec_parms_regval;
+       struct {
+@@ -19243,133 +10343,72 @@
+               mmr_t   busy        : 1;
+       } sh_vec_parms_s;
+ } sh_vec_parms_u_t;
+-#else
+-typedef union sh_vec_parms_u {
+-      mmr_t   sh_vec_parms_regval;
+-      struct {
+-              mmr_t   busy        : 1;
+-              mmr_t   start       : 1;
+-              mmr_t   reserved_1  : 16;
+-              mmr_t   pio_id      : 11;
+-              mmr_t   address     : 32;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   ni_port     : 1;
+-              mmr_t   type        : 1;
+-      } sh_vec_parms_s;
+-} sh_vec_parms_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_VEC_ROUTE"                        */
+ /*                     Vector Request Message Route                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_route_u {
+-      mmr_t   sh_vec_route_regval;
+-      struct {
+-              mmr_t   route       : 64;
+-      } sh_vec_route_s;
+-} sh_vec_route_u_t;
+-#else
+ typedef union sh_vec_route_u {
+       mmr_t   sh_vec_route_regval;
+       struct {
+               mmr_t   route       : 64;
+       } sh_vec_route_s;
+ } sh_vec_route_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_CPU_PERM"                        */
+ /*                    CPU MMR Access Permission Bits                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_cpu_perm_u {
+       mmr_t   sh_cpu_perm_regval;
+       struct {
+               mmr_t   access_bits : 64;
+       } sh_cpu_perm_s;
+ } sh_cpu_perm_u_t;
+-#else
+-typedef union sh_cpu_perm_u {
+-      mmr_t   sh_cpu_perm_regval;
+-      struct {
+-              mmr_t   access_bits : 64;
+-      } sh_cpu_perm_s;
+-} sh_cpu_perm_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_CPU_PERM_OVR"                      */
+ /*                  CPU MMR Access Permission Override                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_cpu_perm_ovr_u {
+-      mmr_t   sh_cpu_perm_ovr_regval;
+-      struct {
+-              mmr_t   override    : 64;
+-      } sh_cpu_perm_ovr_s;
+-} sh_cpu_perm_ovr_u_t;
+-#else
+ typedef union sh_cpu_perm_ovr_u {
+       mmr_t   sh_cpu_perm_ovr_regval;
+       struct {
+               mmr_t   override    : 64;
+       } sh_cpu_perm_ovr_s;
+ } sh_cpu_perm_ovr_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_EXT_IO_PERM"                       */
+ /*                External IO MMR Access Permission Bits                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ext_io_perm_u {
+-      mmr_t   sh_ext_io_perm_regval;
+-      struct {
+-              mmr_t   access_bits : 64;
+-      } sh_ext_io_perm_s;
+-} sh_ext_io_perm_u_t;
+-#else
+ typedef union sh_ext_io_perm_u {
+       mmr_t   sh_ext_io_perm_regval;
+       struct {
+               mmr_t   access_bits : 64;
+       } sh_ext_io_perm_s;
+ } sh_ext_io_perm_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_EXT_IOI_ACCESS"                     */
+ /*             External IO Interrupt Access Permission Bits             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ext_ioi_access_u {
+-      mmr_t   sh_ext_ioi_access_regval;
+-      struct {
+-              mmr_t   access_bits : 64;
+-      } sh_ext_ioi_access_s;
+-} sh_ext_ioi_access_u_t;
+-#else
+ typedef union sh_ext_ioi_access_u {
+       mmr_t   sh_ext_ioi_access_regval;
+       struct {
+               mmr_t   access_bits : 64;
+       } sh_ext_ioi_access_s;
+ } sh_ext_ioi_access_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_GC_FIL_CTRL"                       */
+ /*                   SHub Global Clock Filter Control                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gc_fil_ctrl_u {
+       mmr_t   sh_gc_fil_ctrl_regval;
+       struct {
+@@ -19386,31 +10425,12 @@
+               mmr_t   reserved_4      : 6;
+       } sh_gc_fil_ctrl_s;
+ } sh_gc_fil_ctrl_u_t;
+-#else
+-typedef union sh_gc_fil_ctrl_u {
+-      mmr_t   sh_gc_fil_ctrl_regval;
+-      struct {
+-              mmr_t   reserved_4      : 6;
+-              mmr_t   error_counter   : 10;
+-              mmr_t   reserved_3      : 2;
+-              mmr_t   dropout_thresh  : 10;
+-              mmr_t   reserved_2      : 2;
+-              mmr_t   dropout_counter : 10;
+-              mmr_t   reserved_1      : 3;
+-              mmr_t   mask_enable     : 1;
+-              mmr_t   mask_counter    : 12;
+-              mmr_t   reserved_0      : 3;
+-              mmr_t   offset          : 5;
+-      } sh_gc_fil_ctrl_s;
+-} sh_gc_fil_ctrl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_GC_SRC_CTRL"                       */
+ /*                      SHub Global Clock Control                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_gc_src_ctrl_u {
+       mmr_t   sh_gc_src_ctrl_regval;
+       struct {
+@@ -19426,116 +10446,61 @@
+               mmr_t   reserved_4     : 30;
+       } sh_gc_src_ctrl_s;
+ } sh_gc_src_ctrl_u_t;
+-#else
+-typedef union sh_gc_src_ctrl_u {
+-      mmr_t   sh_gc_src_ctrl_regval;
+-      struct {
+-              mmr_t   reserved_4     : 30;
+-              mmr_t   source_sel     : 2;
+-              mmr_t   reserved_3     : 3;
+-              mmr_t   toggle_bit     : 1;
+-              mmr_t   reserved_2     : 2;
+-              mmr_t   counter        : 10;
+-              mmr_t   reserved_1     : 2;
+-              mmr_t   max_count      : 10;
+-              mmr_t   reserved_0     : 3;
+-              mmr_t   enable_counter : 1;
+-      } sh_gc_src_ctrl_s;
+-} sh_gc_src_ctrl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_HARD_RESET"                       */
+ /*                           SHub Hard Reset                            */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_hard_reset_u {
+-      mmr_t   sh_hard_reset_regval;
+-      struct {
+-              mmr_t   hard_reset  : 1;
+-              mmr_t   reserved_0  : 63;
+-      } sh_hard_reset_s;
+-} sh_hard_reset_u_t;
+-#else
++/* ==================================================================== */
++
+ typedef union sh_hard_reset_u {
+       mmr_t   sh_hard_reset_regval;
+       struct {
+-              mmr_t   reserved_0  : 63;
+               mmr_t   hard_reset  : 1;
++              mmr_t   reserved_0  : 63;
+       } sh_hard_reset_s;
+ } sh_hard_reset_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_IO_PERM"                         */
+ /*                    II MMR Access Permission Bits                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_io_perm_u {
+-      mmr_t   sh_io_perm_regval;
+-      struct {
+-              mmr_t   access_bits : 64;
+-      } sh_io_perm_s;
+-} sh_io_perm_u_t;
+-#else
+ typedef union sh_io_perm_u {
+       mmr_t   sh_io_perm_regval;
+       struct {
+               mmr_t   access_bits : 64;
+       } sh_io_perm_s;
+ } sh_io_perm_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_IOI_ACCESS"                       */
+ /*                 II Interrupt Access Permission Bits                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ioi_access_u {
+-      mmr_t   sh_ioi_access_regval;
+-      struct {
+-              mmr_t   access_bits : 64;
+-      } sh_ioi_access_s;
+-} sh_ioi_access_u_t;
+-#else
+ typedef union sh_ioi_access_u {
+       mmr_t   sh_ioi_access_regval;
+       struct {
+               mmr_t   access_bits : 64;
+       } sh_ioi_access_s;
+ } sh_ioi_access_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_IPI_ACCESS"                       */
+ /*                 CPU interrupt Access Permission Bits                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ipi_access_u {
+       mmr_t   sh_ipi_access_regval;
+       struct {
+               mmr_t   access_bits : 64;
+       } sh_ipi_access_s;
+ } sh_ipi_access_u_t;
+-#else
+-typedef union sh_ipi_access_u {
+-      mmr_t   sh_ipi_access_regval;
+-      struct {
+-              mmr_t   access_bits : 64;
+-      } sh_ipi_access_s;
+-} sh_ipi_access_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_JTAG_CONFIG"                       */
+ /*                       SHub JTAG configuration                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_jtag_config_u {
+       mmr_t   sh_jtag_config_regval;
+       struct {
+@@ -19559,38 +10524,12 @@
+               mmr_t   reserved_0                    : 8;
+       } sh_jtag_config_s;
+ } sh_jtag_config_u_t;
+-#else
+-typedef union sh_jtag_config_u {
+-      mmr_t   sh_jtag_config_regval;
+-      struct {
+-              mmr_t   reserved_0                    : 8;
+-              mmr_t   gtl_config_re                 : 1;
+-              mmr_t   fsb_config_aux                : 2;
+-              mmr_t   fsb_config_enable_bist        : 1;
+-              mmr_t   fsb_config_output_tristate    : 4;
+-              mmr_t   fsb_config_clock_ratio        : 5;
+-              mmr_t   fsb_config_enable_bus_parking : 1;
+-              mmr_t   fsb_config_sample_binit       : 1;
+-              mmr_t   fsb_config_ioq_depth          : 1;
+-              mmr_t   jtag_mci_override             : 1;
+-              mmr_t   jtag_mci_target               : 14;
+-              mmr_t   jtag_mci_reset_delay          : 4;
+-              mmr_t   wrt90_override                : 1;
+-              mmr_t   wrt90_overrider               : 1;
+-              mmr_t   wrt90_target                  : 14;
+-              mmr_t   ii_clk_sel                    : 2;
+-              mmr_t   ni_clk_sel                    : 1;
+-              mmr_t   md_clk_sel                    : 2;
+-      } sh_jtag_config_s;
+-} sh_jtag_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_SHUB_ID"                         */
+ /*                            SHub ID Number                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_shub_id_u {
+       mmr_t   sh_shub_id_regval;
+       struct {
+@@ -19608,116 +10547,60 @@
+               mmr_t   reserved_3    : 7;
+       } sh_shub_id_s;
+ } sh_shub_id_u_t;
+-#else
+-typedef union sh_shub_id_u {
+-      mmr_t   sh_shub_id_regval;
+-      struct {
+-              mmr_t   reserved_3    : 7;
+-              mmr_t   ni_port       : 1;
+-              mmr_t   reserved_2    : 3;
+-              mmr_t   nodes_per_bit : 5;
+-              mmr_t   reserved_1    : 2;
+-              mmr_t   sharing_mode  : 2;
+-              mmr_t   reserved_0    : 1;
+-              mmr_t   node_id       : 11;
+-              mmr_t   revision      : 4;
+-              mmr_t   part_number   : 16;
+-              mmr_t   manufacturer  : 11;
+-              mmr_t   force1        : 1;
+-      } sh_shub_id_s;
+-} sh_shub_id_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_SHUBS_PRESENT0"                     */
+ /*         Shubs 0 - 63 Present. Used for invalidate generation         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_shubs_present0_u {
+-      mmr_t   sh_shubs_present0_regval;
+-      struct {
+-              mmr_t   shubs_present0 : 64;
+-      } sh_shubs_present0_s;
+-} sh_shubs_present0_u_t;
+-#else
+ typedef union sh_shubs_present0_u {
+       mmr_t   sh_shubs_present0_regval;
+       struct {
+               mmr_t   shubs_present0 : 64;
+       } sh_shubs_present0_s;
+ } sh_shubs_present0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_SHUBS_PRESENT1"                     */
+ /*        Shubs 64 - 127 Present. Used for invalidate generation        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_shubs_present1_u {
+-      mmr_t   sh_shubs_present1_regval;
+-      struct {
+-              mmr_t   shubs_present1 : 64;
+-      } sh_shubs_present1_s;
+-} sh_shubs_present1_u_t;
+-#else
+ typedef union sh_shubs_present1_u {
+       mmr_t   sh_shubs_present1_regval;
+       struct {
+               mmr_t   shubs_present1 : 64;
+       } sh_shubs_present1_s;
+ } sh_shubs_present1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_SHUBS_PRESENT2"                     */
+ /*       Shubs 128 - 191 Present. Used for invalidate generation        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_shubs_present2_u {
+-      mmr_t   sh_shubs_present2_regval;
+-      struct {
+-              mmr_t   shubs_present2 : 64;
+-      } sh_shubs_present2_s;
+-} sh_shubs_present2_u_t;
+-#else
+ typedef union sh_shubs_present2_u {
+       mmr_t   sh_shubs_present2_regval;
+       struct {
+               mmr_t   shubs_present2 : 64;
+       } sh_shubs_present2_s;
+ } sh_shubs_present2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_SHUBS_PRESENT3"                     */
+ /*       Shubs 192 - 255 Present. Used for invalidate generation        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_shubs_present3_u {
+       mmr_t   sh_shubs_present3_regval;
+       struct {
+               mmr_t   shubs_present3 : 64;
+       } sh_shubs_present3_s;
+ } sh_shubs_present3_u_t;
+-#else
+-typedef union sh_shubs_present3_u {
+-      mmr_t   sh_shubs_present3_regval;
+-      struct {
+-              mmr_t   shubs_present3 : 64;
+-      } sh_shubs_present3_s;
+-} sh_shubs_present3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_SOFT_RESET"                       */
+ /*                           SHub Soft Reset                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_soft_reset_u {
+       mmr_t   sh_soft_reset_regval;
+       struct {
+@@ -19725,22 +10608,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_soft_reset_s;
+ } sh_soft_reset_u_t;
+-#else
+-typedef union sh_soft_reset_u {
+-      mmr_t   sh_soft_reset_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   soft_reset  : 1;
+-      } sh_soft_reset_s;
+-} sh_soft_reset_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_FIRST_ERROR"                       */
+ /*                    Shub Global First Error Flags                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_first_error_u {
+       mmr_t   sh_first_error_regval;
+       struct {
+@@ -19748,22 +10621,12 @@
+               mmr_t   reserved_0  : 45;
+       } sh_first_error_s;
+ } sh_first_error_u_t;
+-#else
+-typedef union sh_first_error_u {
+-      mmr_t   sh_first_error_regval;
+-      struct {
+-              mmr_t   reserved_0  : 45;
+-              mmr_t   first_error : 19;
+-      } sh_first_error_s;
+-} sh_first_error_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_II_HW_TIME_STAMP"                    */
+ /*                     II hardware error time stamp                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_hw_time_stamp_u {
+       mmr_t   sh_ii_hw_time_stamp_regval;
+       struct {
+@@ -19771,22 +10634,12 @@
+               mmr_t   valid       : 1;
+       } sh_ii_hw_time_stamp_s;
+ } sh_ii_hw_time_stamp_u_t;
+-#else
+-typedef union sh_ii_hw_time_stamp_u {
+-      mmr_t   sh_ii_hw_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_ii_hw_time_stamp_s;
+-} sh_ii_hw_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_LB_HW_TIME_STAMP"                    */
+ /*                     LB hardware error time stamp                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_hw_time_stamp_u {
+       mmr_t   sh_lb_hw_time_stamp_regval;
+       struct {
+@@ -19794,22 +10647,12 @@
+               mmr_t   valid       : 1;
+       } sh_lb_hw_time_stamp_s;
+ } sh_lb_hw_time_stamp_u_t;
+-#else
+-typedef union sh_lb_hw_time_stamp_u {
+-      mmr_t   sh_lb_hw_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_lb_hw_time_stamp_s;
+-} sh_lb_hw_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_COR_TIME_STAMP"                    */
+ /*                   MD correctable error time stamp                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_cor_time_stamp_u {
+       mmr_t   sh_md_cor_time_stamp_regval;
+       struct {
+@@ -19817,22 +10660,12 @@
+               mmr_t   valid       : 1;
+       } sh_md_cor_time_stamp_s;
+ } sh_md_cor_time_stamp_u_t;
+-#else
+-typedef union sh_md_cor_time_stamp_u {
+-      mmr_t   sh_md_cor_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_md_cor_time_stamp_s;
+-} sh_md_cor_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_MD_HW_TIME_STAMP"                    */
+ /*                     MD hardware error time stamp                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_hw_time_stamp_u {
+       mmr_t   sh_md_hw_time_stamp_regval;
+       struct {
+@@ -19840,22 +10673,12 @@
+               mmr_t   valid       : 1;
+       } sh_md_hw_time_stamp_s;
+ } sh_md_hw_time_stamp_u_t;
+-#else
+-typedef union sh_md_hw_time_stamp_u {
+-      mmr_t   sh_md_hw_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_md_hw_time_stamp_s;
+-} sh_md_hw_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_UNCOR_TIME_STAMP"                   */
+ /*                  MD uncorrectable error time stamp                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_uncor_time_stamp_u {
+       mmr_t   sh_md_uncor_time_stamp_regval;
+       struct {
+@@ -19863,22 +10686,12 @@
+               mmr_t   valid       : 1;
+       } sh_md_uncor_time_stamp_s;
+ } sh_md_uncor_time_stamp_u_t;
+-#else
+-typedef union sh_md_uncor_time_stamp_u {
+-      mmr_t   sh_md_uncor_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_md_uncor_time_stamp_s;
+-} sh_md_uncor_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PI_COR_TIME_STAMP"                    */
+ /*                   PI correctable error time stamp                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_cor_time_stamp_u {
+       mmr_t   sh_pi_cor_time_stamp_regval;
+       struct {
+@@ -19886,22 +10699,12 @@
+               mmr_t   valid       : 1;
+       } sh_pi_cor_time_stamp_s;
+ } sh_pi_cor_time_stamp_u_t;
+-#else
+-typedef union sh_pi_cor_time_stamp_u {
+-      mmr_t   sh_pi_cor_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_pi_cor_time_stamp_s;
+-} sh_pi_cor_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_PI_HW_TIME_STAMP"                    */
+ /*                     PI hardware error time stamp                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_hw_time_stamp_u {
+       mmr_t   sh_pi_hw_time_stamp_regval;
+       struct {
+@@ -19909,22 +10712,12 @@
+               mmr_t   valid       : 1;
+       } sh_pi_hw_time_stamp_s;
+ } sh_pi_hw_time_stamp_u_t;
+-#else
+-typedef union sh_pi_hw_time_stamp_u {
+-      mmr_t   sh_pi_hw_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_pi_hw_time_stamp_s;
+-} sh_pi_hw_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PI_UNCOR_TIME_STAMP"                   */
+ /*                  PI uncorrectable error time stamp                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_uncor_time_stamp_u {
+       mmr_t   sh_pi_uncor_time_stamp_regval;
+       struct {
+@@ -19932,22 +10725,12 @@
+               mmr_t   valid       : 1;
+       } sh_pi_uncor_time_stamp_s;
+ } sh_pi_uncor_time_stamp_u_t;
+-#else
+-typedef union sh_pi_uncor_time_stamp_u {
+-      mmr_t   sh_pi_uncor_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_pi_uncor_time_stamp_s;
+-} sh_pi_uncor_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC0_ADV_TIME_STAMP"                  */
+ /*                      Proc 0 advisory time stamp                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_adv_time_stamp_u {
+       mmr_t   sh_proc0_adv_time_stamp_regval;
+       struct {
+@@ -19955,22 +10738,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc0_adv_time_stamp_s;
+ } sh_proc0_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc0_adv_time_stamp_u {
+-      mmr_t   sh_proc0_adv_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc0_adv_time_stamp_s;
+-} sh_proc0_adv_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC0_ERR_TIME_STAMP"                  */
+ /*                       Proc 0 error time stamp                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc0_err_time_stamp_u {
+       mmr_t   sh_proc0_err_time_stamp_regval;
+       struct {
+@@ -19978,22 +10751,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc0_err_time_stamp_s;
+ } sh_proc0_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc0_err_time_stamp_u {
+-      mmr_t   sh_proc0_err_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc0_err_time_stamp_s;
+-} sh_proc0_err_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC1_ADV_TIME_STAMP"                  */
+ /*                      Proc 1 advisory time stamp                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_adv_time_stamp_u {
+       mmr_t   sh_proc1_adv_time_stamp_regval;
+       struct {
+@@ -20001,22 +10764,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc1_adv_time_stamp_s;
+ } sh_proc1_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc1_adv_time_stamp_u {
+-      mmr_t   sh_proc1_adv_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc1_adv_time_stamp_s;
+-} sh_proc1_adv_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC1_ERR_TIME_STAMP"                  */
+ /*                       Proc 1 error time stamp                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc1_err_time_stamp_u {
+       mmr_t   sh_proc1_err_time_stamp_regval;
+       struct {
+@@ -20024,22 +10777,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc1_err_time_stamp_s;
+ } sh_proc1_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc1_err_time_stamp_u {
+-      mmr_t   sh_proc1_err_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc1_err_time_stamp_s;
+-} sh_proc1_err_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC2_ADV_TIME_STAMP"                  */
+ /*                      Proc 2 advisory time stamp                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_adv_time_stamp_u {
+       mmr_t   sh_proc2_adv_time_stamp_regval;
+       struct {
+@@ -20047,22 +10790,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc2_adv_time_stamp_s;
+ } sh_proc2_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc2_adv_time_stamp_u {
+-      mmr_t   sh_proc2_adv_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc2_adv_time_stamp_s;
+-} sh_proc2_adv_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC2_ERR_TIME_STAMP"                  */
+ /*                       Proc 2 error time stamp                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc2_err_time_stamp_u {
+       mmr_t   sh_proc2_err_time_stamp_regval;
+       struct {
+@@ -20070,22 +10803,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc2_err_time_stamp_s;
+ } sh_proc2_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc2_err_time_stamp_u {
+-      mmr_t   sh_proc2_err_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc2_err_time_stamp_s;
+-} sh_proc2_err_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC3_ADV_TIME_STAMP"                  */
+ /*                      Proc 3 advisory time stamp                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_adv_time_stamp_u {
+       mmr_t   sh_proc3_adv_time_stamp_regval;
+       struct {
+@@ -20093,22 +10816,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc3_adv_time_stamp_s;
+ } sh_proc3_adv_time_stamp_u_t;
+-#else
+-typedef union sh_proc3_adv_time_stamp_u {
+-      mmr_t   sh_proc3_adv_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc3_adv_time_stamp_s;
+-} sh_proc3_adv_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROC3_ERR_TIME_STAMP"                  */
+ /*                       Proc 3 error time stamp                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_proc3_err_time_stamp_u {
+       mmr_t   sh_proc3_err_time_stamp_regval;
+       struct {
+@@ -20116,22 +10829,12 @@
+               mmr_t   valid       : 1;
+       } sh_proc3_err_time_stamp_s;
+ } sh_proc3_err_time_stamp_u_t;
+-#else
+-typedef union sh_proc3_err_time_stamp_u {
+-      mmr_t   sh_proc3_err_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_proc3_err_time_stamp_s;
+-} sh_proc3_err_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_XN_COR_TIME_STAMP"                    */
+ /*                   XN correctable error time stamp                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_cor_time_stamp_u {
+       mmr_t   sh_xn_cor_time_stamp_regval;
+       struct {
+@@ -20139,22 +10842,12 @@
+               mmr_t   valid       : 1;
+       } sh_xn_cor_time_stamp_s;
+ } sh_xn_cor_time_stamp_u_t;
+-#else
+-typedef union sh_xn_cor_time_stamp_u {
+-      mmr_t   sh_xn_cor_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_xn_cor_time_stamp_s;
+-} sh_xn_cor_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_HW_TIME_STAMP"                    */
+ /*                     XN hardware error time stamp                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_hw_time_stamp_u {
+       mmr_t   sh_xn_hw_time_stamp_regval;
+       struct {
+@@ -20162,22 +10855,12 @@
+               mmr_t   valid       : 1;
+       } sh_xn_hw_time_stamp_s;
+ } sh_xn_hw_time_stamp_u_t;
+-#else
+-typedef union sh_xn_hw_time_stamp_u {
+-      mmr_t   sh_xn_hw_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_xn_hw_time_stamp_s;
+-} sh_xn_hw_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_XN_UNCOR_TIME_STAMP"                   */
+ /*                  XN uncorrectable error time stamp                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_uncor_time_stamp_u {
+       mmr_t   sh_xn_uncor_time_stamp_regval;
+       struct {
+@@ -20185,22 +10868,12 @@
+               mmr_t   valid       : 1;
+       } sh_xn_uncor_time_stamp_s;
+ } sh_xn_uncor_time_stamp_u_t;
+-#else
+-typedef union sh_xn_uncor_time_stamp_u {
+-      mmr_t   sh_xn_uncor_time_stamp_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   time        : 63;
+-      } sh_xn_uncor_time_stamp_s;
+-} sh_xn_uncor_time_stamp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_DEBUG_PORT"                       */
+ /*                           SHub Debug Port                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_debug_port_u {
+       mmr_t   sh_debug_port_regval;
+       struct {
+@@ -20215,52 +10888,25 @@
+               mmr_t   reserved_0    : 32;
+       } sh_debug_port_s;
+ } sh_debug_port_u_t;
+-#else
+-typedef union sh_debug_port_u {
+-      mmr_t   sh_debug_port_regval;
+-      struct {
+-              mmr_t   reserved_0    : 32;
+-              mmr_t   debug_nibble7 : 4;
+-              mmr_t   debug_nibble6 : 4;
+-              mmr_t   debug_nibble5 : 4;
+-              mmr_t   debug_nibble4 : 4;
+-              mmr_t   debug_nibble3 : 4;
+-              mmr_t   debug_nibble2 : 4;
+-              mmr_t   debug_nibble1 : 4;
+-              mmr_t   debug_nibble0 : 4;
+-      } sh_debug_port_s;
+-} sh_debug_port_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_II_DEBUG_DATA"                      */
+ /*                            II Debug Data                             */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_ii_debug_data_u {
+-      mmr_t   sh_ii_debug_data_regval;
+-      struct {
+-              mmr_t   ii_data     : 32;
+-              mmr_t   reserved_0  : 32;
+-      } sh_ii_debug_data_s;
+-} sh_ii_debug_data_u_t;
+-#else
++/* ==================================================================== */
++
+ typedef union sh_ii_debug_data_u {
+       mmr_t   sh_ii_debug_data_regval;
+       struct {
+-              mmr_t   reserved_0  : 32;
+               mmr_t   ii_data     : 32;
++              mmr_t   reserved_0  : 32;
+       } sh_ii_debug_data_s;
+ } sh_ii_debug_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_II_WRAP_DEBUG_DATA"                   */
+ /*                      SHub II Wrapper Debug Data                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ii_wrap_debug_data_u {
+       mmr_t   sh_ii_wrap_debug_data_regval;
+       struct {
+@@ -20268,22 +10914,12 @@
+               mmr_t   reserved_0   : 32;
+       } sh_ii_wrap_debug_data_s;
+ } sh_ii_wrap_debug_data_u_t;
+-#else
+-typedef union sh_ii_wrap_debug_data_u {
+-      mmr_t   sh_ii_wrap_debug_data_regval;
+-      struct {
+-              mmr_t   reserved_0   : 32;
+-              mmr_t   ii_wrap_data : 32;
+-      } sh_ii_wrap_debug_data_s;
+-} sh_ii_wrap_debug_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_LB_DEBUG_DATA"                      */
+ /*                          SHub LB Debug Data                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_lb_debug_data_u {
+       mmr_t   sh_lb_debug_data_regval;
+       struct {
+@@ -20291,22 +10927,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_lb_debug_data_s;
+ } sh_lb_debug_data_u_t;
+-#else
+-typedef union sh_lb_debug_data_u {
+-      mmr_t   sh_lb_debug_data_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   lb_data     : 32;
+-      } sh_lb_debug_data_s;
+-} sh_lb_debug_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_MD_DEBUG_DATA"                      */
+ /*                          SHub MD Debug Data                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_debug_data_u {
+       mmr_t   sh_md_debug_data_regval;
+       struct {
+@@ -20314,22 +10940,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_md_debug_data_s;
+ } sh_md_debug_data_u_t;
+-#else
+-typedef union sh_md_debug_data_u {
+-      mmr_t   sh_md_debug_data_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   md_data     : 32;
+-      } sh_md_debug_data_s;
+-} sh_md_debug_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PI_DEBUG_DATA"                      */
+ /*                          SHub PI Debug Data                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_debug_data_u {
+       mmr_t   sh_pi_debug_data_regval;
+       struct {
+@@ -20337,22 +10953,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_pi_debug_data_s;
+ } sh_pi_debug_data_u_t;
+-#else
+-typedef union sh_pi_debug_data_u {
+-      mmr_t   sh_pi_debug_data_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   pi_data     : 32;
+-      } sh_pi_debug_data_s;
+-} sh_pi_debug_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_XN_DEBUG_DATA"                      */
+ /*                          SHub XN Debug Data                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_debug_data_u {
+       mmr_t   sh_xn_debug_data_regval;
+       struct {
+@@ -20360,22 +10966,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_xn_debug_data_s;
+ } sh_xn_debug_data_u_t;
+-#else
+-typedef union sh_xn_debug_data_u {
+-      mmr_t   sh_xn_debug_data_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   xn_data     : 32;
+-      } sh_xn_debug_data_s;
+-} sh_xn_debug_data_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_TSF_ARMED_STATE"                     */
+ /*                Trigger sequencing facility arm state                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_armed_state_u {
+       mmr_t   sh_tsf_armed_state_regval;
+       struct {
+@@ -20383,22 +10979,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_tsf_armed_state_s;
+ } sh_tsf_armed_state_u_t;
+-#else
+-typedef union sh_tsf_armed_state_u {
+-      mmr_t   sh_tsf_armed_state_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   state       : 8;
+-      } sh_tsf_armed_state_s;
+-} sh_tsf_armed_state_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_TSF_COUNTER_VALUE"                    */
+ /*              Trigger sequencing facility counter value               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_counter_value_u {
+       mmr_t   sh_tsf_counter_value_regval;
+       struct {
+@@ -20408,24 +10994,12 @@
+               mmr_t   count_8a    : 8;
+       } sh_tsf_counter_value_s;
+ } sh_tsf_counter_value_u_t;
+-#else
+-typedef union sh_tsf_counter_value_u {
+-      mmr_t   sh_tsf_counter_value_regval;
+-      struct {
+-              mmr_t   count_8a    : 8;
+-              mmr_t   count_8b    : 8;
+-              mmr_t   count_16    : 16;
+-              mmr_t   count_32    : 32;
+-      } sh_tsf_counter_value_s;
+-} sh_tsf_counter_value_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_TSF_TRIGGERED_STATE"                   */
+ /*             Trigger sequencing facility triggered state              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_tsf_triggered_state_u {
+       mmr_t   sh_tsf_triggered_state_regval;
+       struct {
+@@ -20433,64 +11007,36 @@
+               mmr_t   reserved_0  : 56;
+       } sh_tsf_triggered_state_s;
+ } sh_tsf_triggered_state_u_t;
+-#else
+-typedef union sh_tsf_triggered_state_u {
+-      mmr_t   sh_tsf_triggered_state_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   state       : 8;
+-      } sh_tsf_triggered_state_s;
+-} sh_tsf_triggered_state_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_VEC_RDDATA"                       */
+ /*                      Vector Reply Message Data                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_rddata_u {
+-      mmr_t   sh_vec_rddata_regval;
+-      struct {
+-              mmr_t   data        : 64;
+-      } sh_vec_rddata_s;
+-} sh_vec_rddata_u_t;
+-#else
+ typedef union sh_vec_rddata_u {
+       mmr_t   sh_vec_rddata_regval;
+       struct {
+               mmr_t   data        : 64;
+       } sh_vec_rddata_s;
+ } sh_vec_rddata_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_VEC_RETURN"                       */
+ /*                  Vector Reply Message Return Route                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_vec_return_u {
+-      mmr_t   sh_vec_return_regval;
+-      struct {
+-              mmr_t   route       : 64;
+-      } sh_vec_return_s;
+-} sh_vec_return_u_t;
+-#else
+ typedef union sh_vec_return_u {
+       mmr_t   sh_vec_return_regval;
+       struct {
+               mmr_t   route       : 64;
+       } sh_vec_return_s;
+ } sh_vec_return_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_VEC_STATUS"                       */
+ /*                     Vector Reply Message Status                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_vec_status_u {
+       mmr_t   sh_vec_status_regval;
+       struct {
+@@ -20503,27 +11049,12 @@
+               mmr_t   status_valid : 1;
+       } sh_vec_status_s;
+ } sh_vec_status_u_t;
+-#else
+-typedef union sh_vec_status_u {
+-      mmr_t   sh_vec_status_regval;
+-      struct {
+-              mmr_t   status_valid : 1;
+-              mmr_t   overrun      : 1;
+-              mmr_t   reserved_0   : 2;
+-              mmr_t   source       : 14;
+-              mmr_t   pio_id       : 11;
+-              mmr_t   address      : 32;
+-              mmr_t   type         : 3;
+-      } sh_vec_status_s;
+-} sh_vec_status_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT0_CONTROL"               */
+ /*                    Performance Counter 0 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count0_control_u {
+       mmr_t   sh_performance_count0_control_regval;
+       struct {
+@@ -20541,32 +11072,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count0_control_s;
+ } sh_performance_count0_control_u_t;
+-#else
+-typedef union sh_performance_count0_control_u {
+-      mmr_t   sh_performance_count0_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count0_control_s;
+-} sh_performance_count0_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT1_CONTROL"               */
+ /*                    Performance Counter 1 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count1_control_u {
+       mmr_t   sh_performance_count1_control_regval;
+       struct {
+@@ -20584,32 +11095,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count1_control_s;
+ } sh_performance_count1_control_u_t;
+-#else
+-typedef union sh_performance_count1_control_u {
+-      mmr_t   sh_performance_count1_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count1_control_s;
+-} sh_performance_count1_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT2_CONTROL"               */
+ /*                    Performance Counter 2 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count2_control_u {
+       mmr_t   sh_performance_count2_control_regval;
+       struct {
+@@ -20627,32 +11118,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count2_control_s;
+ } sh_performance_count2_control_u_t;
+-#else
+-typedef union sh_performance_count2_control_u {
+-      mmr_t   sh_performance_count2_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count2_control_s;
+-} sh_performance_count2_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT3_CONTROL"               */
+ /*                    Performance Counter 3 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count3_control_u {
+       mmr_t   sh_performance_count3_control_regval;
+       struct {
+@@ -20670,32 +11141,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count3_control_s;
+ } sh_performance_count3_control_u_t;
+-#else
+-typedef union sh_performance_count3_control_u {
+-      mmr_t   sh_performance_count3_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count3_control_s;
+-} sh_performance_count3_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT4_CONTROL"               */
+ /*                    Performance Counter 4 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count4_control_u {
+       mmr_t   sh_performance_count4_control_regval;
+       struct {
+@@ -20713,32 +11164,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count4_control_s;
+ } sh_performance_count4_control_u_t;
+-#else
+-typedef union sh_performance_count4_control_u {
+-      mmr_t   sh_performance_count4_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count4_control_s;
+-} sh_performance_count4_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT5_CONTROL"               */
+ /*                    Performance Counter 5 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count5_control_u {
+       mmr_t   sh_performance_count5_control_regval;
+       struct {
+@@ -20756,32 +11187,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count5_control_s;
+ } sh_performance_count5_control_u_t;
+-#else
+-typedef union sh_performance_count5_control_u {
+-      mmr_t   sh_performance_count5_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count5_control_s;
+-} sh_performance_count5_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT6_CONTROL"               */
+ /*                    Performance Counter 6 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count6_control_u {
+       mmr_t   sh_performance_count6_control_regval;
+       struct {
+@@ -20799,32 +11210,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count6_control_s;
+ } sh_performance_count6_control_u_t;
+-#else
+-typedef union sh_performance_count6_control_u {
+-      mmr_t   sh_performance_count6_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count6_control_s;
+-} sh_performance_count6_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_PERFORMANCE_COUNT7_CONTROL"               */
+ /*                    Performance Counter 7 Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_count7_control_u {
+       mmr_t   sh_performance_count7_control_regval;
+       struct {
+@@ -20842,32 +11233,12 @@
+               mmr_t   reserved_0      : 45;
+       } sh_performance_count7_control_s;
+ } sh_performance_count7_control_u_t;
+-#else
+-typedef union sh_performance_count7_control_u {
+-      mmr_t   sh_performance_count7_control_regval;
+-      struct {
+-              mmr_t   reserved_0      : 45;
+-              mmr_t   peak_det_enable : 1;
+-              mmr_t   dec_enable      : 1;
+-              mmr_t   inc_enable      : 1;
+-              mmr_t   dn_mode         : 1;
+-              mmr_t   dn_polarity     : 1;
+-              mmr_t   dn_event        : 1;
+-              mmr_t   dn_stimulus     : 5;
+-              mmr_t   up_mode         : 1;
+-              mmr_t   up_polarity     : 1;
+-              mmr_t   up_event        : 1;
+-              mmr_t   up_stimulus     : 5;
+-      } sh_performance_count7_control_s;
+-} sh_performance_count7_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PROFILE_DN_CONTROL"                   */
+ /*                     Profile Counter Down Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_dn_control_u {
+       mmr_t   sh_profile_dn_control_regval;
+       struct {
+@@ -20878,25 +11249,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_profile_dn_control_s;
+ } sh_profile_dn_control_u_t;
+-#else
+-typedef union sh_profile_dn_control_u {
+-      mmr_t   sh_profile_dn_control_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   mode        : 1;
+-              mmr_t   polarity    : 1;
+-              mmr_t   event       : 1;
+-              mmr_t   stimulus    : 5;
+-      } sh_profile_dn_control_s;
+-} sh_profile_dn_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PROFILE_PEAK_CONTROL"                  */
+ /*                     Profile Counter Peak Control                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_peak_control_u {
+       mmr_t   sh_profile_peak_control_regval;
+       struct {
+@@ -20908,26 +11266,12 @@
+               mmr_t   reserved_2  : 57;
+       } sh_profile_peak_control_s;
+ } sh_profile_peak_control_u_t;
+-#else
+-typedef union sh_profile_peak_control_u {
+-      mmr_t   sh_profile_peak_control_regval;
+-      struct {
+-              mmr_t   reserved_2  : 57;
+-              mmr_t   polarity    : 1;
+-              mmr_t   event       : 1;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   stimulus    : 1;
+-              mmr_t   reserved_0  : 3;
+-      } sh_profile_peak_control_s;
+-} sh_profile_peak_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PROFILE_RANGE"                      */
+ /*                        Profile Counter Range                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_range_u {
+       mmr_t   sh_profile_range_regval;
+       struct {
+@@ -20941,28 +11285,12 @@
+               mmr_t   range7      : 8;
+       } sh_profile_range_s;
+ } sh_profile_range_u_t;
+-#else
+-typedef union sh_profile_range_u {
+-      mmr_t   sh_profile_range_regval;
+-      struct {
+-              mmr_t   range7      : 8;
+-              mmr_t   range6      : 8;
+-              mmr_t   range5      : 8;
+-              mmr_t   range4      : 8;
+-              mmr_t   range3      : 8;
+-              mmr_t   range2      : 8;
+-              mmr_t   range1      : 8;
+-              mmr_t   range0      : 8;
+-      } sh_profile_range_s;
+-} sh_profile_range_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PROFILE_UP_CONTROL"                   */
+ /*                      Profile Counter Up Control                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_up_control_u {
+       mmr_t   sh_profile_up_control_regval;
+       struct {
+@@ -20973,25 +11301,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_profile_up_control_s;
+ } sh_profile_up_control_u_t;
+-#else
+-typedef union sh_profile_up_control_u {
+-      mmr_t   sh_profile_up_control_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   mode        : 1;
+-              mmr_t   polarity    : 1;
+-              mmr_t   event       : 1;
+-              mmr_t   stimulus    : 5;
+-      } sh_profile_up_control_s;
+-} sh_profile_up_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER0"                  */
+ /*                        Performance Counter 0                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter0_u {
+       mmr_t   sh_performance_counter0_regval;
+       struct {
+@@ -20999,22 +11314,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter0_s;
+ } sh_performance_counter0_u_t;
+-#else
+-typedef union sh_performance_counter0_u {
+-      mmr_t   sh_performance_counter0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter0_s;
+-} sh_performance_counter0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER1"                  */
+ /*                        Performance Counter 1                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter1_u {
+       mmr_t   sh_performance_counter1_regval;
+       struct {
+@@ -21022,22 +11327,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter1_s;
+ } sh_performance_counter1_u_t;
+-#else
+-typedef union sh_performance_counter1_u {
+-      mmr_t   sh_performance_counter1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter1_s;
+-} sh_performance_counter1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER2"                  */
+ /*                        Performance Counter 2                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter2_u {
+       mmr_t   sh_performance_counter2_regval;
+       struct {
+@@ -21045,22 +11340,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter2_s;
+ } sh_performance_counter2_u_t;
+-#else
+-typedef union sh_performance_counter2_u {
+-      mmr_t   sh_performance_counter2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter2_s;
+-} sh_performance_counter2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER3"                  */
+ /*                        Performance Counter 3                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter3_u {
+       mmr_t   sh_performance_counter3_regval;
+       struct {
+@@ -21068,22 +11353,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter3_s;
+ } sh_performance_counter3_u_t;
+-#else
+-typedef union sh_performance_counter3_u {
+-      mmr_t   sh_performance_counter3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter3_s;
+-} sh_performance_counter3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER4"                  */
+ /*                        Performance Counter 4                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter4_u {
+       mmr_t   sh_performance_counter4_regval;
+       struct {
+@@ -21091,22 +11366,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter4_s;
+ } sh_performance_counter4_u_t;
+-#else
+-typedef union sh_performance_counter4_u {
+-      mmr_t   sh_performance_counter4_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter4_s;
+-} sh_performance_counter4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER5"                  */
+ /*                        Performance Counter 5                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter5_u {
+       mmr_t   sh_performance_counter5_regval;
+       struct {
+@@ -21114,22 +11379,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter5_s;
+ } sh_performance_counter5_u_t;
+-#else
+-typedef union sh_performance_counter5_u {
+-      mmr_t   sh_performance_counter5_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter5_s;
+-} sh_performance_counter5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER6"                  */
+ /*                        Performance Counter 6                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter6_u {
+       mmr_t   sh_performance_counter6_regval;
+       struct {
+@@ -21137,22 +11392,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter6_s;
+ } sh_performance_counter6_u_t;
+-#else
+-typedef union sh_performance_counter6_u {
+-      mmr_t   sh_performance_counter6_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter6_s;
+-} sh_performance_counter6_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_PERFORMANCE_COUNTER7"                  */
+ /*                        Performance Counter 7                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_performance_counter7_u {
+       mmr_t   sh_performance_counter7_regval;
+       struct {
+@@ -21160,22 +11405,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_performance_counter7_s;
+ } sh_performance_counter7_u_t;
+-#else
+-typedef union sh_performance_counter7_u {
+-      mmr_t   sh_performance_counter7_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   count       : 32;
+-      } sh_performance_counter7_s;
+-} sh_performance_counter7_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_PROFILE_COUNTER"                     */
+ /*                           Profile Counter                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_counter_u {
+       mmr_t   sh_profile_counter_regval;
+       struct {
+@@ -21183,22 +11418,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_profile_counter_s;
+ } sh_profile_counter_u_t;
+-#else
+-typedef union sh_profile_counter_u {
+-      mmr_t   sh_profile_counter_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   counter     : 8;
+-      } sh_profile_counter_s;
+-} sh_profile_counter_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_PROFILE_PEAK"                      */
+ /*                         Profile Peak Counter                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_profile_peak_u {
+       mmr_t   sh_profile_peak_regval;
+       struct {
+@@ -21206,22 +11431,12 @@
+               mmr_t   reserved_0  : 56;
+       } sh_profile_peak_s;
+ } sh_profile_peak_u_t;
+-#else
+-typedef union sh_profile_peak_u {
+-      mmr_t   sh_profile_peak_regval;
+-      struct {
+-              mmr_t   reserved_0  : 56;
+-              mmr_t   counter     : 8;
+-      } sh_profile_peak_s;
+-} sh_profile_peak_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_PTC_0"                          */
+ /*       Puge Translation Cache Message Configuration Information       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ptc_0_u {
+       mmr_t   sh_ptc_0_regval;
+       struct {
+@@ -21233,26 +11448,12 @@
+               mmr_t   start       : 1;
+       } sh_ptc_0_s;
+ } sh_ptc_0_u_t;
+-#else
+-typedef union sh_ptc_0_u {
+-      mmr_t   sh_ptc_0_regval;
+-      struct {
+-              mmr_t   start       : 1;
+-              mmr_t   reserved_1  : 31;
+-              mmr_t   rid         : 24;
+-              mmr_t   ps          : 6;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   a           : 1;
+-      } sh_ptc_0_s;
+-} sh_ptc_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_PTC_1"                          */
+ /*       Puge Translation Cache Message Configuration Information       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ptc_1_u {
+       mmr_t   sh_ptc_1_regval;
+       struct {
+@@ -21262,24 +11463,12 @@
+               mmr_t   start       : 1;
+       } sh_ptc_1_s;
+ } sh_ptc_1_u_t;
+-#else
+-typedef union sh_ptc_1_u {
+-      mmr_t   sh_ptc_1_regval;
+-      struct {
+-              mmr_t   start       : 1;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   vpn         : 49;
+-              mmr_t   reserved_0  : 12;
+-      } sh_ptc_1_s;
+-} sh_ptc_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_PTC_PARMS"                        */
+ /*                       PTC Time-out parmaeters                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_ptc_parms_u {
+       mmr_t   sh_ptc_parms_regval;
+       struct {
+@@ -21288,23 +11477,12 @@
+               mmr_t   reserved_0  : 28;
+       } sh_ptc_parms_s;
+ } sh_ptc_parms_u_t;
+-#else
+-typedef union sh_ptc_parms_u {
+-      mmr_t   sh_ptc_parms_regval;
+-      struct {
+-              mmr_t   reserved_0  : 28;
+-              mmr_t   ptc_to_val  : 12;
+-              mmr_t   ptc_to_wrap : 24;
+-      } sh_ptc_parms_s;
+-} sh_ptc_parms_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_INT_CMPA"                        */
+ /*                  RTC Compare Value for Processor A                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpa_u {
+       mmr_t   sh_int_cmpa_regval;
+       struct {
+@@ -21312,22 +11490,12 @@
+               mmr_t   reserved_0     : 9;
+       } sh_int_cmpa_s;
+ } sh_int_cmpa_u_t;
+-#else
+-typedef union sh_int_cmpa_u {
+-      mmr_t   sh_int_cmpa_regval;
+-      struct {
+-              mmr_t   reserved_0     : 9;
+-              mmr_t   real_time_cmpa : 55;
+-      } sh_int_cmpa_s;
+-} sh_int_cmpa_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_INT_CMPB"                        */
+ /*                  RTC Compare Value for Processor B                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpb_u {
+       mmr_t   sh_int_cmpb_regval;
+       struct {
+@@ -21335,22 +11503,12 @@
+               mmr_t   reserved_0     : 9;
+       } sh_int_cmpb_s;
+ } sh_int_cmpb_u_t;
+-#else
+-typedef union sh_int_cmpb_u {
+-      mmr_t   sh_int_cmpb_regval;
+-      struct {
+-              mmr_t   reserved_0     : 9;
+-              mmr_t   real_time_cmpb : 55;
+-      } sh_int_cmpb_s;
+-} sh_int_cmpb_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_INT_CMPC"                        */
+ /*                  RTC Compare Value for Processor C                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpc_u {
+       mmr_t   sh_int_cmpc_regval;
+       struct {
+@@ -21358,22 +11516,12 @@
+               mmr_t   reserved_0     : 9;
+       } sh_int_cmpc_s;
+ } sh_int_cmpc_u_t;
+-#else
+-typedef union sh_int_cmpc_u {
+-      mmr_t   sh_int_cmpc_regval;
+-      struct {
+-              mmr_t   reserved_0     : 9;
+-              mmr_t   real_time_cmpc : 55;
+-      } sh_int_cmpc_s;
+-} sh_int_cmpc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_INT_CMPD"                        */
+ /*                  RTC Compare Value for Processor D                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_cmpd_u {
+       mmr_t   sh_int_cmpd_regval;
+       struct {
+@@ -21381,22 +11529,12 @@
+               mmr_t   reserved_0     : 9;
+       } sh_int_cmpd_s;
+ } sh_int_cmpd_u_t;
+-#else
+-typedef union sh_int_cmpd_u {
+-      mmr_t   sh_int_cmpd_regval;
+-      struct {
+-              mmr_t   reserved_0     : 9;
+-              mmr_t   real_time_cmpd : 55;
+-      } sh_int_cmpd_s;
+-} sh_int_cmpd_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_INT_PROF"                        */
+ /*                      Profile Compare Registers                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_int_prof_u {
+       mmr_t   sh_int_prof_regval;
+       struct {
+@@ -21404,22 +11542,12 @@
+               mmr_t   reserved_0      : 32;
+       } sh_int_prof_s;
+ } sh_int_prof_u_t;
+-#else
+-typedef union sh_int_prof_u {
+-      mmr_t   sh_int_prof_regval;
+-      struct {
+-              mmr_t   reserved_0      : 32;
+-              mmr_t   profile_compare : 32;
+-      } sh_int_prof_s;
+-} sh_int_prof_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                          Register "SH_RTC"                           */
+ /*                           Real-time Clock                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_rtc_u {
+       mmr_t   sh_rtc_regval;
+       struct {
+@@ -21427,85 +11555,48 @@
+               mmr_t   reserved_0      : 9;
+       } sh_rtc_s;
+ } sh_rtc_u_t;
+-#else
+-typedef union sh_rtc_u {
+-      mmr_t   sh_rtc_regval;
+-      struct {
+-              mmr_t   reserved_0      : 9;
+-              mmr_t   real_time_clock : 55;
+-      } sh_rtc_s;
+-} sh_rtc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_SCRATCH0"                        */
+ /*                          Scratch Register 0                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_scratch0_u {
+-      mmr_t   sh_scratch0_regval;
+-      struct {
+-              mmr_t   scratch0    : 64;
+-      } sh_scratch0_s;
+-} sh_scratch0_u_t;
+-#else
+ typedef union sh_scratch0_u {
+       mmr_t   sh_scratch0_regval;
+       struct {
+               mmr_t   scratch0    : 64;
+       } sh_scratch0_s;
+ } sh_scratch0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_SCRATCH1"                        */
+ /*                          Scratch Register 1                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_scratch1_u {
+-      mmr_t   sh_scratch1_regval;
+-      struct {
+-              mmr_t   scratch1    : 64;
+-      } sh_scratch1_s;
+-} sh_scratch1_u_t;
+-#else
+ typedef union sh_scratch1_u {
+       mmr_t   sh_scratch1_regval;
+       struct {
+               mmr_t   scratch1    : 64;
+       } sh_scratch1_s;
+ } sh_scratch1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_SCRATCH2"                        */
+ /*                          Scratch Register 2                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_scratch2_u {
+-      mmr_t   sh_scratch2_regval;
+-      struct {
+-              mmr_t   scratch2    : 64;
+-      } sh_scratch2_s;
+-} sh_scratch2_u_t;
+-#else
+ typedef union sh_scratch2_u {
+       mmr_t   sh_scratch2_regval;
+       struct {
+               mmr_t   scratch2    : 64;
+       } sh_scratch2_s;
+ } sh_scratch2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_SCRATCH3"                        */
+ /*                          Scratch Register 3                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_scratch3_u {
+       mmr_t   sh_scratch3_regval;
+       struct {
+@@ -21513,22 +11604,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_scratch3_s;
+ } sh_scratch3_u_t;
+-#else
+-typedef union sh_scratch3_u {
+-      mmr_t   sh_scratch3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   scratch3    : 1;
+-      } sh_scratch3_s;
+-} sh_scratch3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                        Register "SH_SCRATCH4"                        */
+ /*                          Scratch Register 4                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_scratch4_u {
+       mmr_t   sh_scratch4_regval;
+       struct {
+@@ -21536,22 +11617,12 @@
+               mmr_t   reserved_0  : 63;
+       } sh_scratch4_s;
+ } sh_scratch4_u_t;
+-#else
+-typedef union sh_scratch4_u {
+-      mmr_t   sh_scratch4_regval;
+-      struct {
+-              mmr_t   reserved_0  : 63;
+-              mmr_t   scratch4    : 1;
+-      } sh_scratch4_s;
+-} sh_scratch4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_CRB_MESSAGE_CONTROL"                   */
+ /*               Coherent Request Buffer Message Control                */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_message_control_u {
+       mmr_t   sh_crb_message_control_regval;
+       struct {
+@@ -21572,35 +11643,12 @@
+               mmr_t   ivack_throttle_control            : 16;
+       } sh_crb_message_control_s;
+ } sh_crb_message_control_u_t;
+-#else
+-typedef union sh_crb_message_control_u {
+-      mmr_t   sh_crb_message_control_regval;
+-      struct {
+-              mmr_t   ivack_throttle_control            : 16;
+-              mmr_t   ivack_stall_count                 : 16;
+-              mmr_t   reserved_0                        : 20;
+-              mmr_t   enable_ivack_consolidation        : 1;
+-              mmr_t   suppress_bogus_writes             : 1;
+-              mmr_t   wrb_attribute_mismatch_xb_enable  : 1;
+-              mmr_t   rrb_attribute_mismatch_xb_enable  : 1;
+-              mmr_t   irb_attribute_mismatch_fsb_enable : 1;
+-              mmr_t   wrb_attribute_mismatch_fsb_enable : 1;
+-              mmr_t   rrb_attribute_mismatch_fsb_enable : 1;
+-              mmr_t   message_color_enable              : 1;
+-              mmr_t   message_color                     : 1;
+-              mmr_t   remote_speculative_message_enable : 1;
+-              mmr_t   local_speculative_message_enable  : 1;
+-              mmr_t   system_coherence_enable           : 1;
+-      } sh_crb_message_control_s;
+-} sh_crb_message_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_CRB_NACK_LIMIT"                     */
+ /*                            CRB Nack Limit                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_nack_limit_u {
+       mmr_t   sh_crb_nack_limit_regval;
+       struct {
+@@ -21610,24 +11658,12 @@
+               mmr_t   enable      : 1;
+       } sh_crb_nack_limit_s;
+ } sh_crb_nack_limit_u_t;
+-#else
+-typedef union sh_crb_nack_limit_u {
+-      mmr_t   sh_crb_nack_limit_regval;
+-      struct {
+-              mmr_t   enable      : 1;
+-              mmr_t   reserved_0  : 47;
+-              mmr_t   pri_freq    : 4;
+-              mmr_t   limit       : 12;
+-      } sh_crb_nack_limit_s;
+-} sh_crb_nack_limit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_CRB_TIMEOUT_PRESCALE"                  */
+ /*               Coherent Request Buffer Timeout Prescale               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_timeout_prescale_u {
+       mmr_t   sh_crb_timeout_prescale_regval;
+       struct {
+@@ -21635,22 +11671,12 @@
+               mmr_t   reserved_0     : 32;
+       } sh_crb_timeout_prescale_s;
+ } sh_crb_timeout_prescale_u_t;
+-#else
+-typedef union sh_crb_timeout_prescale_u {
+-      mmr_t   sh_crb_timeout_prescale_regval;
+-      struct {
+-              mmr_t   reserved_0     : 32;
+-              mmr_t   scaling_factor : 32;
+-      } sh_crb_timeout_prescale_s;
+-} sh_crb_timeout_prescale_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_CRB_TIMEOUT_SKID"                    */
+ /*              Coherent Request Buffer Timeout Skid Limit              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_crb_timeout_skid_u {
+       mmr_t   sh_crb_timeout_skid_regval;
+       struct {
+@@ -21659,23 +11685,12 @@
+               mmr_t   reset_skid_count : 1;
+       } sh_crb_timeout_skid_s;
+ } sh_crb_timeout_skid_u_t;
+-#else
+-typedef union sh_crb_timeout_skid_u {
+-      mmr_t   sh_crb_timeout_skid_regval;
+-      struct {
+-              mmr_t   reset_skid_count : 1;
+-              mmr_t   reserved_0       : 57;
+-              mmr_t   skid             : 6;
+-      } sh_crb_timeout_skid_s;
+-} sh_crb_timeout_skid_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MEMORY_WRITE_STATUS_0"                  */
+ /*                    Memory Write Status for CPU 0                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_0_u {
+       mmr_t   sh_memory_write_status_0_regval;
+       struct {
+@@ -21683,22 +11698,12 @@
+               mmr_t   reserved_0          : 58;
+       } sh_memory_write_status_0_s;
+ } sh_memory_write_status_0_u_t;
+-#else
+-typedef union sh_memory_write_status_0_u {
+-      mmr_t   sh_memory_write_status_0_regval;
+-      struct {
+-              mmr_t   reserved_0          : 58;
+-              mmr_t   pending_write_count : 6;
+-      } sh_memory_write_status_0_s;
+-} sh_memory_write_status_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MEMORY_WRITE_STATUS_1"                  */
+ /*                    Memory Write Status for CPU 1                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_1_u {
+       mmr_t   sh_memory_write_status_1_regval;
+       struct {
+@@ -21706,22 +11711,12 @@
+               mmr_t   reserved_0          : 58;
+       } sh_memory_write_status_1_s;
+ } sh_memory_write_status_1_u_t;
+-#else
+-typedef union sh_memory_write_status_1_u {
+-      mmr_t   sh_memory_write_status_1_regval;
+-      struct {
+-              mmr_t   reserved_0          : 58;
+-              mmr_t   pending_write_count : 6;
+-      } sh_memory_write_status_1_s;
+-} sh_memory_write_status_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PIO_WRITE_STATUS_0"                   */
+ /*                      PIO Write Status for CPU 0                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_write_status_0_u {
+       mmr_t   sh_pio_write_status_0_regval;
+       struct {
+@@ -21730,33 +11725,17 @@
+               mmr_t   write_error         : 1;
+               mmr_t   write_error_address : 47;
+               mmr_t   reserved_0          : 6;
+-              mmr_t   pending_write_count : 6;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   writes_ok           : 1;
+-      } sh_pio_write_status_0_s;
+-} sh_pio_write_status_0_u_t;
+-#else
+-typedef union sh_pio_write_status_0_u {
+-      mmr_t   sh_pio_write_status_0_regval;
+-      struct {
+-              mmr_t   writes_ok           : 1;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   pending_write_count : 6;
+-              mmr_t   reserved_0          : 6;
+-              mmr_t   write_error_address : 47;
+-              mmr_t   write_error         : 1;
+-              mmr_t   write_deadlock      : 1;
+-              mmr_t   multi_write_error   : 1;
++              mmr_t   pending_write_count : 6;
++              mmr_t   reserved_1          : 1;
++              mmr_t   writes_ok           : 1;
+       } sh_pio_write_status_0_s;
+ } sh_pio_write_status_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_PIO_WRITE_STATUS_1"                   */
+ /*                      PIO Write Status for CPU 1                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_write_status_1_u {
+       mmr_t   sh_pio_write_status_1_regval;
+       struct {
+@@ -21770,28 +11749,12 @@
+               mmr_t   writes_ok           : 1;
+       } sh_pio_write_status_1_s;
+ } sh_pio_write_status_1_u_t;
+-#else
+-typedef union sh_pio_write_status_1_u {
+-      mmr_t   sh_pio_write_status_1_regval;
+-      struct {
+-              mmr_t   writes_ok           : 1;
+-              mmr_t   reserved_1          : 1;
+-              mmr_t   pending_write_count : 6;
+-              mmr_t   reserved_0          : 6;
+-              mmr_t   write_error_address : 47;
+-              mmr_t   write_error         : 1;
+-              mmr_t   write_deadlock      : 1;
+-              mmr_t   multi_write_error   : 1;
+-      } sh_pio_write_status_1_s;
+-} sh_pio_write_status_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_MEMORY_WRITE_STATUS_NON_USER_0"             */
+ /*            Memory Write Status for CPU 0. OS access only             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_non_user_0_u {
+       mmr_t   sh_memory_write_status_non_user_0_regval;
+       struct {
+@@ -21800,23 +11763,12 @@
+               mmr_t   clear               : 1;
+       } sh_memory_write_status_non_user_0_s;
+ } sh_memory_write_status_non_user_0_u_t;
+-#else
+-typedef union sh_memory_write_status_non_user_0_u {
+-      mmr_t   sh_memory_write_status_non_user_0_regval;
+-      struct {
+-              mmr_t   clear               : 1;
+-              mmr_t   reserved_0          : 57;
+-              mmr_t   pending_write_count : 6;
+-      } sh_memory_write_status_non_user_0_s;
+-} sh_memory_write_status_non_user_0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_MEMORY_WRITE_STATUS_NON_USER_1"             */
+ /*            Memory Write Status for CPU 1. OS access only             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_memory_write_status_non_user_1_u {
+       mmr_t   sh_memory_write_status_non_user_1_regval;
+       struct {
+@@ -21825,23 +11777,12 @@
+               mmr_t   clear               : 1;
+       } sh_memory_write_status_non_user_1_s;
+ } sh_memory_write_status_non_user_1_u_t;
+-#else
+-typedef union sh_memory_write_status_non_user_1_u {
+-      mmr_t   sh_memory_write_status_non_user_1_regval;
+-      struct {
+-              mmr_t   clear               : 1;
+-              mmr_t   reserved_0          : 57;
+-              mmr_t   pending_write_count : 6;
+-      } sh_memory_write_status_non_user_1_s;
+-} sh_memory_write_status_non_user_1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_MMRBIST_ERR"                       */
+ /*                  Error capture for bist read errors                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mmrbist_err_u {
+       mmr_t   sh_mmrbist_err_regval;
+       struct {
+@@ -21853,26 +11794,12 @@
+               mmr_t   reserved_1        : 25;
+       } sh_mmrbist_err_s;
+ } sh_mmrbist_err_u_t;
+-#else
+-typedef union sh_mmrbist_err_u {
+-      mmr_t   sh_mmrbist_err_regval;
+-      struct {
+-              mmr_t   reserved_1        : 25;
+-              mmr_t   cancelled         : 1;
+-              mmr_t   multiple_detected : 1;
+-              mmr_t   detected          : 1;
+-              mmr_t   reserved_0        : 3;
+-              mmr_t   addr              : 33;
+-      } sh_mmrbist_err_s;
+-} sh_mmrbist_err_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MISC_ERR_HDR_LOWER"                   */
+ /*                       Header capture register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_misc_err_hdr_lower_u {
+       mmr_t   sh_misc_err_hdr_lower_regval;
+       struct {
+@@ -21886,28 +11813,12 @@
+               mmr_t   valid       : 1;
+       } sh_misc_err_hdr_lower_s;
+ } sh_misc_err_hdr_lower_u_t;
+-#else
+-typedef union sh_misc_err_hdr_lower_u {
+-      mmr_t   sh_misc_err_hdr_lower_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_2  : 2;
+-              mmr_t   write       : 1;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   addr        : 33;
+-              mmr_t   reserved_0  : 3;
+-      } sh_misc_err_hdr_lower_s;
+-} sh_misc_err_hdr_lower_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MISC_ERR_HDR_UPPER"                   */
+ /*           Error header capture packet and protocol errors            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_misc_err_hdr_upper_u {
+       mmr_t   sh_misc_err_hdr_upper_regval;
+       struct {
+@@ -21924,31 +11835,12 @@
+               mmr_t   reserved_1    : 35;
+       } sh_misc_err_hdr_upper_s;
+ } sh_misc_err_hdr_upper_u_t;
+-#else
+-typedef union sh_misc_err_hdr_upper_u {
+-      mmr_t   sh_misc_err_hdr_upper_regval;
+-      struct {
+-              mmr_t   reserved_1    : 35;
+-              mmr_t   echo          : 9;
+-              mmr_t   reserved_0    : 12;
+-              mmr_t   xn_pkt_size   : 1;
+-              mmr_t   pi_pkt_size   : 1;
+-              mmr_t   dir_acc       : 1;
+-              mmr_t   rmw_cor       : 1;
+-              mmr_t   rmw_uc        : 1;
+-              mmr_t   nonexist_addr : 1;
+-              mmr_t   illegal_cmd   : 1;
+-              mmr_t   dir_protocol  : 1;
+-      } sh_misc_err_hdr_upper_s;
+-} sh_misc_err_hdr_upper_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_DIR_UC_ERR_HDR_LOWER"                  */
+ /*                       Header capture register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_uc_err_hdr_lower_u {
+       mmr_t   sh_dir_uc_err_hdr_lower_regval;
+       struct {
+@@ -21962,28 +11854,12 @@
+               mmr_t   valid       : 1;
+       } sh_dir_uc_err_hdr_lower_s;
+ } sh_dir_uc_err_hdr_lower_u_t;
+-#else
+-typedef union sh_dir_uc_err_hdr_lower_u {
+-      mmr_t   sh_dir_uc_err_hdr_lower_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_2  : 2;
+-              mmr_t   write       : 1;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   addr        : 33;
+-              mmr_t   reserved_0  : 3;
+-      } sh_dir_uc_err_hdr_lower_s;
+-} sh_dir_uc_err_hdr_lower_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_DIR_UC_ERR_HDR_UPPER"                  */
+ /*           Error header capture packet and protocol errors            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_uc_err_hdr_upper_u {
+       mmr_t   sh_dir_uc_err_hdr_upper_regval;
+       struct {
+@@ -21994,25 +11870,12 @@
+               mmr_t   reserved_2  : 35;
+       } sh_dir_uc_err_hdr_upper_s;
+ } sh_dir_uc_err_hdr_upper_u_t;
+-#else
+-typedef union sh_dir_uc_err_hdr_upper_u {
+-      mmr_t   sh_dir_uc_err_hdr_upper_regval;
+-      struct {
+-              mmr_t   reserved_2  : 35;
+-              mmr_t   echo        : 9;
+-              mmr_t   reserved_1  : 16;
+-              mmr_t   dir_uc      : 1;
+-              mmr_t   reserved_0  : 3;
+-      } sh_dir_uc_err_hdr_upper_s;
+-} sh_dir_uc_err_hdr_upper_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_DIR_COR_ERR_HDR_LOWER"                  */
+ /*                       Header capture register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_cor_err_hdr_lower_u {
+       mmr_t   sh_dir_cor_err_hdr_lower_regval;
+       struct {
+@@ -22026,28 +11889,12 @@
+               mmr_t   valid       : 1;
+       } sh_dir_cor_err_hdr_lower_s;
+ } sh_dir_cor_err_hdr_lower_u_t;
+-#else
+-typedef union sh_dir_cor_err_hdr_lower_u {
+-      mmr_t   sh_dir_cor_err_hdr_lower_regval;
+-      struct {
+-              mmr_t   valid       : 1;
+-              mmr_t   reserved_2  : 2;
+-              mmr_t   write       : 1;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   addr        : 33;
+-              mmr_t   reserved_0  : 3;
+-      } sh_dir_cor_err_hdr_lower_s;
+-} sh_dir_cor_err_hdr_lower_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_DIR_COR_ERR_HDR_UPPER"                  */
+ /*           Error header capture packet and protocol errors            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_dir_cor_err_hdr_upper_u {
+       mmr_t   sh_dir_cor_err_hdr_upper_regval;
+       struct {
+@@ -22058,25 +11905,12 @@
+               mmr_t   reserved_2  : 35;
+       } sh_dir_cor_err_hdr_upper_s;
+ } sh_dir_cor_err_hdr_upper_u_t;
+-#else
+-typedef union sh_dir_cor_err_hdr_upper_u {
+-      mmr_t   sh_dir_cor_err_hdr_upper_regval;
+-      struct {
+-              mmr_t   reserved_2  : 35;
+-              mmr_t   echo        : 9;
+-              mmr_t   reserved_1  : 11;
+-              mmr_t   dir_cor     : 1;
+-              mmr_t   reserved_0  : 8;
+-      } sh_dir_cor_err_hdr_upper_s;
+-} sh_dir_cor_err_hdr_upper_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MEM_ERROR_SUMMARY"                    */
+ /*                          Memory error flags                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_error_summary_u {
+       mmr_t   sh_mem_error_summary_regval;
+       struct {
+@@ -22118,56 +11952,12 @@
+               mmr_t   reserved_5            : 29;
+       } sh_mem_error_summary_s;
+ } sh_mem_error_summary_u_t;
+-#else
+-typedef union sh_mem_error_summary_u {
+-      mmr_t   sh_mem_error_summary_regval;
+-      struct {
+-              mmr_t   reserved_5            : 29;
+-              mmr_t   xn_pkt_size           : 1;
+-              mmr_t   pi_pkt_size           : 1;
+-              mmr_t   red_black_err_timeout : 1;
+-              mmr_t   xn_request_overflow   : 1;
+-              mmr_t   pi_request_overflow   : 1;
+-              mmr_t   xn_reply_overflow     : 1;
+-              mmr_t   pi_reply_overflow     : 1;
+-              mmr_t   reserved_4            : 1;
+-              mmr_t   dqrs_int_hw           : 1;
+-              mmr_t   dqrs_int_cor          : 1;
+-              mmr_t   dqrs_int_uc           : 1;
+-              mmr_t   reserved_3            : 1;
+-              mmr_t   dqrp_int_hw           : 1;
+-              mmr_t   dqrp_int_cor          : 1;
+-              mmr_t   dqrp_int_uc           : 1;
+-              mmr_t   reserved_2            : 1;
+-              mmr_t   dqls_int_hw           : 1;
+-              mmr_t   dqls_int_cor          : 1;
+-              mmr_t   dqls_int_uc           : 1;
+-              mmr_t   reserved_1            : 1;
+-              mmr_t   dqlp_int_hw           : 1;
+-              mmr_t   dqlp_int_cor          : 1;
+-              mmr_t   dqlp_int_uc           : 1;
+-              mmr_t   reserved_0            : 1;
+-              mmr_t   dir_acc               : 1;
+-              mmr_t   acy_int_hw            : 1;
+-              mmr_t   acx_int_hw            : 1;
+-              mmr_t   dqrp_dir_cor          : 1;
+-              mmr_t   dqrp_dir_uc           : 1;
+-              mmr_t   dqlp_dir_cor          : 1;
+-              mmr_t   dqlp_dir_uc           : 1;
+-              mmr_t   dqrp_dir_perr         : 1;
+-              mmr_t   dqlp_dir_perr         : 1;
+-              mmr_t   nonexist_addr         : 1;
+-              mmr_t   illegal_cmd           : 1;
+-      } sh_mem_error_summary_s;
+-} sh_mem_error_summary_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MEM_ERROR_OVERFLOW"                   */
+ /*                          Memory error flags                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_error_overflow_u {
+       mmr_t   sh_mem_error_overflow_regval;
+       struct {
+@@ -22209,56 +11999,12 @@
+               mmr_t   reserved_5            : 29;
+       } sh_mem_error_overflow_s;
+ } sh_mem_error_overflow_u_t;
+-#else
+-typedef union sh_mem_error_overflow_u {
+-      mmr_t   sh_mem_error_overflow_regval;
+-      struct {
+-              mmr_t   reserved_5            : 29;
+-              mmr_t   xn_pkt_size           : 1;
+-              mmr_t   pi_pkt_size           : 1;
+-              mmr_t   red_black_err_timeout : 1;
+-              mmr_t   xn_request_overflow   : 1;
+-              mmr_t   pi_request_overflow   : 1;
+-              mmr_t   xn_reply_overflow     : 1;
+-              mmr_t   pi_reply_overflow     : 1;
+-              mmr_t   reserved_4            : 1;
+-              mmr_t   dqrs_int_hw           : 1;
+-              mmr_t   dqrs_int_cor          : 1;
+-              mmr_t   dqrs_int_uc           : 1;
+-              mmr_t   reserved_3            : 1;
+-              mmr_t   dqrp_int_hw           : 1;
+-              mmr_t   dqrp_int_cor          : 1;
+-              mmr_t   dqrp_int_uc           : 1;
+-              mmr_t   reserved_2            : 1;
+-              mmr_t   dqls_int_hw           : 1;
+-              mmr_t   dqls_int_cor          : 1;
+-              mmr_t   dqls_int_uc           : 1;
+-              mmr_t   reserved_1            : 1;
+-              mmr_t   dqlp_int_hw           : 1;
+-              mmr_t   dqlp_int_cor          : 1;
+-              mmr_t   dqlp_int_uc           : 1;
+-              mmr_t   reserved_0            : 1;
+-              mmr_t   dir_acc               : 1;
+-              mmr_t   acy_int_hw            : 1;
+-              mmr_t   acx_int_hw            : 1;
+-              mmr_t   dqrp_dir_cor          : 1;
+-              mmr_t   dqrp_dir_uc           : 1;
+-              mmr_t   dqlp_dir_cor          : 1;
+-              mmr_t   dqlp_dir_uc           : 1;
+-              mmr_t   dqrp_dir_perr         : 1;
+-              mmr_t   dqlp_dir_perr         : 1;
+-              mmr_t   nonexist_addr         : 1;
+-              mmr_t   illegal_cmd           : 1;
+-      } sh_mem_error_overflow_s;
+-} sh_mem_error_overflow_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_MEM_ERROR_MASK"                     */
+ /*                          Memory error flags                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_error_mask_u {
+       mmr_t   sh_mem_error_mask_regval;
+       struct {
+@@ -22283,73 +12029,29 @@
+               mmr_t   dqls_int_hw           : 1;
+               mmr_t   reserved_2            : 1;
+               mmr_t   dqrp_int_uc           : 1;
+-              mmr_t   dqrp_int_cor          : 1;
+-              mmr_t   dqrp_int_hw           : 1;
+-              mmr_t   reserved_3            : 1;
+-              mmr_t   dqrs_int_uc           : 1;
+-              mmr_t   dqrs_int_cor          : 1;
+-              mmr_t   dqrs_int_hw           : 1;
+-              mmr_t   reserved_4            : 1;
+-              mmr_t   pi_reply_overflow     : 1;
+-              mmr_t   xn_reply_overflow     : 1;
+-              mmr_t   pi_request_overflow   : 1;
+-              mmr_t   xn_request_overflow   : 1;
+-              mmr_t   red_black_err_timeout : 1;
+-              mmr_t   pi_pkt_size           : 1;
+-              mmr_t   xn_pkt_size           : 1;
+-              mmr_t   reserved_5            : 29;
+-      } sh_mem_error_mask_s;
+-} sh_mem_error_mask_u_t;
+-#else
+-typedef union sh_mem_error_mask_u {
+-      mmr_t   sh_mem_error_mask_regval;
+-      struct {
+-              mmr_t   reserved_5            : 29;
+-              mmr_t   xn_pkt_size           : 1;
+-              mmr_t   pi_pkt_size           : 1;
+-              mmr_t   red_black_err_timeout : 1;
+-              mmr_t   xn_request_overflow   : 1;
+-              mmr_t   pi_request_overflow   : 1;
+-              mmr_t   xn_reply_overflow     : 1;
+-              mmr_t   pi_reply_overflow     : 1;
+-              mmr_t   reserved_4            : 1;
+-              mmr_t   dqrs_int_hw           : 1;
+-              mmr_t   dqrs_int_cor          : 1;
+-              mmr_t   dqrs_int_uc           : 1;
+-              mmr_t   reserved_3            : 1;
+-              mmr_t   dqrp_int_hw           : 1;
+-              mmr_t   dqrp_int_cor          : 1;
+-              mmr_t   dqrp_int_uc           : 1;
+-              mmr_t   reserved_2            : 1;
+-              mmr_t   dqls_int_hw           : 1;
+-              mmr_t   dqls_int_cor          : 1;
+-              mmr_t   dqls_int_uc           : 1;
+-              mmr_t   reserved_1            : 1;
+-              mmr_t   dqlp_int_hw           : 1;
+-              mmr_t   dqlp_int_cor          : 1;
+-              mmr_t   dqlp_int_uc           : 1;
+-              mmr_t   reserved_0            : 1;
+-              mmr_t   dir_acc               : 1;
+-              mmr_t   acy_int_hw            : 1;
+-              mmr_t   acx_int_hw            : 1;
+-              mmr_t   dqrp_dir_cor          : 1;
+-              mmr_t   dqrp_dir_uc           : 1;
+-              mmr_t   dqlp_dir_cor          : 1;
+-              mmr_t   dqlp_dir_uc           : 1;
+-              mmr_t   dqrp_dir_perr         : 1;
+-              mmr_t   dqlp_dir_perr         : 1;
+-              mmr_t   nonexist_addr         : 1;
+-              mmr_t   illegal_cmd           : 1;
++              mmr_t   dqrp_int_cor          : 1;
++              mmr_t   dqrp_int_hw           : 1;
++              mmr_t   reserved_3            : 1;
++              mmr_t   dqrs_int_uc           : 1;
++              mmr_t   dqrs_int_cor          : 1;
++              mmr_t   dqrs_int_hw           : 1;
++              mmr_t   reserved_4            : 1;
++              mmr_t   pi_reply_overflow     : 1;
++              mmr_t   xn_reply_overflow     : 1;
++              mmr_t   pi_request_overflow   : 1;
++              mmr_t   xn_request_overflow   : 1;
++              mmr_t   red_black_err_timeout : 1;
++              mmr_t   pi_pkt_size           : 1;
++              mmr_t   xn_pkt_size           : 1;
++              mmr_t   reserved_5            : 29;
+       } sh_mem_error_mask_s;
+ } sh_mem_error_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_X_DIMM_CFG"                       */
+ /*                       AC Mem Config Registers                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_dimm_cfg_u {
+       mmr_t   sh_x_dimm_cfg_regval;
+       struct {
+@@ -22377,42 +12079,12 @@
+               mmr_t   reserved_4  : 28;
+       } sh_x_dimm_cfg_s;
+ } sh_x_dimm_cfg_u_t;
+-#else
+-typedef union sh_x_dimm_cfg_u {
+-      mmr_t   sh_x_dimm_cfg_regval;
+-      struct {
+-              mmr_t   reserved_4  : 28;
+-              mmr_t   freq        : 4;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   dimm3_cs    : 2;
+-              mmr_t   dimm3_rev   : 1;
+-              mmr_t   dimm3_2bk   : 1;
+-              mmr_t   dimm3_size  : 3;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   dimm2_cs    : 2;
+-              mmr_t   dimm2_rev   : 1;
+-              mmr_t   dimm2_2bk   : 1;
+-              mmr_t   dimm2_size  : 3;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   dimm1_cs    : 2;
+-              mmr_t   dimm1_rev   : 1;
+-              mmr_t   dimm1_2bk   : 1;
+-              mmr_t   dimm1_size  : 3;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   dimm0_cs    : 2;
+-              mmr_t   dimm0_rev   : 1;
+-              mmr_t   dimm0_2bk   : 1;
+-              mmr_t   dimm0_size  : 3;
+-      } sh_x_dimm_cfg_s;
+-} sh_x_dimm_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_Y_DIMM_CFG"                       */
+ /*                       AC Mem Config Registers                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_dimm_cfg_u {
+       mmr_t   sh_y_dimm_cfg_regval;
+       struct {
+@@ -22440,42 +12112,12 @@
+               mmr_t   reserved_4  : 28;
+       } sh_y_dimm_cfg_s;
+ } sh_y_dimm_cfg_u_t;
+-#else
+-typedef union sh_y_dimm_cfg_u {
+-      mmr_t   sh_y_dimm_cfg_regval;
+-      struct {
+-              mmr_t   reserved_4  : 28;
+-              mmr_t   freq        : 4;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   dimm3_cs    : 2;
+-              mmr_t   dimm3_rev   : 1;
+-              mmr_t   dimm3_2bk   : 1;
+-              mmr_t   dimm3_size  : 3;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   dimm2_cs    : 2;
+-              mmr_t   dimm2_rev   : 1;
+-              mmr_t   dimm2_2bk   : 1;
+-              mmr_t   dimm2_size  : 3;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   dimm1_cs    : 2;
+-              mmr_t   dimm1_rev   : 1;
+-              mmr_t   dimm1_2bk   : 1;
+-              mmr_t   dimm1_size  : 3;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   dimm0_cs    : 2;
+-              mmr_t   dimm0_rev   : 1;
+-              mmr_t   dimm0_2bk   : 1;
+-              mmr_t   dimm0_size  : 3;
+-      } sh_y_dimm_cfg_s;
+-} sh_y_dimm_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_JNR_DIMM_CFG"                      */
+ /*                       AC Mem Config Registers                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_jnr_dimm_cfg_u {
+       mmr_t   sh_jnr_dimm_cfg_regval;
+       struct {
+@@ -22503,42 +12145,12 @@
+               mmr_t   reserved_4  : 28;
+       } sh_jnr_dimm_cfg_s;
+ } sh_jnr_dimm_cfg_u_t;
+-#else
+-typedef union sh_jnr_dimm_cfg_u {
+-      mmr_t   sh_jnr_dimm_cfg_regval;
+-      struct {
+-              mmr_t   reserved_4  : 28;
+-              mmr_t   freq        : 4;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   dimm3_cs    : 2;
+-              mmr_t   dimm3_rev   : 1;
+-              mmr_t   dimm3_2bk   : 1;
+-              mmr_t   dimm3_size  : 3;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   dimm2_cs    : 2;
+-              mmr_t   dimm2_rev   : 1;
+-              mmr_t   dimm2_2bk   : 1;
+-              mmr_t   dimm2_size  : 3;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   dimm1_cs    : 2;
+-              mmr_t   dimm1_rev   : 1;
+-              mmr_t   dimm1_2bk   : 1;
+-              mmr_t   dimm1_size  : 3;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   dimm0_cs    : 2;
+-              mmr_t   dimm0_rev   : 1;
+-              mmr_t   dimm0_2bk   : 1;
+-              mmr_t   dimm0_size  : 3;
+-      } sh_jnr_dimm_cfg_s;
+-} sh_jnr_dimm_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_X_PHASE_CFG"                       */
+ /*                      AC Phase Config Registers                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_phase_cfg_u {
+       mmr_t   sh_x_phase_cfg_regval;
+       struct {
+@@ -22560,36 +12172,12 @@
+               mmr_t   reserved_0  : 1;
+       } sh_x_phase_cfg_s;
+ } sh_x_phase_cfg_u_t;
+-#else
+-typedef union sh_x_phase_cfg_u {
+-      mmr_t   sh_x_phase_cfg_regval;
+-      struct {
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   dq_sel_a    : 4;
+-              mmr_t   sel_a       : 4;
+-              mmr_t   phe_bubble  : 3;
+-              mmr_t   phd_bubble  : 3;
+-              mmr_t   phc_bubble  : 3;
+-              mmr_t   phb_bubble  : 3;
+-              mmr_t   pha_bubble  : 3;
+-              mmr_t   bubble_en   : 5;
+-              mmr_t   add_cp      : 5;
+-              mmr_t   hold_req    : 5;
+-              mmr_t   hold        : 5;
+-              mmr_t   dq_ld_b     : 5;
+-              mmr_t   dq_ld_a     : 5;
+-              mmr_t   ld_b        : 5;
+-              mmr_t   ld_a        : 5;
+-      } sh_x_phase_cfg_s;
+-} sh_x_phase_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_CFG"                          */
+ /*                         AC Config Registers                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_cfg_u {
+       mmr_t   sh_x_cfg_regval;
+       struct {
+@@ -22609,34 +12197,12 @@
+               mmr_t   clr_dir_cache           : 1;
+       } sh_x_cfg_s;
+ } sh_x_cfg_u_t;
+-#else
+-typedef union sh_x_cfg_u {
+-      mmr_t   sh_x_cfg_regval;
+-      struct {
+-              mmr_t   clr_dir_cache           : 1;
+-              mmr_t   inv_cas_addr            : 1;
+-              mmr_t   req_cntr_val            : 6;
+-              mmr_t   req_cntr_dis            : 1;
+-              mmr_t   trcd4_en                : 1;
+-              mmr_t   trcd2_en                : 1;
+-              mmr_t   sso_wt_en               : 1;
+-              mmr_t   wt_bb_clr               : 4;
+-              mmr_t   dc_bb_clr               : 4;
+-              mmr_t   da_bb_clr               : 4;
+-              mmr_t   ta_dlys                 : 32;
+-              mmr_t   dir_counter_init        : 6;
+-              mmr_t   dirc_random_replacement : 1;
+-              mmr_t   mode_serial             : 1;
+-      } sh_x_cfg_s;
+-} sh_x_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_X_DQCT_CFG"                       */
+ /*                         AC Config Registers                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_dqct_cfg_u {
+       mmr_t   sh_x_dqct_cfg_regval;
+       struct {
+@@ -22649,27 +12215,12 @@
+               mmr_t   reserved_0  : 40;
+       } sh_x_dqct_cfg_s;
+ } sh_x_dqct_cfg_u_t;
+-#else
+-typedef union sh_x_dqct_cfg_u {
+-      mmr_t   sh_x_dqct_cfg_regval;
+-      struct {
+-              mmr_t   reserved_0  : 40;
+-              mmr_t   mdir_rd_sel : 4;
+-              mmr_t   dir_rd_sel  : 4;
+-              mmr_t   dta_wt_sel  : 4;
+-              mmr_t   dta_rd_sel  : 4;
+-              mmr_t   wt_sel      : 4;
+-              mmr_t   rd_sel      : 4;
+-      } sh_x_dqct_cfg_s;
+-} sh_x_dqct_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_X_REFRESH_CONTROL"                    */
+ /*                       Refresh Control Register                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_refresh_control_u {
+       mmr_t   sh_x_refresh_control_regval;
+       struct {
+@@ -22681,26 +12232,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_x_refresh_control_s;
+ } sh_x_refresh_control_u_t;
+-#else
+-typedef union sh_x_refresh_control_u {
+-      mmr_t   sh_x_refresh_control_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   half_rate   : 4;
+-              mmr_t   interleave  : 1;
+-              mmr_t   hold        : 6;
+-              mmr_t   interval    : 9;
+-              mmr_t   enable      : 8;
+-      } sh_x_refresh_control_s;
+-} sh_x_refresh_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_Y_PHASE_CFG"                       */
+ /*                      AC Phase Config Registers                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_phase_cfg_u {
+       mmr_t   sh_y_phase_cfg_regval;
+       struct {
+@@ -22722,36 +12259,12 @@
+               mmr_t   reserved_0  : 1;
+       } sh_y_phase_cfg_s;
+ } sh_y_phase_cfg_u_t;
+-#else
+-typedef union sh_y_phase_cfg_u {
+-      mmr_t   sh_y_phase_cfg_regval;
+-      struct {
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   dq_sel_a    : 4;
+-              mmr_t   sel_a       : 4;
+-              mmr_t   phe_bubble  : 3;
+-              mmr_t   phd_bubble  : 3;
+-              mmr_t   phc_bubble  : 3;
+-              mmr_t   phb_bubble  : 3;
+-              mmr_t   pha_bubble  : 3;
+-              mmr_t   bubble_en   : 5;
+-              mmr_t   add_cp      : 5;
+-              mmr_t   hold_req    : 5;
+-              mmr_t   hold        : 5;
+-              mmr_t   dq_ld_b     : 5;
+-              mmr_t   dq_ld_a     : 5;
+-              mmr_t   ld_b        : 5;
+-              mmr_t   ld_a        : 5;
+-      } sh_y_phase_cfg_s;
+-} sh_y_phase_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_CFG"                          */
+ /*                         AC Config Registers                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_cfg_u {
+       mmr_t   sh_y_cfg_regval;
+       struct {
+@@ -22771,34 +12284,12 @@
+               mmr_t   clr_dir_cache           : 1;
+       } sh_y_cfg_s;
+ } sh_y_cfg_u_t;
+-#else
+-typedef union sh_y_cfg_u {
+-      mmr_t   sh_y_cfg_regval;
+-      struct {
+-              mmr_t   clr_dir_cache           : 1;
+-              mmr_t   inv_cas_addr            : 1;
+-              mmr_t   req_cntr_val            : 6;
+-              mmr_t   req_cntr_dis            : 1;
+-              mmr_t   trcd4_en                : 1;
+-              mmr_t   trcd2_en                : 1;
+-              mmr_t   sso_wt_en               : 1;
+-              mmr_t   wt_bb_clr               : 4;
+-              mmr_t   dc_bb_clr               : 4;
+-              mmr_t   da_bb_clr               : 4;
+-              mmr_t   ta_dlys                 : 32;
+-              mmr_t   dir_counter_init        : 6;
+-              mmr_t   dirc_random_replacement : 1;
+-              mmr_t   mode_serial             : 1;
+-      } sh_y_cfg_s;
+-} sh_y_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_Y_DQCT_CFG"                       */
+ /*                         AC Config Registers                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_dqct_cfg_u {
+       mmr_t   sh_y_dqct_cfg_regval;
+       struct {
+@@ -22811,27 +12302,12 @@
+               mmr_t   reserved_0  : 40;
+       } sh_y_dqct_cfg_s;
+ } sh_y_dqct_cfg_u_t;
+-#else
+-typedef union sh_y_dqct_cfg_u {
+-      mmr_t   sh_y_dqct_cfg_regval;
+-      struct {
+-              mmr_t   reserved_0  : 40;
+-              mmr_t   mdir_rd_sel : 4;
+-              mmr_t   dir_rd_sel  : 4;
+-              mmr_t   dta_wt_sel  : 4;
+-              mmr_t   dta_rd_sel  : 4;
+-              mmr_t   wt_sel      : 4;
+-              mmr_t   rd_sel      : 4;
+-      } sh_y_dqct_cfg_s;
+-} sh_y_dqct_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_Y_REFRESH_CONTROL"                    */
+ /*                       Refresh Control Register                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_refresh_control_u {
+       mmr_t   sh_y_refresh_control_regval;
+       struct {
+@@ -22843,26 +12319,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_y_refresh_control_s;
+ } sh_y_refresh_control_u_t;
+-#else
+-typedef union sh_y_refresh_control_u {
+-      mmr_t   sh_y_refresh_control_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   half_rate   : 4;
+-              mmr_t   interleave  : 1;
+-              mmr_t   hold        : 6;
+-              mmr_t   interval    : 9;
+-              mmr_t   enable      : 8;
+-      } sh_y_refresh_control_s;
+-} sh_y_refresh_control_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_MEM_RED_BLACK"                      */
+ /*                     MD fairness watchdog timers                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_red_black_u {
+       mmr_t   sh_mem_red_black_regval;
+       struct {
+@@ -22871,22 +12333,11 @@
+               mmr_t   reserved_0  : 12;
+       } sh_mem_red_black_s;
+ } sh_mem_red_black_u_t;
+-#else
+-typedef union sh_mem_red_black_u {
+-      mmr_t   sh_mem_red_black_regval;
+-      struct {
+-              mmr_t   reserved_0  : 12;
+-              mmr_t   err_time    : 36;
+-              mmr_t   time        : 16;
+-      } sh_mem_red_black_s;
+-} sh_mem_red_black_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_MISC_MEM_CFG"                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_misc_mem_cfg_u {
+       mmr_t   sh_misc_mem_cfg_regval;
+       struct {
+@@ -22903,43 +12354,18 @@
+               mmr_t   reserved_2                  : 3;
+               mmr_t   disabled_write_tnums        : 5;
+               mmr_t   reserved_3                  : 3;
+-              mmr_t   disabled_victims            : 6;
+-              mmr_t   reserved_4                  : 2;
+-              mmr_t   alternate_xn_rp_plane       : 1;
+-              mmr_t   reserved_5                  : 11;
+-      } sh_misc_mem_cfg_s;
+-} sh_misc_mem_cfg_u_t;
+-#else
+-typedef union sh_misc_mem_cfg_u {
+-      mmr_t   sh_misc_mem_cfg_regval;
+-      struct {
+-              mmr_t   reserved_5                  : 11;
+-              mmr_t   alternate_xn_rp_plane       : 1;
+-              mmr_t   reserved_4                  : 2;
+-              mmr_t   disabled_victims            : 6;
+-              mmr_t   reserved_3                  : 3;
+-              mmr_t   disabled_write_tnums        : 5;
+-              mmr_t   reserved_2                  : 3;
+-              mmr_t   disabled_read_tnums         : 5;
+-              mmr_t   throttle_cnt                : 8;
+-              mmr_t   reserved_1                  : 2;
+-              mmr_t   low_victim_buffer_threshold : 6;
+-              mmr_t   reserved_0                  : 2;
+-              mmr_t   low_write_buffer_threshold  : 6;
+-              mmr_t   xn_rd_same_as_pi            : 1;
+-              mmr_t   jnr_bypass_enable           : 1;
+-              mmr_t   spec_header_enable          : 1;
+-              mmr_t   express_header_enable       : 1;
++              mmr_t   disabled_victims            : 6;
++              mmr_t   reserved_4                  : 2;
++              mmr_t   alternate_xn_rp_plane       : 1;
++              mmr_t   reserved_5                  : 11;
+       } sh_misc_mem_cfg_s;
+ } sh_misc_mem_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_PIO_RQ_CRD_CTL"                     */
+ /*                  pio_rq Credit Circulation Control                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pio_rq_crd_ctl_u {
+       mmr_t   sh_pio_rq_crd_ctl_regval;
+       struct {
+@@ -22947,22 +12373,12 @@
+               mmr_t   reserved_0  : 58;
+       } sh_pio_rq_crd_ctl_s;
+ } sh_pio_rq_crd_ctl_u_t;
+-#else
+-typedef union sh_pio_rq_crd_ctl_u {
+-      mmr_t   sh_pio_rq_crd_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   depth       : 6;
+-      } sh_pio_rq_crd_ctl_s;
+-} sh_pio_rq_crd_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_PI_MD_RQ_CRD_CTL"                    */
+ /*                 pi_md_rq Credit Circulation Control                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md_rq_crd_ctl_u {
+       mmr_t   sh_pi_md_rq_crd_ctl_regval;
+       struct {
+@@ -22970,22 +12386,12 @@
+               mmr_t   reserved_0  : 58;
+       } sh_pi_md_rq_crd_ctl_s;
+ } sh_pi_md_rq_crd_ctl_u_t;
+-#else
+-typedef union sh_pi_md_rq_crd_ctl_u {
+-      mmr_t   sh_pi_md_rq_crd_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   depth       : 6;
+-      } sh_pi_md_rq_crd_ctl_s;
+-} sh_pi_md_rq_crd_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_PI_MD_RP_CRD_CTL"                    */
+ /*                 pi_md_rp Credit Circulation Control                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_pi_md_rp_crd_ctl_u {
+       mmr_t   sh_pi_md_rp_crd_ctl_regval;
+       struct {
+@@ -22993,22 +12399,12 @@
+               mmr_t   reserved_0  : 58;
+       } sh_pi_md_rp_crd_ctl_s;
+ } sh_pi_md_rp_crd_ctl_u_t;
+-#else
+-typedef union sh_pi_md_rp_crd_ctl_u {
+-      mmr_t   sh_pi_md_rp_crd_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   depth       : 6;
+-      } sh_pi_md_rp_crd_ctl_s;
+-} sh_pi_md_rp_crd_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_MD_RQ_CRD_CTL"                    */
+ /*                 xn_md_rq Credit Circulation Control                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_rq_crd_ctl_u {
+       mmr_t   sh_xn_md_rq_crd_ctl_regval;
+       struct {
+@@ -23016,22 +12412,12 @@
+               mmr_t   reserved_0  : 58;
+       } sh_xn_md_rq_crd_ctl_s;
+ } sh_xn_md_rq_crd_ctl_u_t;
+-#else
+-typedef union sh_xn_md_rq_crd_ctl_u {
+-      mmr_t   sh_xn_md_rq_crd_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   depth       : 6;
+-      } sh_xn_md_rq_crd_ctl_s;
+-} sh_xn_md_rq_crd_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_XN_MD_RP_CRD_CTL"                    */
+ /*                 xn_md_rp Credit Circulation Control                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_xn_md_rp_crd_ctl_u {
+       mmr_t   sh_xn_md_rp_crd_ctl_regval;
+       struct {
+@@ -23039,22 +12425,12 @@
+               mmr_t   reserved_0  : 58;
+       } sh_xn_md_rp_crd_ctl_s;
+ } sh_xn_md_rp_crd_ctl_u_t;
+-#else
+-typedef union sh_xn_md_rp_crd_ctl_u {
+-      mmr_t   sh_xn_md_rp_crd_ctl_regval;
+-      struct {
+-              mmr_t   reserved_0  : 58;
+-              mmr_t   depth       : 6;
+-      } sh_xn_md_rp_crd_ctl_s;
+-} sh_xn_md_rp_crd_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG0"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag0_u {
+       mmr_t   sh_x_tag0_regval;
+       struct {
+@@ -23062,22 +12438,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag0_s;
+ } sh_x_tag0_u_t;
+-#else
+-typedef union sh_x_tag0_u {
+-      mmr_t   sh_x_tag0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag0_s;
+-} sh_x_tag0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG1"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag1_u {
+       mmr_t   sh_x_tag1_regval;
+       struct {
+@@ -23085,22 +12451,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag1_s;
+ } sh_x_tag1_u_t;
+-#else
+-typedef union sh_x_tag1_u {
+-      mmr_t   sh_x_tag1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag1_s;
+-} sh_x_tag1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG2"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag2_u {
+       mmr_t   sh_x_tag2_regval;
+       struct {
+@@ -23108,22 +12464,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag2_s;
+ } sh_x_tag2_u_t;
+-#else
+-typedef union sh_x_tag2_u {
+-      mmr_t   sh_x_tag2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag2_s;
+-} sh_x_tag2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG3"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag3_u {
+       mmr_t   sh_x_tag3_regval;
+       struct {
+@@ -23131,22 +12477,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag3_s;
+ } sh_x_tag3_u_t;
+-#else
+-typedef union sh_x_tag3_u {
+-      mmr_t   sh_x_tag3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag3_s;
+-} sh_x_tag3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG4"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag4_u {
+       mmr_t   sh_x_tag4_regval;
+       struct {
+@@ -23154,22 +12490,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag4_s;
+ } sh_x_tag4_u_t;
+-#else
+-typedef union sh_x_tag4_u {
+-      mmr_t   sh_x_tag4_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag4_s;
+-} sh_x_tag4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG5"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag5_u {
+       mmr_t   sh_x_tag5_regval;
+       struct {
+@@ -23177,22 +12503,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag5_s;
+ } sh_x_tag5_u_t;
+-#else
+-typedef union sh_x_tag5_u {
+-      mmr_t   sh_x_tag5_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag5_s;
+-} sh_x_tag5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG6"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag6_u {
+       mmr_t   sh_x_tag6_regval;
+       struct {
+@@ -23200,22 +12516,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag6_s;
+ } sh_x_tag6_u_t;
+-#else
+-typedef union sh_x_tag6_u {
+-      mmr_t   sh_x_tag6_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag6_s;
+-} sh_x_tag6_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_X_TAG7"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag7_u {
+       mmr_t   sh_x_tag7_regval;
+       struct {
+@@ -23223,22 +12529,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_x_tag7_s;
+ } sh_x_tag7_u_t;
+-#else
+-typedef union sh_x_tag7_u {
+-      mmr_t   sh_x_tag7_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_x_tag7_s;
+-} sh_x_tag7_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG0"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag0_u {
+       mmr_t   sh_y_tag0_regval;
+       struct {
+@@ -23246,22 +12542,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag0_s;
+ } sh_y_tag0_u_t;
+-#else
+-typedef union sh_y_tag0_u {
+-      mmr_t   sh_y_tag0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag0_s;
+-} sh_y_tag0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG1"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag1_u {
+       mmr_t   sh_y_tag1_regval;
+       struct {
+@@ -23269,22 +12555,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag1_s;
+ } sh_y_tag1_u_t;
+-#else
+-typedef union sh_y_tag1_u {
+-      mmr_t   sh_y_tag1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag1_s;
+-} sh_y_tag1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG2"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag2_u {
+       mmr_t   sh_y_tag2_regval;
+       struct {
+@@ -23292,22 +12568,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag2_s;
+ } sh_y_tag2_u_t;
+-#else
+-typedef union sh_y_tag2_u {
+-      mmr_t   sh_y_tag2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag2_s;
+-} sh_y_tag2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG3"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag3_u {
+       mmr_t   sh_y_tag3_regval;
+       struct {
+@@ -23315,22 +12581,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag3_s;
+ } sh_y_tag3_u_t;
+-#else
+-typedef union sh_y_tag3_u {
+-      mmr_t   sh_y_tag3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag3_s;
+-} sh_y_tag3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG4"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag4_u {
+       mmr_t   sh_y_tag4_regval;
+       struct {
+@@ -23338,22 +12594,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag4_s;
+ } sh_y_tag4_u_t;
+-#else
+-typedef union sh_y_tag4_u {
+-      mmr_t   sh_y_tag4_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag4_s;
+-} sh_y_tag4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG5"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag5_u {
+       mmr_t   sh_y_tag5_regval;
+       struct {
+@@ -23361,22 +12607,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag5_s;
+ } sh_y_tag5_u_t;
+-#else
+-typedef union sh_y_tag5_u {
+-      mmr_t   sh_y_tag5_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag5_s;
+-} sh_y_tag5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG6"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag6_u {
+       mmr_t   sh_y_tag6_regval;
+       struct {
+@@ -23384,22 +12620,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag6_s;
+ } sh_y_tag6_u_t;
+-#else
+-typedef union sh_y_tag6_u {
+-      mmr_t   sh_y_tag6_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag6_s;
+-} sh_y_tag6_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                         Register "SH_Y_TAG7"                         */
+ /*                           AC tag Registers                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag7_u {
+       mmr_t   sh_y_tag7_regval;
+       struct {
+@@ -23407,22 +12633,12 @@
+               mmr_t   reserved_0  : 44;
+       } sh_y_tag7_s;
+ } sh_y_tag7_u_t;
+-#else
+-typedef union sh_y_tag7_u {
+-      mmr_t   sh_y_tag7_regval;
+-      struct {
+-              mmr_t   reserved_0  : 44;
+-              mmr_t   tag         : 20;
+-      } sh_y_tag7_s;
+-} sh_y_tag7_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_MMRBIST_BASE"                      */
+ /*                        mmr/bist base address                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mmrbist_base_u {
+       mmr_t   sh_mmrbist_base_regval;
+       struct {
+@@ -23431,23 +12647,12 @@
+               mmr_t   reserved_1  : 14;
+       } sh_mmrbist_base_s;
+ } sh_mmrbist_base_u_t;
+-#else
+-typedef union sh_mmrbist_base_u {
+-      mmr_t   sh_mmrbist_base_regval;
+-      struct {
+-              mmr_t   reserved_1  : 14;
+-              mmr_t   dword_addr  : 47;
+-              mmr_t   reserved_0  : 3;
+-      } sh_mmrbist_base_s;
+-} sh_mmrbist_base_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_MMRBIST_CTL"                       */
+ /*                          Bist base address                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mmrbist_ctl_u {
+       mmr_t   sh_mmrbist_ctl_regval;
+       struct {
+@@ -23463,30 +12668,12 @@
+               mmr_t   reserved_3   : 19;
+       } sh_mmrbist_ctl_s;
+ } sh_mmrbist_ctl_u_t;
+-#else
+-typedef union sh_mmrbist_ctl_u {
+-      mmr_t   sh_mmrbist_ctl_regval;
+-      struct {
+-              mmr_t   reserved_3   : 19;
+-              mmr_t   reset_state  : 1;
+-              mmr_t   reserved_2   : 1;
+-              mmr_t   mem_idle     : 1;
+-              mmr_t   fail         : 1;
+-              mmr_t   in_progress  : 1;
+-              mmr_t   reserved_1   : 1;
+-              mmr_t   cmd          : 7;
+-              mmr_t   reserved_0   : 1;
+-              mmr_t   block_length : 31;
+-      } sh_mmrbist_ctl_s;
+-} sh_mmrbist_ctl_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_MD_DBUG_DATA_CFG"                    */
+ /*                configuration for md debug data muxes                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dbug_data_cfg_u {
+       mmr_t   sh_md_dbug_data_cfg_regval;
+       struct {
+@@ -23524,52 +12711,12 @@
+               mmr_t   reserved_15     : 1;
+       } sh_md_dbug_data_cfg_s;
+ } sh_md_dbug_data_cfg_u_t;
+-#else
+-typedef union sh_md_dbug_data_cfg_u {
+-      mmr_t   sh_md_dbug_data_cfg_regval;
+-      struct {
+-              mmr_t   reserved_15     : 1;
+-              mmr_t   nibble7_nibble  : 3;
+-              mmr_t   reserved_14     : 1;
+-              mmr_t   nibble7_chiplet : 3;
+-              mmr_t   reserved_13     : 1;
+-              mmr_t   nibble6_nibble  : 3;
+-              mmr_t   reserved_12     : 1;
+-              mmr_t   nibble6_chiplet : 3;
+-              mmr_t   reserved_11     : 1;
+-              mmr_t   nibble5_nibble  : 3;
+-              mmr_t   reserved_10     : 1;
+-              mmr_t   nibble5_chiplet : 3;
+-              mmr_t   reserved_9      : 1;
+-              mmr_t   nibble4_nibble  : 3;
+-              mmr_t   reserved_8      : 1;
+-              mmr_t   nibble4_chiplet : 3;
+-              mmr_t   reserved_7      : 1;
+-              mmr_t   nibble3_nibble  : 3;
+-              mmr_t   reserved_6      : 1;
+-              mmr_t   nibble3_chiplet : 3;
+-              mmr_t   reserved_5      : 1;
+-              mmr_t   nibble2_nibble  : 3;
+-              mmr_t   reserved_4      : 1;
+-              mmr_t   nibble2_chiplet : 3;
+-              mmr_t   reserved_3      : 1;
+-              mmr_t   nibble1_nibble  : 3;
+-              mmr_t   reserved_2      : 1;
+-              mmr_t   nibble1_chiplet : 3;
+-              mmr_t   reserved_1      : 1;
+-              mmr_t   nibble0_nibble  : 3;
+-              mmr_t   reserved_0      : 1;
+-              mmr_t   nibble0_chiplet : 3;
+-      } sh_md_dbug_data_cfg_s;
+-} sh_md_dbug_data_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DBUG_TRIGGER_CFG"                   */
+ /*                 configuration for md debug triggers                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dbug_trigger_cfg_u {
+       mmr_t   sh_md_dbug_trigger_cfg_regval;
+       struct {
+@@ -23607,75 +12754,25 @@
+               mmr_t   enable          : 1;
+       } sh_md_dbug_trigger_cfg_s;
+ } sh_md_dbug_trigger_cfg_u_t;
+-#else
+-typedef union sh_md_dbug_trigger_cfg_u {
+-      mmr_t   sh_md_dbug_trigger_cfg_regval;
+-      struct {
+-              mmr_t   enable          : 1;
+-              mmr_t   nibble7_nibble  : 3;
+-              mmr_t   reserved_14     : 1;
+-              mmr_t   nibble7_chiplet : 3;
+-              mmr_t   reserved_13     : 1;
+-              mmr_t   nibble6_nibble  : 3;
+-              mmr_t   reserved_12     : 1;
+-              mmr_t   nibble6_chiplet : 3;
+-              mmr_t   reserved_11     : 1;
+-              mmr_t   nibble5_nibble  : 3;
+-              mmr_t   reserved_10     : 1;
+-              mmr_t   nibble5_chiplet : 3;
+-              mmr_t   reserved_9      : 1;
+-              mmr_t   nibble4_nibble  : 3;
+-              mmr_t   reserved_8      : 1;
+-              mmr_t   nibble4_chiplet : 3;
+-              mmr_t   reserved_7      : 1;
+-              mmr_t   nibble3_nibble  : 3;
+-              mmr_t   reserved_6      : 1;
+-              mmr_t   nibble3_chiplet : 3;
+-              mmr_t   reserved_5      : 1;
+-              mmr_t   nibble2_nibble  : 3;
+-              mmr_t   reserved_4      : 1;
+-              mmr_t   nibble2_chiplet : 3;
+-              mmr_t   reserved_3      : 1;
+-              mmr_t   nibble1_nibble  : 3;
+-              mmr_t   reserved_2      : 1;
+-              mmr_t   nibble1_chiplet : 3;
+-              mmr_t   reserved_1      : 1;
+-              mmr_t   nibble0_nibble  : 3;
+-              mmr_t   reserved_0      : 1;
+-              mmr_t   nibble0_chiplet : 3;
+-      } sh_md_dbug_trigger_cfg_s;
+-} sh_md_dbug_trigger_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_MD_DBUG_COMPARE"                     */
+ /*                  md debug compare pattern and mask                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dbug_compare_u {
+       mmr_t   sh_md_dbug_compare_regval;
+       struct {
+               mmr_t   pattern     : 32;
+-              mmr_t   mask        : 32;
+-      } sh_md_dbug_compare_s;
+-} sh_md_dbug_compare_u_t;
+-#else
+-typedef union sh_md_dbug_compare_u {
+-      mmr_t   sh_md_dbug_compare_regval;
+-      struct {
+-              mmr_t   mask        : 32;
+-              mmr_t   pattern     : 32;
++              mmr_t   mask        : 32;
+       } sh_md_dbug_compare_s;
+ } sh_md_dbug_compare_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_X_MOD_DBUG_SEL"                     */
+ /*                         MD acx debug select                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_mod_dbug_sel_u {
+       mmr_t   sh_x_mod_dbug_sel_regval;
+       struct {
+@@ -23689,28 +12786,12 @@
+               mmr_t   reserved_0  : 6;
+       } sh_x_mod_dbug_sel_s;
+ } sh_x_mod_dbug_sel_u_t;
+-#else
+-typedef union sh_x_mod_dbug_sel_u {
+-      mmr_t   sh_x_mod_dbug_sel_regval;
+-      struct {
+-              mmr_t   reserved_0  : 6;
+-              mmr_t   dqr_sel     : 6;
+-              mmr_t   dql_sel     : 6;
+-              mmr_t   atr_sel     : 11;
+-              mmr_t   atl_sel     : 11;
+-              mmr_t   arb_sel     : 8;
+-              mmr_t   wbq_sel     : 8;
+-              mmr_t   tag_sel     : 8;
+-      } sh_x_mod_dbug_sel_s;
+-} sh_x_mod_dbug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_X_DBUG_SEL"                       */
+ /*                         MD acx debug select                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_dbug_sel_u {
+       mmr_t   sh_x_dbug_sel_regval;
+       struct {
+@@ -23718,22 +12799,12 @@
+               mmr_t   reserved_0  : 40;
+       } sh_x_dbug_sel_s;
+ } sh_x_dbug_sel_u_t;
+-#else
+-typedef union sh_x_dbug_sel_u {
+-      mmr_t   sh_x_dbug_sel_regval;
+-      struct {
+-              mmr_t   reserved_0  : 40;
+-              mmr_t   dbg_sel     : 24;
+-      } sh_x_dbug_sel_s;
+-} sh_x_dbug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_X_LADDR_CMP"                       */
+ /*                        MD acx address compare                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_laddr_cmp_u {
+       mmr_t   sh_x_laddr_cmp_regval;
+       struct {
+@@ -23743,24 +12814,12 @@
+               mmr_t   reserved_1  : 4;
+       } sh_x_laddr_cmp_s;
+ } sh_x_laddr_cmp_u_t;
+-#else
+-typedef union sh_x_laddr_cmp_u {
+-      mmr_t   sh_x_laddr_cmp_regval;
+-      struct {
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   mask_val    : 28;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   cmp_val     : 28;
+-      } sh_x_laddr_cmp_s;
+-} sh_x_laddr_cmp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_X_RADDR_CMP"                       */
+ /*                        MD acx address compare                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_raddr_cmp_u {
+       mmr_t   sh_x_raddr_cmp_regval;
+       struct {
+@@ -23770,24 +12829,12 @@
+               mmr_t   reserved_1  : 4;
+       } sh_x_raddr_cmp_s;
+ } sh_x_raddr_cmp_u_t;
+-#else
+-typedef union sh_x_raddr_cmp_u {
+-      mmr_t   sh_x_raddr_cmp_regval;
+-      struct {
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   mask_val    : 28;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   cmp_val     : 28;
+-      } sh_x_raddr_cmp_s;
+-} sh_x_raddr_cmp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_X_TAG_CMP"                        */
+ /*                        MD acx tagmgr compare                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag_cmp_u {
+       mmr_t   sh_x_tag_cmp_regval;
+       struct {
+@@ -23797,24 +12844,12 @@
+               mmr_t   reserved_0  : 9;
+       } sh_x_tag_cmp_s;
+ } sh_x_tag_cmp_u_t;
+-#else
+-typedef union sh_x_tag_cmp_u {
+-      mmr_t   sh_x_tag_cmp_regval;
+-      struct {
+-              mmr_t   reserved_0  : 9;
+-              mmr_t   src         : 14;
+-              mmr_t   addr        : 33;
+-              mmr_t   cmd         : 8;
+-      } sh_x_tag_cmp_s;
+-} sh_x_tag_cmp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_X_TAG_MASK"                       */
+ /*                          MD acx tagmgr mask                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_x_tag_mask_u {
+       mmr_t   sh_x_tag_mask_regval;
+       struct {
+@@ -23824,24 +12859,12 @@
+               mmr_t   reserved_0  : 9;
+       } sh_x_tag_mask_s;
+ } sh_x_tag_mask_u_t;
+-#else
+-typedef union sh_x_tag_mask_u {
+-      mmr_t   sh_x_tag_mask_regval;
+-      struct {
+-              mmr_t   reserved_0  : 9;
+-              mmr_t   src         : 14;
+-              mmr_t   addr        : 33;
+-              mmr_t   cmd         : 8;
+-      } sh_x_tag_mask_s;
+-} sh_x_tag_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_Y_MOD_DBUG_SEL"                     */
+ /*                         MD acy debug select                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_mod_dbug_sel_u {
+       mmr_t   sh_y_mod_dbug_sel_regval;
+       struct {
+@@ -23855,28 +12878,12 @@
+               mmr_t   reserved_0  : 6;
+       } sh_y_mod_dbug_sel_s;
+ } sh_y_mod_dbug_sel_u_t;
+-#else
+-typedef union sh_y_mod_dbug_sel_u {
+-      mmr_t   sh_y_mod_dbug_sel_regval;
+-      struct {
+-              mmr_t   reserved_0  : 6;
+-              mmr_t   dqr_sel     : 6;
+-              mmr_t   dql_sel     : 6;
+-              mmr_t   atr_sel     : 11;
+-              mmr_t   atl_sel     : 11;
+-              mmr_t   arb_sel     : 8;
+-              mmr_t   wbq_sel     : 8;
+-              mmr_t   tag_sel     : 8;
+-      } sh_y_mod_dbug_sel_s;
+-} sh_y_mod_dbug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_Y_DBUG_SEL"                       */
+ /*                         MD acy debug select                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_dbug_sel_u {
+       mmr_t   sh_y_dbug_sel_regval;
+       struct {
+@@ -23884,22 +12891,12 @@
+               mmr_t   reserved_0  : 40;
+       } sh_y_dbug_sel_s;
+ } sh_y_dbug_sel_u_t;
+-#else
+-typedef union sh_y_dbug_sel_u {
+-      mmr_t   sh_y_dbug_sel_regval;
+-      struct {
+-              mmr_t   reserved_0  : 40;
+-              mmr_t   dbg_sel     : 24;
+-      } sh_y_dbug_sel_s;
+-} sh_y_dbug_sel_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_Y_LADDR_CMP"                       */
+ /*                        MD acy address compare                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_laddr_cmp_u {
+       mmr_t   sh_y_laddr_cmp_regval;
+       struct {
+@@ -23909,24 +12906,12 @@
+               mmr_t   reserved_1  : 4;
+       } sh_y_laddr_cmp_s;
+ } sh_y_laddr_cmp_u_t;
+-#else
+-typedef union sh_y_laddr_cmp_u {
+-      mmr_t   sh_y_laddr_cmp_regval;
+-      struct {
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   mask_val    : 28;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   cmp_val     : 28;
+-      } sh_y_laddr_cmp_s;
+-} sh_y_laddr_cmp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                      Register "SH_Y_RADDR_CMP"                       */
+ /*                        MD acy address compare                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_raddr_cmp_u {
+       mmr_t   sh_y_raddr_cmp_regval;
+       struct {
+@@ -23936,24 +12921,12 @@
+               mmr_t   reserved_1  : 4;
+       } sh_y_raddr_cmp_s;
+ } sh_y_raddr_cmp_u_t;
+-#else
+-typedef union sh_y_raddr_cmp_u {
+-      mmr_t   sh_y_raddr_cmp_regval;
+-      struct {
+-              mmr_t   reserved_1  : 4;
+-              mmr_t   mask_val    : 28;
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   cmp_val     : 28;
+-      } sh_y_raddr_cmp_s;
+-} sh_y_raddr_cmp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_Y_TAG_CMP"                        */
+ /*                        MD acy tagmgr compare                         */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag_cmp_u {
+       mmr_t   sh_y_tag_cmp_regval;
+       struct {
+@@ -23963,24 +12936,12 @@
+               mmr_t   reserved_0  : 9;
+       } sh_y_tag_cmp_s;
+ } sh_y_tag_cmp_u_t;
+-#else
+-typedef union sh_y_tag_cmp_u {
+-      mmr_t   sh_y_tag_cmp_regval;
+-      struct {
+-              mmr_t   reserved_0  : 9;
+-              mmr_t   src         : 14;
+-              mmr_t   addr        : 33;
+-              mmr_t   cmd         : 8;
+-      } sh_y_tag_cmp_s;
+-} sh_y_tag_cmp_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                       Register "SH_Y_TAG_MASK"                       */
+ /*                          MD acy tagmgr mask                          */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_y_tag_mask_u {
+       mmr_t   sh_y_tag_mask_regval;
+       struct {
+@@ -23990,24 +12951,12 @@
+               mmr_t   reserved_0  : 9;
+       } sh_y_tag_mask_s;
+ } sh_y_tag_mask_u_t;
+-#else
+-typedef union sh_y_tag_mask_u {
+-      mmr_t   sh_y_tag_mask_regval;
+-      struct {
+-              mmr_t   reserved_0  : 9;
+-              mmr_t   src         : 14;
+-              mmr_t   addr        : 33;
+-              mmr_t   cmd         : 8;
+-      } sh_y_tag_mask_s;
+-} sh_y_tag_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_JNR_DBUG_DATA_CFG"                  */
+ /*              configuration for md jnr debug data muxes               */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_jnr_dbug_data_cfg_u {
+       mmr_t   sh_md_jnr_dbug_data_cfg_regval;
+       struct {
+@@ -24029,36 +12978,12 @@
+               mmr_t   reserved_7  : 33;
+       } sh_md_jnr_dbug_data_cfg_s;
+ } sh_md_jnr_dbug_data_cfg_u_t;
+-#else
+-typedef union sh_md_jnr_dbug_data_cfg_u {
+-      mmr_t   sh_md_jnr_dbug_data_cfg_regval;
+-      struct {
+-              mmr_t   reserved_7  : 33;
+-              mmr_t   nibble7_sel : 3;
+-              mmr_t   reserved_6  : 1;
+-              mmr_t   nibble6_sel : 3;
+-              mmr_t   reserved_5  : 1;
+-              mmr_t   nibble5_sel : 3;
+-              mmr_t   reserved_4  : 1;
+-              mmr_t   nibble4_sel : 3;
+-              mmr_t   reserved_3  : 1;
+-              mmr_t   nibble3_sel : 3;
+-              mmr_t   reserved_2  : 1;
+-              mmr_t   nibble2_sel : 3;
+-              mmr_t   reserved_1  : 1;
+-              mmr_t   nibble1_sel : 3;
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   nibble0_sel : 3;
+-      } sh_md_jnr_dbug_data_cfg_s;
+-} sh_md_jnr_dbug_data_cfg_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                     Register "SH_MD_LAST_CREDIT"                     */
+ /*                 captures last credit values on reset                 */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_last_credit_u {
+       mmr_t   sh_md_last_credit_regval;
+       struct {
+@@ -24074,30 +12999,12 @@
+               mmr_t   reserved_4  : 26;
+       } sh_md_last_credit_s;
+ } sh_md_last_credit_u_t;
+-#else
+-typedef union sh_md_last_credit_u {
+-      mmr_t   sh_md_last_credit_regval;
+-      struct {
+-              mmr_t   reserved_4  : 26;
+-              mmr_t   to_lb       : 6;
+-              mmr_t   reserved_3  : 2;
+-              mmr_t   rp_to_xn    : 6;
+-              mmr_t   reserved_2  : 2;
+-              mmr_t   rq_to_xn    : 6;
+-              mmr_t   reserved_1  : 2;
+-              mmr_t   rp_to_pi    : 6;
+-              mmr_t   reserved_0  : 2;
+-              mmr_t   rq_to_pi    : 6;
+-      } sh_md_last_credit_s;
+-} sh_md_last_credit_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_MEM_CAPTURE_ADDR"                    */
+ /*                   Address capture address register                   */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_capture_addr_u {
+       mmr_t   sh_mem_capture_addr_regval;
+       struct {
+@@ -24107,24 +13014,12 @@
+               mmr_t   reserved_1  : 20;
+       } sh_mem_capture_addr_s;
+ } sh_mem_capture_addr_u_t;
+-#else
+-typedef union sh_mem_capture_addr_u {
+-      mmr_t   sh_mem_capture_addr_regval;
+-      struct {
+-              mmr_t   reserved_1  : 20;
+-              mmr_t   cmd         : 8;
+-              mmr_t   addr        : 33;
+-              mmr_t   reserved_0  : 3;
+-      } sh_mem_capture_addr_s;
+-} sh_mem_capture_addr_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_MEM_CAPTURE_MASK"                    */
+ /*                    Address capture mask register                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_capture_mask_u {
+       mmr_t   sh_mem_capture_mask_regval;
+       struct {
+@@ -24136,26 +13031,12 @@
+               mmr_t   reserved_1    : 18;
+       } sh_mem_capture_mask_s;
+ } sh_mem_capture_mask_u_t;
+-#else
+-typedef union sh_mem_capture_mask_u {
+-      mmr_t   sh_mem_capture_mask_regval;
+-      struct {
+-              mmr_t   reserved_1    : 18;
+-              mmr_t   enable_remote : 1;
+-              mmr_t   enable_local  : 1;
+-              mmr_t   cmd           : 8;
+-              mmr_t   addr          : 33;
+-              mmr_t   reserved_0    : 3;
+-      } sh_mem_capture_mask_s;
+-} sh_mem_capture_mask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                    Register "SH_MEM_CAPTURE_HDR"                     */
+ /*                   Address capture header register                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_mem_capture_hdr_u {
+       mmr_t   sh_mem_capture_hdr_regval;
+       struct {
+@@ -24166,25 +13047,12 @@
+               mmr_t   cntr        : 6;
+       } sh_mem_capture_hdr_s;
+ } sh_mem_capture_hdr_u_t;
+-#else
+-typedef union sh_mem_capture_hdr_u {
+-      mmr_t   sh_mem_capture_hdr_regval;
+-      struct {
+-              mmr_t   cntr        : 6;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   addr        : 33;
+-              mmr_t   reserved_0  : 3;
+-      } sh_mem_capture_hdr_s;
+-} sh_mem_capture_hdr_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQLP_MMR_DIR_CONFIG"                 */
+ /*                     DQ directory config register                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_config_u {
+       mmr_t   sh_md_dqlp_mmr_dir_config_regval;
+       struct {
+@@ -24194,276 +13062,156 @@
+               mmr_t   reserved_0  : 59;
+       } sh_md_dqlp_mmr_dir_config_s;
+ } sh_md_dqlp_mmr_dir_config_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_config_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_config_regval;
+-      struct {
+-              mmr_t   reserved_0  : 59;
+-              mmr_t   en_dirpois  : 1;
+-              mmr_t   en_direcc   : 1;
+-              mmr_t   sys_size    : 3;
+-      } sh_md_dqlp_mmr_dir_config_s;
+-} sh_md_dqlp_mmr_dir_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC0"                */
+ /*                      node [63:0] presence bits                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_presvec0_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_presvec0_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_presvec0_s;
+-} sh_md_dqlp_mmr_dir_presvec0_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_presvec0_u {
+       mmr_t   sh_md_dqlp_mmr_dir_presvec0_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_presvec0_s;
+ } sh_md_dqlp_mmr_dir_presvec0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC1"                */
+ /*                     node [127:64] presence bits                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_presvec1_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_presvec1_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_presvec1_s;
+-} sh_md_dqlp_mmr_dir_presvec1_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_presvec1_u {
+       mmr_t   sh_md_dqlp_mmr_dir_presvec1_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_presvec1_s;
+ } sh_md_dqlp_mmr_dir_presvec1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC2"                */
+ /*                     node [191:128] presence bits                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_presvec2_u {
+       mmr_t   sh_md_dqlp_mmr_dir_presvec2_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_presvec2_s;
+ } sh_md_dqlp_mmr_dir_presvec2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_presvec2_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_presvec2_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_presvec2_s;
+-} sh_md_dqlp_mmr_dir_presvec2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRESVEC3"                */
+ /*                     node [255:192] presence bits                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_presvec3_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_presvec3_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_presvec3_s;
+-} sh_md_dqlp_mmr_dir_presvec3_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_presvec3_u {
+       mmr_t   sh_md_dqlp_mmr_dir_presvec3_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_presvec3_s;
+ } sh_md_dqlp_mmr_dir_presvec3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC0"                 */
+ /*                        local vector for acc=0                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec0_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec0_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec0_s;
+-} sh_md_dqlp_mmr_dir_locvec0_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec0_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec0_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec0_s;
+ } sh_md_dqlp_mmr_dir_locvec0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC1"                 */
+ /*                        local vector for acc=1                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec1_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec1_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec1_s;
+-} sh_md_dqlp_mmr_dir_locvec1_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec1_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec1_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec1_s;
+ } sh_md_dqlp_mmr_dir_locvec1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC2"                 */
+ /*                        local vector for acc=2                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_locvec2_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec2_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec2_s;
+ } sh_md_dqlp_mmr_dir_locvec2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_locvec2_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec2_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec2_s;
+-} sh_md_dqlp_mmr_dir_locvec2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC3"                 */
+ /*                        local vector for acc=3                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec3_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec3_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec3_s;
+-} sh_md_dqlp_mmr_dir_locvec3_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec3_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec3_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec3_s;
+ } sh_md_dqlp_mmr_dir_locvec3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC4"                 */
+ /*                        local vector for acc=4                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec4_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec4_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec4_s;
+-} sh_md_dqlp_mmr_dir_locvec4_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec4_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec4_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec4_s;
+ } sh_md_dqlp_mmr_dir_locvec4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC5"                 */
+ /*                        local vector for acc=5                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec5_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec5_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec5_s;
+-} sh_md_dqlp_mmr_dir_locvec5_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec5_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec5_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec5_s;
+ } sh_md_dqlp_mmr_dir_locvec5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC6"                 */
+ /*                        local vector for acc=6                        */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec6_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec6_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec6_s;
+-} sh_md_dqlp_mmr_dir_locvec6_u_t;
+-#else
++/* ==================================================================== */
++
+ typedef union sh_md_dqlp_mmr_dir_locvec6_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec6_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec6_s;
+ } sh_md_dqlp_mmr_dir_locvec6_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_LOCVEC7"                 */
+ /*                        local vector for acc=7                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqlp_mmr_dir_locvec7_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_locvec7_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqlp_mmr_dir_locvec7_s;
+-} sh_md_dqlp_mmr_dir_locvec7_u_t;
+-#else
+ typedef union sh_md_dqlp_mmr_dir_locvec7_u {
+       mmr_t   sh_md_dqlp_mmr_dir_locvec7_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqlp_mmr_dir_locvec7_s;
+ } sh_md_dqlp_mmr_dir_locvec7_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC0"                 */
+ /*                      privilege vector for acc=0                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec0_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec0_regval;
+       struct {
+@@ -24472,23 +13220,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec0_s;
+ } sh_md_dqlp_mmr_dir_privec0_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec0_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec0_s;
+-} sh_md_dqlp_mmr_dir_privec0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC1"                 */
+ /*                      privilege vector for acc=1                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec1_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec1_regval;
+       struct {
+@@ -24497,23 +13234,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec1_s;
+ } sh_md_dqlp_mmr_dir_privec1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec1_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec1_s;
+-} sh_md_dqlp_mmr_dir_privec1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC2"                 */
+ /*                      privilege vector for acc=2                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec2_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec2_regval;
+       struct {
+@@ -24522,23 +13248,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec2_s;
+ } sh_md_dqlp_mmr_dir_privec2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec2_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec2_s;
+-} sh_md_dqlp_mmr_dir_privec2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC3"                 */
+ /*                      privilege vector for acc=3                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec3_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec3_regval;
+       struct {
+@@ -24547,23 +13262,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec3_s;
+ } sh_md_dqlp_mmr_dir_privec3_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec3_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec3_s;
+-} sh_md_dqlp_mmr_dir_privec3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC4"                 */
+ /*                      privilege vector for acc=4                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec4_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec4_regval;
+       struct {
+@@ -24572,23 +13276,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec4_s;
+ } sh_md_dqlp_mmr_dir_privec4_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec4_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec4_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec4_s;
+-} sh_md_dqlp_mmr_dir_privec4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC5"                 */
+ /*                      privilege vector for acc=5                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec5_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec5_regval;
+       struct {
+@@ -24597,23 +13290,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec5_s;
+ } sh_md_dqlp_mmr_dir_privec5_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec5_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec5_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec5_s;
+-} sh_md_dqlp_mmr_dir_privec5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC6"                 */
+ /*                      privilege vector for acc=6                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec6_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec6_regval;
+       struct {
+@@ -24622,23 +13304,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec6_s;
+ } sh_md_dqlp_mmr_dir_privec6_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec6_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec6_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec6_s;
+-} sh_md_dqlp_mmr_dir_privec6_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC7"                 */
+ /*                      privilege vector for acc=7                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_privec7_u {
+       mmr_t   sh_md_dqlp_mmr_dir_privec7_regval;
+       struct {
+@@ -24647,23 +13318,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqlp_mmr_dir_privec7_s;
+ } sh_md_dqlp_mmr_dir_privec7_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_privec7_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_privec7_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqlp_mmr_dir_privec7_s;
+-} sh_md_dqlp_mmr_dir_privec7_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQLP_MMR_DIR_TIMER"                  */
+ /*                            MD SXRO timer                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_timer_u {
+       mmr_t   sh_md_dqlp_mmr_dir_timer_regval;
+       struct {
+@@ -24673,24 +13333,12 @@
+               mmr_t   reserved_0  : 42;
+       } sh_md_dqlp_mmr_dir_timer_s;
+ } sh_md_dqlp_mmr_dir_timer_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_timer_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_timer_regval;
+-      struct {
+-              mmr_t   reserved_0  : 42;
+-              mmr_t   timer_cur   : 9;
+-              mmr_t   timer_en    : 1;
+-              mmr_t   timer_div   : 12;
+-      } sh_md_dqlp_mmr_dir_timer_s;
+-} sh_md_dqlp_mmr_dir_timer_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY"               */
+ /*                       directory pio write data                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_piowd_dir_entry_u {
+       mmr_t   sh_md_dqlp_mmr_piowd_dir_entry_regval;
+       struct {
+@@ -24701,25 +13349,12 @@
+               mmr_t   reserved_0  : 6;
+       } sh_md_dqlp_mmr_piowd_dir_entry_s;
+ } sh_md_dqlp_mmr_piowd_dir_entry_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_piowd_dir_entry_u {
+-      mmr_t   sh_md_dqlp_mmr_piowd_dir_entry_regval;
+-      struct {
+-              mmr_t   reserved_0  : 6;
+-              mmr_t   acc         : 3;
+-              mmr_t   pri         : 3;
+-              mmr_t   dirb        : 26;
+-              mmr_t   dira        : 26;
+-      } sh_md_dqlp_mmr_piowd_dir_entry_s;
+-} sh_md_dqlp_mmr_piowd_dir_entry_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_MD_DQLP_MMR_PIOWD_DIR_ECC"                */
+ /*                        directory ecc register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_piowd_dir_ecc_u {
+       mmr_t   sh_md_dqlp_mmr_piowd_dir_ecc_regval;
+       struct {
+@@ -24728,23 +13363,12 @@
+               mmr_t   reserved_0  : 50;
+       } sh_md_dqlp_mmr_piowd_dir_ecc_s;
+ } sh_md_dqlp_mmr_piowd_dir_ecc_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_piowd_dir_ecc_u {
+-      mmr_t   sh_md_dqlp_mmr_piowd_dir_ecc_regval;
+-      struct {
+-              mmr_t   reserved_0  : 50;
+-              mmr_t   eccb        : 7;
+-              mmr_t   ecca        : 7;
+-      } sh_md_dqlp_mmr_piowd_dir_ecc_s;
+-} sh_md_dqlp_mmr_piowd_dir_ecc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ENTRY"              */
+ /*                      x directory pio read data                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xpiord_xdir_entry_u {
+       mmr_t   sh_md_dqlp_mmr_xpiord_xdir_entry_regval;
+       struct {
+@@ -24757,27 +13381,12 @@
+               mmr_t   reserved_0  : 4;
+       } sh_md_dqlp_mmr_xpiord_xdir_entry_s;
+ } sh_md_dqlp_mmr_xpiord_xdir_entry_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xpiord_xdir_entry_u {
+-      mmr_t   sh_md_dqlp_mmr_xpiord_xdir_entry_regval;
+-      struct {
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   acc         : 3;
+-              mmr_t   pri         : 3;
+-              mmr_t   dirb        : 26;
+-              mmr_t   dira        : 26;
+-      } sh_md_dqlp_mmr_xpiord_xdir_entry_s;
+-} sh_md_dqlp_mmr_xpiord_xdir_entry_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_MD_DQLP_MMR_XPIORD_XDIR_ECC"               */
+ /*                           x directory ecc                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xpiord_xdir_ecc_u {
+       mmr_t   sh_md_dqlp_mmr_xpiord_xdir_ecc_regval;
+       struct {
+@@ -24786,23 +13395,12 @@
+               mmr_t   reserved_0  : 50;
+       } sh_md_dqlp_mmr_xpiord_xdir_ecc_s;
+ } sh_md_dqlp_mmr_xpiord_xdir_ecc_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xpiord_xdir_ecc_u {
+-      mmr_t   sh_md_dqlp_mmr_xpiord_xdir_ecc_regval;
+-      struct {
+-              mmr_t   reserved_0  : 50;
+-              mmr_t   eccb        : 7;
+-              mmr_t   ecca        : 7;
+-      } sh_md_dqlp_mmr_xpiord_xdir_ecc_s;
+-} sh_md_dqlp_mmr_xpiord_xdir_ecc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ENTRY"              */
+ /*                      y directory pio read data                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ypiord_ydir_entry_u {
+       mmr_t   sh_md_dqlp_mmr_ypiord_ydir_entry_regval;
+       struct {
+@@ -24815,27 +13413,12 @@
+               mmr_t   reserved_0  : 4;
+       } sh_md_dqlp_mmr_ypiord_ydir_entry_s;
+ } sh_md_dqlp_mmr_ypiord_ydir_entry_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ypiord_ydir_entry_u {
+-      mmr_t   sh_md_dqlp_mmr_ypiord_ydir_entry_regval;
+-      struct {
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   acc         : 3;
+-              mmr_t   pri         : 3;
+-              mmr_t   dirb        : 26;
+-              mmr_t   dira        : 26;
+-      } sh_md_dqlp_mmr_ypiord_ydir_entry_s;
+-} sh_md_dqlp_mmr_ypiord_ydir_entry_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_MD_DQLP_MMR_YPIORD_YDIR_ECC"               */
+ /*                           y directory ecc                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ypiord_ydir_ecc_u {
+       mmr_t   sh_md_dqlp_mmr_ypiord_ydir_ecc_regval;
+       struct {
+@@ -24844,23 +13427,12 @@
+               mmr_t   reserved_0  : 50;
+       } sh_md_dqlp_mmr_ypiord_ydir_ecc_s;
+ } sh_md_dqlp_mmr_ypiord_ydir_ecc_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ypiord_ydir_ecc_u {
+-      mmr_t   sh_md_dqlp_mmr_ypiord_ydir_ecc_regval;
+-      struct {
+-              mmr_t   reserved_0  : 50;
+-              mmr_t   eccb        : 7;
+-              mmr_t   ecca        : 7;
+-      } sh_md_dqlp_mmr_ypiord_ydir_ecc_s;
+-} sh_md_dqlp_mmr_ypiord_ydir_ecc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_XCERR1"                   */
+ /*              correctable dir ecc group 1 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xcerr1_u {
+       mmr_t   sh_md_dqlp_mmr_xcerr1_regval;
+       struct {
+@@ -24871,25 +13443,12 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqlp_mmr_xcerr1_s;
+ } sh_md_dqlp_mmr_xcerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xcerr1_u {
+-      mmr_t   sh_md_dqlp_mmr_xcerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqlp_mmr_xcerr1_s;
+-} sh_md_dqlp_mmr_xcerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_XCERR2"                   */
+ /*              correctable dir ecc group 2 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xcerr2_u {
+       mmr_t   sh_md_dqlp_mmr_xcerr2_regval;
+       struct {
+@@ -24899,24 +13458,12 @@
+               mmr_t   reserved_0  : 26;
+       } sh_md_dqlp_mmr_xcerr2_s;
+ } sh_md_dqlp_mmr_xcerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xcerr2_u {
+-      mmr_t   sh_md_dqlp_mmr_xcerr2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp2        : 36;
+-      } sh_md_dqlp_mmr_xcerr2_s;
+-} sh_md_dqlp_mmr_xcerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_XUERR1"                   */
+ /*             uncorrectable dir ecc group 1 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xuerr1_u {
+       mmr_t   sh_md_dqlp_mmr_xuerr1_regval;
+       struct {
+@@ -24927,25 +13474,12 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqlp_mmr_xuerr1_s;
+ } sh_md_dqlp_mmr_xuerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xuerr1_u {
+-      mmr_t   sh_md_dqlp_mmr_xuerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqlp_mmr_xuerr1_s;
+-} sh_md_dqlp_mmr_xuerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_XUERR2"                   */
+ /*             uncorrectable dir ecc group 2 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xuerr2_u {
+       mmr_t   sh_md_dqlp_mmr_xuerr2_regval;
+       struct {
+@@ -24955,24 +13489,12 @@
+               mmr_t   reserved_0  : 26;
+       } sh_md_dqlp_mmr_xuerr2_s;
+ } sh_md_dqlp_mmr_xuerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xuerr2_u {
+-      mmr_t   sh_md_dqlp_mmr_xuerr2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp2        : 36;
+-      } sh_md_dqlp_mmr_xuerr2_s;
+-} sh_md_dqlp_mmr_xuerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_XPERR"                    */
+ /*                       protocol error register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xperr_u {
+       mmr_t   sh_md_dqlp_mmr_xperr_regval;
+       struct {
+@@ -24990,32 +13512,12 @@
+               mmr_t   reserved_0  : 1;
+       } sh_md_dqlp_mmr_xperr_s;
+ } sh_md_dqlp_mmr_xperr_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xperr_u {
+-      mmr_t   sh_md_dqlp_mmr_xperr_regval;
+-      struct {
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   mybit       : 8;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   priv        : 1;
+-              mmr_t   prige       : 1;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   dir         : 26;
+-      } sh_md_dqlp_mmr_xperr_s;
+-} sh_md_dqlp_mmr_xperr_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_YCERR1"                   */
+ /*              correctable dir ecc group 1 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ycerr1_u {
+       mmr_t   sh_md_dqlp_mmr_ycerr1_regval;
+       struct {
+@@ -25026,25 +13528,12 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqlp_mmr_ycerr1_s;
+ } sh_md_dqlp_mmr_ycerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ycerr1_u {
+-      mmr_t   sh_md_dqlp_mmr_ycerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqlp_mmr_ycerr1_s;
+-} sh_md_dqlp_mmr_ycerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_YCERR2"                   */
+ /*              correctable dir ecc group 2 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ycerr2_u {
+       mmr_t   sh_md_dqlp_mmr_ycerr2_regval;
+       struct {
+@@ -25054,24 +13543,12 @@
+               mmr_t   reserved_0  : 26;
+       } sh_md_dqlp_mmr_ycerr2_s;
+ } sh_md_dqlp_mmr_ycerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ycerr2_u {
+-      mmr_t   sh_md_dqlp_mmr_ycerr2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp2        : 36;
+-      } sh_md_dqlp_mmr_ycerr2_s;
+-} sh_md_dqlp_mmr_ycerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_YUERR1"                   */
+ /*             uncorrectable dir ecc group 1 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_yuerr1_u {
+       mmr_t   sh_md_dqlp_mmr_yuerr1_regval;
+       struct {
+@@ -25082,25 +13559,12 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqlp_mmr_yuerr1_s;
+ } sh_md_dqlp_mmr_yuerr1_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_yuerr1_u {
+-      mmr_t   sh_md_dqlp_mmr_yuerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqlp_mmr_yuerr1_s;
+-} sh_md_dqlp_mmr_yuerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_YUERR2"                   */
+ /*             uncorrectable dir ecc group 2 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_yuerr2_u {
+       mmr_t   sh_md_dqlp_mmr_yuerr2_regval;
+       struct {
+@@ -25110,24 +13574,12 @@
+               mmr_t   reserved_0  : 26;
+       } sh_md_dqlp_mmr_yuerr2_s;
+ } sh_md_dqlp_mmr_yuerr2_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_yuerr2_u {
+-      mmr_t   sh_md_dqlp_mmr_yuerr2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp2        : 36;
+-      } sh_md_dqlp_mmr_yuerr2_s;
+-} sh_md_dqlp_mmr_yuerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQLP_MMR_YPERR"                    */
+ /*                       protocol error register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_yperr_u {
+       mmr_t   sh_md_dqlp_mmr_yperr_regval;
+       struct {
+@@ -25136,41 +13588,21 @@
+               mmr_t   src         : 14;
+               mmr_t   prige       : 1;
+               mmr_t   priv        : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   unc         : 1;
+-              mmr_t   mybit       : 8;
+-              mmr_t   val         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   arm         : 1;
+-              mmr_t   reserved_0  : 1;
+-      } sh_md_dqlp_mmr_yperr_s;
+-} sh_md_dqlp_mmr_yperr_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_yperr_u {
+-      mmr_t   sh_md_dqlp_mmr_yperr_regval;
+-      struct {
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   mybit       : 8;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   priv        : 1;
+-              mmr_t   prige       : 1;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   dir         : 26;
++              mmr_t   cor         : 1;
++              mmr_t   unc         : 1;
++              mmr_t   mybit       : 8;
++              mmr_t   val         : 1;
++              mmr_t   more        : 1;
++              mmr_t   arm         : 1;
++              mmr_t   reserved_0  : 1;
+       } sh_md_dqlp_mmr_yperr_s;
+ } sh_md_dqlp_mmr_yperr_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_CMDTRIG"                 */
+ /*                             cmd triggers                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_cmdtrig_u {
+       mmr_t   sh_md_dqlp_mmr_dir_cmdtrig_regval;
+       struct {
+@@ -25181,25 +13613,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_md_dqlp_mmr_dir_cmdtrig_s;
+ } sh_md_dqlp_mmr_dir_cmdtrig_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_cmdtrig_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_cmdtrig_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   cmd3        : 8;
+-              mmr_t   cmd2        : 8;
+-              mmr_t   cmd1        : 8;
+-              mmr_t   cmd0        : 8;
+-      } sh_md_dqlp_mmr_dir_cmdtrig_s;
+-} sh_md_dqlp_mmr_dir_cmdtrig_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_TBLTRIG"                 */
+ /*                          dir table trigger                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_tbltrig_u {
+       mmr_t   sh_md_dqlp_mmr_dir_tbltrig_regval;
+       struct {
+@@ -25212,27 +13631,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqlp_mmr_dir_tbltrig_s;
+ } sh_md_dqlp_mmr_dir_tbltrig_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_tbltrig_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_tbltrig_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   mybit       : 8;
+-              mmr_t   dirst       : 9;
+-              mmr_t   prige       : 1;
+-              mmr_t   acc         : 2;
+-              mmr_t   cmd         : 8;
+-              mmr_t   src         : 14;
+-      } sh_md_dqlp_mmr_dir_tbltrig_s;
+-} sh_md_dqlp_mmr_dir_tbltrig_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_DIR_TBLMASK"                 */
+ /*                        dir table trigger mask                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_dir_tblmask_u {
+       mmr_t   sh_md_dqlp_mmr_dir_tblmask_regval;
+       struct {
+@@ -25245,27 +13649,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqlp_mmr_dir_tblmask_s;
+ } sh_md_dqlp_mmr_dir_tblmask_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_dir_tblmask_u {
+-      mmr_t   sh_md_dqlp_mmr_dir_tblmask_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   mybit       : 8;
+-              mmr_t   dirst       : 9;
+-              mmr_t   prige       : 1;
+-              mmr_t   acc         : 2;
+-              mmr_t   cmd         : 8;
+-              mmr_t   src         : 14;
+-      } sh_md_dqlp_mmr_dir_tblmask_s;
+-} sh_md_dqlp_mmr_dir_tblmask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLP_MMR_XBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_h_u {
+       mmr_t   sh_md_dqlp_mmr_xbist_h_regval;
+       struct {
+@@ -25277,26 +13666,12 @@
+               mmr_t   reserved_1  : 21;
+       } sh_md_dqlp_mmr_xbist_h_s;
+ } sh_md_dqlp_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_h_u {
+-      mmr_t   sh_md_dqlp_mmr_xbist_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_xbist_h_s;
+-} sh_md_dqlp_mmr_xbist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLP_MMR_XBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_l_u {
+       mmr_t   sh_md_dqlp_mmr_xbist_l_regval;
+       struct {
+@@ -25307,25 +13682,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqlp_mmr_xbist_l_s;
+ } sh_md_dqlp_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_l_u {
+-      mmr_t   sh_md_dqlp_mmr_xbist_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_xbist_l_s;
+-} sh_md_dqlp_mmr_xbist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_XBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_err_h_u {
+       mmr_t   sh_md_dqlp_mmr_xbist_err_h_regval;
+       struct {
+@@ -25336,25 +13698,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqlp_mmr_xbist_err_h_s;
+ } sh_md_dqlp_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_err_h_u {
+-      mmr_t   sh_md_dqlp_mmr_xbist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_xbist_err_h_s;
+-} sh_md_dqlp_mmr_xbist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_XBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_xbist_err_l_u {
+       mmr_t   sh_md_dqlp_mmr_xbist_err_l_regval;
+       struct {
+@@ -25365,25 +13714,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqlp_mmr_xbist_err_l_s;
+ } sh_md_dqlp_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_xbist_err_l_u {
+-      mmr_t   sh_md_dqlp_mmr_xbist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_xbist_err_l_s;
+-} sh_md_dqlp_mmr_xbist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLP_MMR_YBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_h_u {
+       mmr_t   sh_md_dqlp_mmr_ybist_h_regval;
+       struct {
+@@ -25395,26 +13731,12 @@
+               mmr_t   reserved_1  : 21;
+       } sh_md_dqlp_mmr_ybist_h_s;
+ } sh_md_dqlp_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_h_u {
+-      mmr_t   sh_md_dqlp_mmr_ybist_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_ybist_h_s;
+-} sh_md_dqlp_mmr_ybist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLP_MMR_YBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_l_u {
+       mmr_t   sh_md_dqlp_mmr_ybist_l_regval;
+       struct {
+@@ -25425,25 +13747,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqlp_mmr_ybist_l_s;
+ } sh_md_dqlp_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_l_u {
+-      mmr_t   sh_md_dqlp_mmr_ybist_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_ybist_l_s;
+-} sh_md_dqlp_mmr_ybist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_YBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_err_h_u {
+       mmr_t   sh_md_dqlp_mmr_ybist_err_h_regval;
+       struct {
+@@ -25454,25 +13763,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqlp_mmr_ybist_err_h_s;
+ } sh_md_dqlp_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_err_h_u {
+-      mmr_t   sh_md_dqlp_mmr_ybist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_ybist_err_h_s;
+-} sh_md_dqlp_mmr_ybist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLP_MMR_YBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqlp_mmr_ybist_err_l_u {
+       mmr_t   sh_md_dqlp_mmr_ybist_err_l_regval;
+       struct {
+@@ -25483,25 +13779,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqlp_mmr_ybist_err_l_s;
+ } sh_md_dqlp_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqlp_mmr_ybist_err_l_u {
+-      mmr_t   sh_md_dqlp_mmr_ybist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqlp_mmr_ybist_err_l_s;
+-} sh_md_dqlp_mmr_ybist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLS_MMR_XBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_h_u {
+       mmr_t   sh_md_dqls_mmr_xbist_h_regval;
+       struct {
+@@ -25512,25 +13795,12 @@
+               mmr_t   reserved_0  : 21;
+       } sh_md_dqls_mmr_xbist_h_s;
+ } sh_md_dqls_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_h_u {
+-      mmr_t   sh_md_dqls_mmr_xbist_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_xbist_h_s;
+-} sh_md_dqls_mmr_xbist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLS_MMR_XBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_l_u {
+       mmr_t   sh_md_dqls_mmr_xbist_l_regval;
+       struct {
+@@ -25540,24 +13810,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqls_mmr_xbist_l_s;
+ } sh_md_dqls_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_l_u {
+-      mmr_t   sh_md_dqls_mmr_xbist_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_xbist_l_s;
+-} sh_md_dqls_mmr_xbist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLS_MMR_XBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_err_h_u {
+       mmr_t   sh_md_dqls_mmr_xbist_err_h_regval;
+       struct {
+@@ -25567,24 +13825,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqls_mmr_xbist_err_h_s;
+ } sh_md_dqls_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_err_h_u {
+-      mmr_t   sh_md_dqls_mmr_xbist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_xbist_err_h_s;
+-} sh_md_dqls_mmr_xbist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLS_MMR_XBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xbist_err_l_u {
+       mmr_t   sh_md_dqls_mmr_xbist_err_l_regval;
+       struct {
+@@ -25594,24 +13840,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqls_mmr_xbist_err_l_s;
+ } sh_md_dqls_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xbist_err_l_u {
+-      mmr_t   sh_md_dqls_mmr_xbist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_xbist_err_l_s;
+-} sh_md_dqls_mmr_xbist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLS_MMR_YBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_h_u {
+       mmr_t   sh_md_dqls_mmr_ybist_h_regval;
+       struct {
+@@ -25622,25 +13856,12 @@
+               mmr_t   reserved_0  : 21;
+       } sh_md_dqls_mmr_ybist_h_s;
+ } sh_md_dqls_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_h_u {
+-      mmr_t   sh_md_dqls_mmr_ybist_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_ybist_h_s;
+-} sh_md_dqls_mmr_ybist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQLS_MMR_YBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_l_u {
+       mmr_t   sh_md_dqls_mmr_ybist_l_regval;
+       struct {
+@@ -25650,24 +13871,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqls_mmr_ybist_l_s;
+ } sh_md_dqls_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_l_u {
+-      mmr_t   sh_md_dqls_mmr_ybist_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_ybist_l_s;
+-} sh_md_dqls_mmr_ybist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLS_MMR_YBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_err_h_u {
+       mmr_t   sh_md_dqls_mmr_ybist_err_h_regval;
+       struct {
+@@ -25677,24 +13886,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqls_mmr_ybist_err_h_s;
+ } sh_md_dqls_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_err_h_u {
+-      mmr_t   sh_md_dqls_mmr_ybist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_ybist_err_h_s;
+-} sh_md_dqls_mmr_ybist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQLS_MMR_YBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_ybist_err_l_u {
+       mmr_t   sh_md_dqls_mmr_ybist_err_l_regval;
+       struct {
+@@ -25704,24 +13901,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqls_mmr_ybist_err_l_s;
+ } sh_md_dqls_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_ybist_err_l_u {
+-      mmr_t   sh_md_dqls_mmr_ybist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqls_mmr_ybist_err_l_s;
+-} sh_md_dqls_mmr_ybist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQLS_MMR_JNR_DEBUG"                  */
+ /*                    joiner/fct debug configuration                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_jnr_debug_u {
+       mmr_t   sh_md_dqls_mmr_jnr_debug_regval;
+       struct {
+@@ -25730,23 +13915,12 @@
+               mmr_t   reserved_0  : 62;
+       } sh_md_dqls_mmr_jnr_debug_s;
+ } sh_md_dqls_mmr_jnr_debug_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_jnr_debug_u {
+-      mmr_t   sh_md_dqls_mmr_jnr_debug_regval;
+-      struct {
+-              mmr_t   reserved_0  : 62;
+-              mmr_t   rw          : 1;
+-              mmr_t   px          : 1;
+-      } sh_md_dqls_mmr_jnr_debug_s;
+-} sh_md_dqls_mmr_jnr_debug_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQLS_MMR_XAMOPW_ERR"                 */
+ /*                  amo/partial rmw ecc error register                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqls_mmr_xamopw_err_u {
+       mmr_t   sh_md_dqls_mmr_xamopw_err_regval;
+       struct {
+@@ -25762,30 +13936,12 @@
+               mmr_t   reserved_2  : 31;
+       } sh_md_dqls_mmr_xamopw_err_s;
+ } sh_md_dqls_mmr_xamopw_err_u_t;
+-#else
+-typedef union sh_md_dqls_mmr_xamopw_err_u {
+-      mmr_t   sh_md_dqls_mmr_xamopw_err_regval;
+-      struct {
+-              mmr_t   reserved_2  : 31;
+-              mmr_t   arm         : 1;
+-              mmr_t   reserved_1  : 6;
+-              mmr_t   runc        : 1;
+-              mmr_t   rcor        : 1;
+-              mmr_t   rsyn        : 8;
+-              mmr_t   reserved_0  : 6;
+-              mmr_t   sunc        : 1;
+-              mmr_t   scor        : 1;
+-              mmr_t   ssyn        : 8;
+-      } sh_md_dqls_mmr_xamopw_err_s;
+-} sh_md_dqls_mmr_xamopw_err_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQRP_MMR_DIR_CONFIG"                 */
+ /*                     DQ directory config register                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_config_u {
+       mmr_t   sh_md_dqrp_mmr_dir_config_regval;
+       struct {
+@@ -25795,276 +13951,156 @@
+               mmr_t   reserved_0  : 59;
+       } sh_md_dqrp_mmr_dir_config_s;
+ } sh_md_dqrp_mmr_dir_config_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_config_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_config_regval;
+-      struct {
+-              mmr_t   reserved_0  : 59;
+-              mmr_t   en_dirpois  : 1;
+-              mmr_t   en_direcc   : 1;
+-              mmr_t   sys_size    : 3;
+-      } sh_md_dqrp_mmr_dir_config_s;
+-} sh_md_dqrp_mmr_dir_config_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC0"                */
+ /*                      node [63:0] presence bits                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec0_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_presvec0_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_presvec0_s;
+-} sh_md_dqrp_mmr_dir_presvec0_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_presvec0_u {
+       mmr_t   sh_md_dqrp_mmr_dir_presvec0_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_presvec0_s;
+ } sh_md_dqrp_mmr_dir_presvec0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC1"                */
+ /*                     node [127:64] presence bits                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec1_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_presvec1_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_presvec1_s;
+-} sh_md_dqrp_mmr_dir_presvec1_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_presvec1_u {
+       mmr_t   sh_md_dqrp_mmr_dir_presvec1_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_presvec1_s;
+ } sh_md_dqrp_mmr_dir_presvec1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC2"                */
+ /*                     node [191:128] presence bits                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec2_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_presvec2_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_presvec2_s;
+-} sh_md_dqrp_mmr_dir_presvec2_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_presvec2_u {
+       mmr_t   sh_md_dqrp_mmr_dir_presvec2_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_presvec2_s;
+ } sh_md_dqrp_mmr_dir_presvec2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRESVEC3"                */
+-/*                     node [255:192] presence bits                     */
+-/* ==================================================================== */
+-
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_presvec3_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_presvec3_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_presvec3_s;
+-} sh_md_dqrp_mmr_dir_presvec3_u_t;
+-#else
++/*                     node [255:192] presence bits                     */
++/* ==================================================================== */
++
+ typedef union sh_md_dqrp_mmr_dir_presvec3_u {
+       mmr_t   sh_md_dqrp_mmr_dir_presvec3_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_presvec3_s;
+ } sh_md_dqrp_mmr_dir_presvec3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC0"                 */
+ /*                        local vector for acc=0                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec0_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec0_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec0_s;
+-} sh_md_dqrp_mmr_dir_locvec0_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec0_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec0_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec0_s;
+ } sh_md_dqrp_mmr_dir_locvec0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC1"                 */
+ /*                        local vector for acc=1                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec1_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec1_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec1_s;
+-} sh_md_dqrp_mmr_dir_locvec1_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec1_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec1_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec1_s;
+ } sh_md_dqrp_mmr_dir_locvec1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC2"                 */
+ /*                        local vector for acc=2                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec2_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec2_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec2_s;
+-} sh_md_dqrp_mmr_dir_locvec2_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec2_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec2_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec2_s;
+ } sh_md_dqrp_mmr_dir_locvec2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC3"                 */
+ /*                        local vector for acc=3                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec3_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec3_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec3_s;
+-} sh_md_dqrp_mmr_dir_locvec3_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec3_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec3_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec3_s;
+ } sh_md_dqrp_mmr_dir_locvec3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC4"                 */
+ /*                        local vector for acc=4                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec4_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec4_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec4_s;
+-} sh_md_dqrp_mmr_dir_locvec4_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec4_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec4_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec4_s;
+ } sh_md_dqrp_mmr_dir_locvec4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC5"                 */
+ /*                        local vector for acc=5                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec5_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec5_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec5_s;
+-} sh_md_dqrp_mmr_dir_locvec5_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec5_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec5_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec5_s;
+ } sh_md_dqrp_mmr_dir_locvec5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC6"                 */
+ /*                        local vector for acc=6                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec6_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec6_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec6_s;
+-} sh_md_dqrp_mmr_dir_locvec6_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec6_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec6_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec6_s;
+ } sh_md_dqrp_mmr_dir_locvec6_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_LOCVEC7"                 */
+ /*                        local vector for acc=7                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_dir_locvec7_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_locvec7_regval;
+-      struct {
+-              mmr_t   vec         : 64;
+-      } sh_md_dqrp_mmr_dir_locvec7_s;
+-} sh_md_dqrp_mmr_dir_locvec7_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_dir_locvec7_u {
+       mmr_t   sh_md_dqrp_mmr_dir_locvec7_regval;
+       struct {
+               mmr_t   vec         : 64;
+       } sh_md_dqrp_mmr_dir_locvec7_s;
+ } sh_md_dqrp_mmr_dir_locvec7_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC0"                 */
+ /*                      privilege vector for acc=0                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec0_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec0_regval;
+       struct {
+@@ -26073,23 +14109,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec0_s;
+ } sh_md_dqrp_mmr_dir_privec0_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec0_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec0_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec0_s;
+-} sh_md_dqrp_mmr_dir_privec0_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC1"                 */
+ /*                      privilege vector for acc=1                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec1_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec1_regval;
+       struct {
+@@ -26098,23 +14123,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec1_s;
+ } sh_md_dqrp_mmr_dir_privec1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec1_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec1_s;
+-} sh_md_dqrp_mmr_dir_privec1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC2"                 */
+ /*                      privilege vector for acc=2                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec2_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec2_regval;
+       struct {
+@@ -26123,23 +14137,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec2_s;
+ } sh_md_dqrp_mmr_dir_privec2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec2_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec2_s;
+-} sh_md_dqrp_mmr_dir_privec2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC3"                 */
+ /*                      privilege vector for acc=3                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec3_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec3_regval;
+       struct {
+@@ -26148,23 +14151,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec3_s;
+ } sh_md_dqrp_mmr_dir_privec3_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec3_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec3_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec3_s;
+-} sh_md_dqrp_mmr_dir_privec3_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC4"                 */
+ /*                      privilege vector for acc=4                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec4_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec4_regval;
+       struct {
+@@ -26173,23 +14165,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec4_s;
+ } sh_md_dqrp_mmr_dir_privec4_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec4_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec4_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec4_s;
+-} sh_md_dqrp_mmr_dir_privec4_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC5"                 */
+ /*                      privilege vector for acc=5                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec5_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec5_regval;
+       struct {
+@@ -26198,23 +14179,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec5_s;
+ } sh_md_dqrp_mmr_dir_privec5_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec5_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec5_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec5_s;
+-} sh_md_dqrp_mmr_dir_privec5_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC6"                 */
+ /*                      privilege vector for acc=6                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec6_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec6_regval;
+       struct {
+@@ -26223,23 +14193,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec6_s;
+ } sh_md_dqrp_mmr_dir_privec6_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec6_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec6_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec6_s;
+-} sh_md_dqrp_mmr_dir_privec6_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC7"                 */
+ /*                      privilege vector for acc=7                      */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_privec7_u {
+       mmr_t   sh_md_dqrp_mmr_dir_privec7_regval;
+       struct {
+@@ -26248,23 +14207,12 @@
+               mmr_t   reserved_0  : 36;
+       } sh_md_dqrp_mmr_dir_privec7_s;
+ } sh_md_dqrp_mmr_dir_privec7_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_privec7_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_privec7_regval;
+-      struct {
+-              mmr_t   reserved_0  : 36;
+-              mmr_t   out         : 14;
+-              mmr_t   in          : 14;
+-      } sh_md_dqrp_mmr_dir_privec7_s;
+-} sh_md_dqrp_mmr_dir_privec7_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQRP_MMR_DIR_TIMER"                  */
+ /*                            MD SXRO timer                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_timer_u {
+       mmr_t   sh_md_dqrp_mmr_dir_timer_regval;
+       struct {
+@@ -26274,24 +14222,12 @@
+               mmr_t   reserved_0  : 42;
+       } sh_md_dqrp_mmr_dir_timer_s;
+ } sh_md_dqrp_mmr_dir_timer_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_timer_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_timer_regval;
+-      struct {
+-              mmr_t   reserved_0  : 42;
+-              mmr_t   timer_cur   : 9;
+-              mmr_t   timer_en    : 1;
+-              mmr_t   timer_div   : 12;
+-      } sh_md_dqrp_mmr_dir_timer_s;
+-} sh_md_dqrp_mmr_dir_timer_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY"               */
+ /*                       directory pio write data                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_piowd_dir_entry_u {
+       mmr_t   sh_md_dqrp_mmr_piowd_dir_entry_regval;
+       struct {
+@@ -26302,25 +14238,12 @@
+               mmr_t   reserved_0  : 6;
+       } sh_md_dqrp_mmr_piowd_dir_entry_s;
+ } sh_md_dqrp_mmr_piowd_dir_entry_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_piowd_dir_entry_u {
+-      mmr_t   sh_md_dqrp_mmr_piowd_dir_entry_regval;
+-      struct {
+-              mmr_t   reserved_0  : 6;
+-              mmr_t   acc         : 3;
+-              mmr_t   pri         : 3;
+-              mmr_t   dirb        : 26;
+-              mmr_t   dira        : 26;
+-      } sh_md_dqrp_mmr_piowd_dir_entry_s;
+-} sh_md_dqrp_mmr_piowd_dir_entry_u_t;
+-#endif
+ /* ==================================================================== */
+ /*               Register "SH_MD_DQRP_MMR_PIOWD_DIR_ECC"                */
+ /*                        directory ecc register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_piowd_dir_ecc_u {
+       mmr_t   sh_md_dqrp_mmr_piowd_dir_ecc_regval;
+       struct {
+@@ -26329,23 +14252,12 @@
+               mmr_t   reserved_0  : 50;
+       } sh_md_dqrp_mmr_piowd_dir_ecc_s;
+ } sh_md_dqrp_mmr_piowd_dir_ecc_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_piowd_dir_ecc_u {
+-      mmr_t   sh_md_dqrp_mmr_piowd_dir_ecc_regval;
+-      struct {
+-              mmr_t   reserved_0  : 50;
+-              mmr_t   eccb        : 7;
+-              mmr_t   ecca        : 7;
+-      } sh_md_dqrp_mmr_piowd_dir_ecc_s;
+-} sh_md_dqrp_mmr_piowd_dir_ecc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ENTRY"              */
+ /*                      x directory pio read data                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xpiord_xdir_entry_u {
+       mmr_t   sh_md_dqrp_mmr_xpiord_xdir_entry_regval;
+       struct {
+@@ -26358,27 +14270,12 @@
+               mmr_t   reserved_0  : 4;
+       } sh_md_dqrp_mmr_xpiord_xdir_entry_s;
+ } sh_md_dqrp_mmr_xpiord_xdir_entry_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xpiord_xdir_entry_u {
+-      mmr_t   sh_md_dqrp_mmr_xpiord_xdir_entry_regval;
+-      struct {
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   acc         : 3;
+-              mmr_t   pri         : 3;
+-              mmr_t   dirb        : 26;
+-              mmr_t   dira        : 26;
+-      } sh_md_dqrp_mmr_xpiord_xdir_entry_s;
+-} sh_md_dqrp_mmr_xpiord_xdir_entry_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_MD_DQRP_MMR_XPIORD_XDIR_ECC"               */
+ /*                           x directory ecc                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xpiord_xdir_ecc_u {
+       mmr_t   sh_md_dqrp_mmr_xpiord_xdir_ecc_regval;
+       struct {
+@@ -26387,23 +14284,12 @@
+               mmr_t   reserved_0  : 50;
+       } sh_md_dqrp_mmr_xpiord_xdir_ecc_s;
+ } sh_md_dqrp_mmr_xpiord_xdir_ecc_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xpiord_xdir_ecc_u {
+-      mmr_t   sh_md_dqrp_mmr_xpiord_xdir_ecc_regval;
+-      struct {
+-              mmr_t   reserved_0  : 50;
+-              mmr_t   eccb        : 7;
+-              mmr_t   ecca        : 7;
+-      } sh_md_dqrp_mmr_xpiord_xdir_ecc_s;
+-} sh_md_dqrp_mmr_xpiord_xdir_ecc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*             Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ENTRY"              */
+ /*                      y directory pio read data                       */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ypiord_ydir_entry_u {
+       mmr_t   sh_md_dqrp_mmr_ypiord_ydir_entry_regval;
+       struct {
+@@ -26416,27 +14302,12 @@
+               mmr_t   reserved_0  : 4;
+       } sh_md_dqrp_mmr_ypiord_ydir_entry_s;
+ } sh_md_dqrp_mmr_ypiord_ydir_entry_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ypiord_ydir_entry_u {
+-      mmr_t   sh_md_dqrp_mmr_ypiord_ydir_entry_regval;
+-      struct {
+-              mmr_t   reserved_0  : 4;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   acc         : 3;
+-              mmr_t   pri         : 3;
+-              mmr_t   dirb        : 26;
+-              mmr_t   dira        : 26;
+-      } sh_md_dqrp_mmr_ypiord_ydir_entry_s;
+-} sh_md_dqrp_mmr_ypiord_ydir_entry_u_t;
+-#endif
+ /* ==================================================================== */
+ /*              Register "SH_MD_DQRP_MMR_YPIORD_YDIR_ECC"               */
+ /*                           y directory ecc                            */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ypiord_ydir_ecc_u {
+       mmr_t   sh_md_dqrp_mmr_ypiord_ydir_ecc_regval;
+       struct {
+@@ -26445,23 +14316,12 @@
+               mmr_t   reserved_0  : 50;
+       } sh_md_dqrp_mmr_ypiord_ydir_ecc_s;
+ } sh_md_dqrp_mmr_ypiord_ydir_ecc_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ypiord_ydir_ecc_u {
+-      mmr_t   sh_md_dqrp_mmr_ypiord_ydir_ecc_regval;
+-      struct {
+-              mmr_t   reserved_0  : 50;
+-              mmr_t   eccb        : 7;
+-              mmr_t   ecca        : 7;
+-      } sh_md_dqrp_mmr_ypiord_ydir_ecc_s;
+-} sh_md_dqrp_mmr_ypiord_ydir_ecc_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_XCERR1"                   */
+ /*              correctable dir ecc group 1 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xcerr1_u {
+       mmr_t   sh_md_dqrp_mmr_xcerr1_regval;
+       struct {
+@@ -26472,25 +14332,12 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqrp_mmr_xcerr1_s;
+ } sh_md_dqrp_mmr_xcerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xcerr1_u {
+-      mmr_t   sh_md_dqrp_mmr_xcerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqrp_mmr_xcerr1_s;
+-} sh_md_dqrp_mmr_xcerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_XCERR2"                   */
+ /*              correctable dir ecc group 2 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xcerr2_u {
+       mmr_t   sh_md_dqrp_mmr_xcerr2_regval;
+       struct {
+@@ -26500,24 +14347,12 @@
+               mmr_t   reserved_0  : 26;
+       } sh_md_dqrp_mmr_xcerr2_s;
+ } sh_md_dqrp_mmr_xcerr2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xcerr2_u {
+-      mmr_t   sh_md_dqrp_mmr_xcerr2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp2        : 36;
+-      } sh_md_dqrp_mmr_xcerr2_s;
+-} sh_md_dqrp_mmr_xcerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_XUERR1"                   */
+ /*             uncorrectable dir ecc group 1 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xuerr1_u {
+       mmr_t   sh_md_dqrp_mmr_xuerr1_regval;
+       struct {
+@@ -26528,25 +14363,12 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqrp_mmr_xuerr1_s;
+ } sh_md_dqrp_mmr_xuerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xuerr1_u {
+-      mmr_t   sh_md_dqrp_mmr_xuerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqrp_mmr_xuerr1_s;
+-} sh_md_dqrp_mmr_xuerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_XUERR2"                   */
+ /*             uncorrectable dir ecc group 2 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xuerr2_u {
+       mmr_t   sh_md_dqrp_mmr_xuerr2_regval;
+       struct {
+@@ -26556,24 +14378,12 @@
+               mmr_t   reserved_0  : 26;
+       } sh_md_dqrp_mmr_xuerr2_s;
+ } sh_md_dqrp_mmr_xuerr2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xuerr2_u {
+-      mmr_t   sh_md_dqrp_mmr_xuerr2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp2        : 36;
+-      } sh_md_dqrp_mmr_xuerr2_s;
+-} sh_md_dqrp_mmr_xuerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_XPERR"                    */
+ /*                       protocol error register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xperr_u {
+       mmr_t   sh_md_dqrp_mmr_xperr_regval;
+       struct {
+@@ -26591,32 +14401,12 @@
+               mmr_t   reserved_0  : 1;
+       } sh_md_dqrp_mmr_xperr_s;
+ } sh_md_dqrp_mmr_xperr_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xperr_u {
+-      mmr_t   sh_md_dqrp_mmr_xperr_regval;
+-      struct {
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   mybit       : 8;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   priv        : 1;
+-              mmr_t   prige       : 1;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   dir         : 26;
+-      } sh_md_dqrp_mmr_xperr_s;
+-} sh_md_dqrp_mmr_xperr_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_YCERR1"                   */
+ /*              correctable dir ecc group 1 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ycerr1_u {
+       mmr_t   sh_md_dqrp_mmr_ycerr1_regval;
+       struct {
+@@ -26627,52 +14417,27 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqrp_mmr_ycerr1_s;
+ } sh_md_dqrp_mmr_ycerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ycerr1_u {
+-      mmr_t   sh_md_dqrp_mmr_ycerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqrp_mmr_ycerr1_s;
+-} sh_md_dqrp_mmr_ycerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_YCERR2"                   */
+ /*              correctable dir ecc group 2 error register              */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+-typedef union sh_md_dqrp_mmr_ycerr2_u {
+-      mmr_t   sh_md_dqrp_mmr_ycerr2_regval;
+-      struct {
+-              mmr_t   grp2        : 36;
+-              mmr_t   val         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   reserved_0  : 26;
+-      } sh_md_dqrp_mmr_ycerr2_s;
+-} sh_md_dqrp_mmr_ycerr2_u_t;
+-#else
+ typedef union sh_md_dqrp_mmr_ycerr2_u {
+       mmr_t   sh_md_dqrp_mmr_ycerr2_regval;
+       struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+               mmr_t   grp2        : 36;
++              mmr_t   val         : 1;
++              mmr_t   more        : 1;
++              mmr_t   reserved_0  : 26;
+       } sh_md_dqrp_mmr_ycerr2_s;
+ } sh_md_dqrp_mmr_ycerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_YUERR1"                   */
+ /*             uncorrectable dir ecc group 1 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_yuerr1_u {
+       mmr_t   sh_md_dqrp_mmr_yuerr1_regval;
+       struct {
+@@ -26683,25 +14448,12 @@
+               mmr_t   reserved_0  : 25;
+       } sh_md_dqrp_mmr_yuerr1_s;
+ } sh_md_dqrp_mmr_yuerr1_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_yuerr1_u {
+-      mmr_t   sh_md_dqrp_mmr_yuerr1_regval;
+-      struct {
+-              mmr_t   reserved_0  : 25;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp1        : 36;
+-      } sh_md_dqrp_mmr_yuerr1_s;
+-} sh_md_dqrp_mmr_yuerr1_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_YUERR2"                   */
+ /*             uncorrectable dir ecc group 2 error register             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_yuerr2_u {
+       mmr_t   sh_md_dqrp_mmr_yuerr2_regval;
+       struct {
+@@ -26711,24 +14463,12 @@
+               mmr_t   reserved_0  : 26;
+       } sh_md_dqrp_mmr_yuerr2_s;
+ } sh_md_dqrp_mmr_yuerr2_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_yuerr2_u {
+-      mmr_t   sh_md_dqrp_mmr_yuerr2_regval;
+-      struct {
+-              mmr_t   reserved_0  : 26;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   grp2        : 36;
+-      } sh_md_dqrp_mmr_yuerr2_s;
+-} sh_md_dqrp_mmr_yuerr2_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                   Register "SH_MD_DQRP_MMR_YPERR"                    */
+ /*                       protocol error register                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_yperr_u {
+       mmr_t   sh_md_dqrp_mmr_yperr_regval;
+       struct {
+@@ -26746,32 +14486,12 @@
+               mmr_t   reserved_0  : 1;
+       } sh_md_dqrp_mmr_yperr_s;
+ } sh_md_dqrp_mmr_yperr_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_yperr_u {
+-      mmr_t   sh_md_dqrp_mmr_yperr_regval;
+-      struct {
+-              mmr_t   reserved_0  : 1;
+-              mmr_t   arm         : 1;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   mybit       : 8;
+-              mmr_t   unc         : 1;
+-              mmr_t   cor         : 1;
+-              mmr_t   priv        : 1;
+-              mmr_t   prige       : 1;
+-              mmr_t   src         : 14;
+-              mmr_t   cmd         : 8;
+-              mmr_t   dir         : 26;
+-      } sh_md_dqrp_mmr_yperr_s;
+-} sh_md_dqrp_mmr_yperr_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_CMDTRIG"                 */
+ /*                             cmd triggers                             */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_cmdtrig_u {
+       mmr_t   sh_md_dqrp_mmr_dir_cmdtrig_regval;
+       struct {
+@@ -26782,25 +14502,12 @@
+               mmr_t   reserved_0  : 32;
+       } sh_md_dqrp_mmr_dir_cmdtrig_s;
+ } sh_md_dqrp_mmr_dir_cmdtrig_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_cmdtrig_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_cmdtrig_regval;
+-      struct {
+-              mmr_t   reserved_0  : 32;
+-              mmr_t   cmd3        : 8;
+-              mmr_t   cmd2        : 8;
+-              mmr_t   cmd1        : 8;
+-              mmr_t   cmd0        : 8;
+-      } sh_md_dqrp_mmr_dir_cmdtrig_s;
+-} sh_md_dqrp_mmr_dir_cmdtrig_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_TBLTRIG"                 */
+ /*                          dir table trigger                           */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_tbltrig_u {
+       mmr_t   sh_md_dqrp_mmr_dir_tbltrig_regval;
+       struct {
+@@ -26813,27 +14520,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrp_mmr_dir_tbltrig_s;
+ } sh_md_dqrp_mmr_dir_tbltrig_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_tbltrig_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_tbltrig_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   mybit       : 8;
+-              mmr_t   dirst       : 9;
+-              mmr_t   prige       : 1;
+-              mmr_t   acc         : 2;
+-              mmr_t   cmd         : 8;
+-              mmr_t   src         : 14;
+-      } sh_md_dqrp_mmr_dir_tbltrig_s;
+-} sh_md_dqrp_mmr_dir_tbltrig_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_DIR_TBLMASK"                 */
+ /*                        dir table trigger mask                        */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_dir_tblmask_u {
+       mmr_t   sh_md_dqrp_mmr_dir_tblmask_regval;
+       struct {
+@@ -26846,27 +14538,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrp_mmr_dir_tblmask_s;
+ } sh_md_dqrp_mmr_dir_tblmask_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_dir_tblmask_u {
+-      mmr_t   sh_md_dqrp_mmr_dir_tblmask_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   mybit       : 8;
+-              mmr_t   dirst       : 9;
+-              mmr_t   prige       : 1;
+-              mmr_t   acc         : 2;
+-              mmr_t   cmd         : 8;
+-              mmr_t   src         : 14;
+-      } sh_md_dqrp_mmr_dir_tblmask_s;
+-} sh_md_dqrp_mmr_dir_tblmask_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRP_MMR_XBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_h_u {
+       mmr_t   sh_md_dqrp_mmr_xbist_h_regval;
+       struct {
+@@ -26878,26 +14555,12 @@
+               mmr_t   reserved_1  : 21;
+       } sh_md_dqrp_mmr_xbist_h_s;
+ } sh_md_dqrp_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_h_u {
+-      mmr_t   sh_md_dqrp_mmr_xbist_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_xbist_h_s;
+-} sh_md_dqrp_mmr_xbist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRP_MMR_XBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_l_u {
+       mmr_t   sh_md_dqrp_mmr_xbist_l_regval;
+       struct {
+@@ -26908,25 +14571,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqrp_mmr_xbist_l_s;
+ } sh_md_dqrp_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_l_u {
+-      mmr_t   sh_md_dqrp_mmr_xbist_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_xbist_l_s;
+-} sh_md_dqrp_mmr_xbist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_XBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_err_h_u {
+       mmr_t   sh_md_dqrp_mmr_xbist_err_h_regval;
+       struct {
+@@ -26937,25 +14587,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqrp_mmr_xbist_err_h_s;
+ } sh_md_dqrp_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_err_h_u {
+-      mmr_t   sh_md_dqrp_mmr_xbist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_xbist_err_h_s;
+-} sh_md_dqrp_mmr_xbist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_XBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_xbist_err_l_u {
+       mmr_t   sh_md_dqrp_mmr_xbist_err_l_regval;
+       struct {
+@@ -26966,25 +14603,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqrp_mmr_xbist_err_l_s;
+ } sh_md_dqrp_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_xbist_err_l_u {
+-      mmr_t   sh_md_dqrp_mmr_xbist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_xbist_err_l_s;
+-} sh_md_dqrp_mmr_xbist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRP_MMR_YBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_h_u {
+       mmr_t   sh_md_dqrp_mmr_ybist_h_regval;
+       struct {
+@@ -26996,26 +14620,12 @@
+               mmr_t   reserved_1  : 21;
+       } sh_md_dqrp_mmr_ybist_h_s;
+ } sh_md_dqrp_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_h_u {
+-      mmr_t   sh_md_dqrp_mmr_ybist_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_ybist_h_s;
+-} sh_md_dqrp_mmr_ybist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRP_MMR_YBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_l_u {
+       mmr_t   sh_md_dqrp_mmr_ybist_l_regval;
+       struct {
+@@ -27026,25 +14636,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqrp_mmr_ybist_l_s;
+ } sh_md_dqrp_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_l_u {
+-      mmr_t   sh_md_dqrp_mmr_ybist_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_ybist_l_s;
+-} sh_md_dqrp_mmr_ybist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_YBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_err_h_u {
+       mmr_t   sh_md_dqrp_mmr_ybist_err_h_regval;
+       struct {
+@@ -27055,25 +14652,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqrp_mmr_ybist_err_h_s;
+ } sh_md_dqrp_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_err_h_u {
+-      mmr_t   sh_md_dqrp_mmr_ybist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_ybist_err_h_s;
+-} sh_md_dqrp_mmr_ybist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRP_MMR_YBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrp_mmr_ybist_err_l_u {
+       mmr_t   sh_md_dqrp_mmr_ybist_err_l_regval;
+       struct {
+@@ -27084,25 +14668,12 @@
+               mmr_t   reserved_1  : 22;
+       } sh_md_dqrp_mmr_ybist_err_l_s;
+ } sh_md_dqrp_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrp_mmr_ybist_err_l_u {
+-      mmr_t   sh_md_dqrp_mmr_ybist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_1  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   reserved_0  : 8;
+-              mmr_t   pat         : 32;
+-      } sh_md_dqrp_mmr_ybist_err_l_s;
+-} sh_md_dqrp_mmr_ybist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRS_MMR_XBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_h_u {
+       mmr_t   sh_md_dqrs_mmr_xbist_h_regval;
+       struct {
+@@ -27113,25 +14684,12 @@
+               mmr_t   reserved_0  : 21;
+       } sh_md_dqrs_mmr_xbist_h_s;
+ } sh_md_dqrs_mmr_xbist_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_h_u {
+-      mmr_t   sh_md_dqrs_mmr_xbist_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_xbist_h_s;
+-} sh_md_dqrs_mmr_xbist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRS_MMR_XBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_l_u {
+       mmr_t   sh_md_dqrs_mmr_xbist_l_regval;
+       struct {
+@@ -27141,24 +14699,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrs_mmr_xbist_l_s;
+ } sh_md_dqrs_mmr_xbist_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_l_u {
+-      mmr_t   sh_md_dqrs_mmr_xbist_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_xbist_l_s;
+-} sh_md_dqrs_mmr_xbist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRS_MMR_XBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_err_h_u {
+       mmr_t   sh_md_dqrs_mmr_xbist_err_h_regval;
+       struct {
+@@ -27168,24 +14714,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrs_mmr_xbist_err_h_s;
+ } sh_md_dqrs_mmr_xbist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_err_h_u {
+-      mmr_t   sh_md_dqrs_mmr_xbist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_xbist_err_h_s;
+-} sh_md_dqrs_mmr_xbist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRS_MMR_XBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_xbist_err_l_u {
+       mmr_t   sh_md_dqrs_mmr_xbist_err_l_regval;
+       struct {
+@@ -27195,24 +14729,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrs_mmr_xbist_err_l_s;
+ } sh_md_dqrs_mmr_xbist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_xbist_err_l_u {
+-      mmr_t   sh_md_dqrs_mmr_xbist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_xbist_err_l_s;
+-} sh_md_dqrs_mmr_xbist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRS_MMR_YBIST_H"                   */
+ /*                    rising edge bist/fill pattern                     */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_h_u {
+       mmr_t   sh_md_dqrs_mmr_ybist_h_regval;
+       struct {
+@@ -27223,25 +14745,12 @@
+               mmr_t   reserved_0  : 21;
+       } sh_md_dqrs_mmr_ybist_h_s;
+ } sh_md_dqrs_mmr_ybist_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_h_u {
+-      mmr_t   sh_md_dqrs_mmr_ybist_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 21;
+-              mmr_t   arm         : 1;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_ybist_h_s;
+-} sh_md_dqrs_mmr_ybist_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                  Register "SH_MD_DQRS_MMR_YBIST_L"                   */
+ /*                    falling edge bist/fill pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_l_u {
+       mmr_t   sh_md_dqrs_mmr_ybist_l_regval;
+       struct {
+@@ -27251,24 +14760,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrs_mmr_ybist_l_s;
+ } sh_md_dqrs_mmr_ybist_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_l_u {
+-      mmr_t   sh_md_dqrs_mmr_ybist_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   rot         : 1;
+-              mmr_t   inv         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_ybist_l_s;
+-} sh_md_dqrs_mmr_ybist_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRS_MMR_YBIST_ERR_H"                 */
+ /*                    rising edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_err_h_u {
+       mmr_t   sh_md_dqrs_mmr_ybist_err_h_regval;
+       struct {
+@@ -27278,24 +14775,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrs_mmr_ybist_err_h_s;
+ } sh_md_dqrs_mmr_ybist_err_h_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_err_h_u {
+-      mmr_t   sh_md_dqrs_mmr_ybist_err_h_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_ybist_err_h_s;
+-} sh_md_dqrs_mmr_ybist_err_h_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                Register "SH_MD_DQRS_MMR_YBIST_ERR_L"                 */
+ /*                   falling edge bist error pattern                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_ybist_err_l_u {
+       mmr_t   sh_md_dqrs_mmr_ybist_err_l_regval;
+       struct {
+@@ -27305,24 +14790,12 @@
+               mmr_t   reserved_0  : 22;
+       } sh_md_dqrs_mmr_ybist_err_l_s;
+ } sh_md_dqrs_mmr_ybist_err_l_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_ybist_err_l_u {
+-      mmr_t   sh_md_dqrs_mmr_ybist_err_l_regval;
+-      struct {
+-              mmr_t   reserved_0  : 22;
+-              mmr_t   more        : 1;
+-              mmr_t   val         : 1;
+-              mmr_t   pat         : 40;
+-      } sh_md_dqrs_mmr_ybist_err_l_s;
+-} sh_md_dqrs_mmr_ybist_err_l_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQRS_MMR_JNR_DEBUG"                  */
+ /*                    joiner/fct debug configuration                    */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_jnr_debug_u {
+       mmr_t   sh_md_dqrs_mmr_jnr_debug_regval;
+       struct {
+@@ -27331,23 +14804,12 @@
+               mmr_t   reserved_0  : 62;
+       } sh_md_dqrs_mmr_jnr_debug_s;
+ } sh_md_dqrs_mmr_jnr_debug_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_jnr_debug_u {
+-      mmr_t   sh_md_dqrs_mmr_jnr_debug_regval;
+-      struct {
+-              mmr_t   reserved_0  : 62;
+-              mmr_t   rw          : 1;
+-              mmr_t   px          : 1;
+-      } sh_md_dqrs_mmr_jnr_debug_s;
+-} sh_md_dqrs_mmr_jnr_debug_u_t;
+-#endif
+ /* ==================================================================== */
+ /*                 Register "SH_MD_DQRS_MMR_YAMOPW_ERR"                 */
+ /*                  amo/partial rmw ecc error register                  */
+ /* ==================================================================== */
+-#ifdef LITTLE_ENDIAN
+ typedef union sh_md_dqrs_mmr_yamopw_err_u {
+       mmr_t   sh_md_dqrs_mmr_yamopw_err_regval;
+       struct {
+@@ -27363,23 +14825,5 @@
+               mmr_t   reserved_2  : 31;
+       } sh_md_dqrs_mmr_yamopw_err_s;
+ } sh_md_dqrs_mmr_yamopw_err_u_t;
+-#else
+-typedef union sh_md_dqrs_mmr_yamopw_err_u {
+-      mmr_t   sh_md_dqrs_mmr_yamopw_err_regval;
+-      struct {
+-              mmr_t   reserved_2  : 31;
+-              mmr_t   arm         : 1;
+-              mmr_t   reserved_1  : 6;
+-              mmr_t   runc        : 1;
+-              mmr_t   rcor        : 1;
+-              mmr_t   rsyn        : 8;
+-              mmr_t   reserved_0  : 6;
+-              mmr_t   sunc        : 1;
+-              mmr_t   scor        : 1;
+-              mmr_t   ssyn        : 8;
+-      } sh_md_dqrs_mmr_yamopw_err_s;
+-} sh_md_dqrs_mmr_yamopw_err_u_t;
+-#endif
+-
+ #endif /* _ASM_IA64_SN_SN2_SHUB_MMR_T_H */
+Index: linux-2.6.0-test5/include/asm-ia64/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/spinlock.h      2003-09-27 11:38:40.582358928 +0800
+@@ -24,6 +24,7 @@
+ #define SPIN_LOCK_UNLOCKED                    (spinlock_t) { 0 }
+ #define spin_lock_init(x)                     ((x)->lock = 0)
++#ifdef ASM_SUPPORTED
+ /*
+  * Try to get the lock.  If we fail to get the lock, make a non-standard call to
+  * ia64_spinlock_contention().  We do not use a normal call because that would force all
+@@ -85,6 +86,21 @@
+ # endif /* CONFIG_MCKINLEY */
+ #endif
+ }
++#else /* !ASM_SUPPORTED */
++# define _raw_spin_lock(x)                                                            \
++do {                                                                                  \
++      __u32 *ia64_spinlock_ptr = (__u32 *) (x);                                       \
++      __u64 ia64_spinlock_val;                                                        \
++      ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0);                 \
++      if (unlikely(ia64_spinlock_val)) {                                              \
++              do {                                                                    \
++                      while (*ia64_spinlock_ptr)                                      \
++                              ia64_barrier();                                         \
++                      ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0); \
++              } while (ia64_spinlock_val);                                            \
++      }                                                                               \
++} while (0)
++#endif /* !ASM_SUPPORTED */
+ #define spin_is_locked(x)     ((x)->lock != 0)
+ #define _raw_spin_unlock(x)   do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0)
+@@ -94,8 +110,18 @@
+ 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)
+@@ -111,28 +137,67 @@
+       }                                                                               \
+ } 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);                       \
+       ia64_fetchadd(-1, (int *) __read_lock_ptr, rel);        \
+ } while (0)
++#ifdef ASM_SUPPORTED
+ #define _raw_write_lock(rw)                                                   \
+ do {                                                                          \
+       __asm__ __volatile__ (                                                  \
+               "mov ar.ccv = r0\n"                                             \
+-              "dep r29 = -1, r0, 31, 1\n"                                     \
+-              ";;\n"                                                          \
++              "dep r29 = -1, r0, 31, 1;;\n"                                   \
+               "1:\n"                                                          \
+-              "ld4 r2 = [%0]\n"                                               \
+-              ";;\n"                                                          \
++              "ld4 r2 = [%0];;\n"                                             \
+               "cmp4.eq p0,p7 = r0,r2\n"                                       \
+               "(p7) br.cond.spnt.few 1b \n"                                   \
+-              "cmpxchg4.acq r2 = [%0], r29, ar.ccv\n"                         \
+-              ";;\n"                                                          \
++              "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n"                       \
+               "cmp4.eq p0,p7 = r0, r2\n"                                      \
+-              "(p7) br.cond.spnt.few 1b\n"                                    \
+-              ";;\n"                                                          \
++              "(p7) br.cond.spnt.few 1b;;\n"                                  \
+               :: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory");            \
+ } while(0)
+@@ -142,17 +207,60 @@
+                                                                               \
+       __asm__ __volatile__ (                                                  \
+               "mov ar.ccv = r0\n"                                             \
+-              "dep r29 = -1, r0, 31, 1\n"                                     \
+-              ";;\n"                                                          \
++              "dep r29 = -1, r0, 31, 1;;\n"                                   \
+               "cmpxchg4.acq %0 = [%1], r29, ar.ccv\n"                         \
+               : "=r"(result) : "r"(rw) : "ar.ccv", "r29", "memory");          \
+       (result == 0);                                                          \
+ })
++#else /* !ASM_SUPPORTED */
++
++#define _raw_write_lock(l)                                                            \
++({                                                                                    \
++      __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1);                       \
++      __u32 *ia64_write_lock_ptr = (__u32 *) (l);                                     \
++      do {                                                                            \
++              while (*ia64_write_lock_ptr)                                            \
++                      ia64_barrier();                                                 \
++              ia64_val = ia64_cmpxchg4_acq(ia64_write_lock_ptr, ia64_set_val, 0);     \
++      } while (ia64_val);                                                             \
++})
++
++#define _raw_write_trylock(rw)                                                \
++({                                                                    \
++      __u64 ia64_val;                                                 \
++      __u64 ia64_set_val = ia64_dep_mi(-1, 0, 31,1);                  \
++      ia64_val = ia64_cmpxchg4_acq((__u32 *)(rw), ia64_set_val, 0);   \
++      (ia64_val == 0);                                                \
++})
++
++#endif /* !ASM_SUPPORTED */
++
+ #define _raw_write_unlock(x)                                                          \
+ ({                                                                                    \
+       smp_mb__before_clear_bit();     /* need barrier before releasing lock... */     \
+       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 */
+Index: linux-2.6.0-test5/include/asm-ia64/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/uaccess.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/uaccess.h       2003-09-27 11:38:40.586358320 +0800
+@@ -33,6 +33,7 @@
+ #include <linux/errno.h>
+ #include <linux/sched.h>
++#include <asm/intrinsics.h>
+ #include <asm/pgtable.h>
+ /*
+@@ -86,6 +87,8 @@
+ #define __put_user(x,ptr)     __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+ #define __get_user(x,ptr)     __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
++#ifdef ASM_SUPPORTED
++
+ extern void __get_user_unknown (void);
+ #define __get_user_nocheck(x,ptr,size)                \
+@@ -217,6 +220,90 @@
+               "[1:]"                                                                  \
+               : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
++#else /* !ASM_SUPPORTED */
++
++#define RELOC_TYPE    2       /* ip-rel */
++
++#define __put_user_xx(val, addr, size, err)                                                   \
++      __st_user("__ex_table", (unsigned long) addr, size, RELOC_TYPE, (unsigned long) (val)); \
++      (err) = ia64_getreg(_IA64_REG_R8);
++
++#define __get_user_xx(val, addr, size, err)                                   \
++      __ld_user("__ex_table", (unsigned long) addr, size, RELOC_TYPE);        \
++      (err) = ia64_getreg(_IA64_REG_R8);                                      \
++      (val) = ia64_getreg(_IA64_REG_R9);
++
++extern void __get_user_unknown (void);
++
++#define __get_user_nocheck(x, ptr, size)                              \
++({                                                                    \
++      register long __gu_err = 0;                                     \
++      register long __gu_val = 0;                                     \
++      const __typeof__(*(ptr)) *__gu_addr = (ptr);                    \
++      switch (size) {                                                 \
++            case 1: case 2: case 4: case 8:                           \
++              __get_user_xx(__gu_val, __gu_addr, size, __gu_err);     \
++              break;                                                  \
++            default:                                                  \
++              __get_user_unknown();                                   \
++              break;                                                  \
++        }                                                             \
++        (x) = (__typeof__(*(ptr))) __gu_val;                          \
++        __gu_err;                                                     \
++})
++
++#define __get_user_check(x,ptr,size,segment)                                  \
++({                                                                            \
++      register long __gu_err = -EFAULT;                                       \
++      register long __gu_val  = 0;                                            \
++      const __typeof__(*(ptr)) *__gu_addr = (ptr);                            \
++      if (__access_ok((long) __gu_addr, size, segment)) {                     \
++              switch (size) {                                                 \
++                    case 1: case 2: case 4: case 8:                           \
++                      __get_user_xx(__gu_val, __gu_addr, size, __gu_err);     \
++                      break;                                                  \
++                    default:                                                  \
++                      __get_user_unknown(); break;                            \
++              }                                                               \
++      }                                                                       \
++      (x) = (__typeof__(*(ptr))) __gu_val;                                    \
++      __gu_err;                                                               \
++})
++
++extern void __put_user_unknown (void);
++
++#define __put_user_nocheck(x, ptr, size)                      \
++({                                                            \
++      int __pu_err = 0;                                       \
++      __typeof__(*(ptr)) *__pu_addr = (ptr);                  \
++      switch (size) {                                         \
++            case 1: case 2: case 4: case 8:                   \
++              __put_user_xx(x, __pu_addr, size, __pu_err);    \
++              break;                                          \
++            default:                                          \
++              __put_user_unknown(); break;                    \
++      }                                                       \
++      __pu_err;                                               \
++})
++
++#define __put_user_check(x,ptr,size,segment)                          \
++({                                                                    \
++      register long __pu_err = -EFAULT;                               \
++      __typeof__(*(ptr)) *__pu_addr = (ptr);                          \
++      if (__access_ok((long)__pu_addr,size,segment)) {                \
++              switch (size) {                                         \
++                    case 1: case 2: case 4: case 8:                   \
++                      __put_user_xx(x,__pu_addr, size, __pu_err);     \
++                      break;                                          \
++                    default:                                          \
++                      __put_user_unknown(); break;                    \
++              }                                                       \
++      }                                                               \
++      __pu_err;                                                       \
++})
++
++#endif /* !ASM_SUPPORTED */
++
+ /*
+  * Complex access routines
+  */
+Index: linux-2.6.0-test5/include/asm-ia64/unistd.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ia64/unistd.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ia64/unistd.h        2003-09-27 11:38:40.589357864 +0800
+@@ -248,7 +248,6 @@
+ #define __NR_sys_clock_nanosleep      1256
+ #define __NR_sys_fstatfs64            1257
+ #define __NR_sys_statfs64             1258
+-#define __NR_fadvises64_64            1259
+ #ifdef __KERNEL__
+Index: linux-2.6.0-test5/include/asm-m68k/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/cacheflush.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/cacheflush.h    2003-09-27 11:38:40.591357560 +0800
+@@ -80,6 +80,9 @@
+ #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 @@
+ #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);
+Index: linux-2.6.0-test5/include/asm-m68knommu/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68knommu/cacheflush.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68knommu/cacheflush.h       2003-09-27 11:38:40.592357408 +0800
+@@ -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)
+ {
+Index: linux-2.6.0-test5/include/asm-m68knommu/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68knommu/processor.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68knommu/processor.h        2003-09-27 11:38:40.594357104 +0800
+@@ -58,7 +58,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ /* 
+Index: linux-2.6.0-test5/include/asm-m68knommu/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68knommu/signal.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68knommu/signal.h   2003-09-27 11:38:40.596356800 +0800
+@@ -68,7 +68,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-m68k/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/pgtable.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/pgtable.h       2003-09-27 11:38:40.598356496 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-m68k/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/posix_types.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/posix_types.h   2003-09-27 11:38:40.600356192 +0800
+@@ -7,7 +7,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned short        __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short        __kernel_mode_t;
+ typedef unsigned short        __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-m68k/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/processor.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/processor.h     2003-09-27 11:38:40.601356040 +0800
+@@ -56,7 +56,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ struct task_work {
+Index: linux-2.6.0-test5/include/asm-m68k/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-m68k/signal.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-m68k/signal.h        2003-09-27 11:38:40.604355584 +0800
+@@ -68,7 +68,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-mips64/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips64/lockmeter.h      2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-mips64/lockmeter.h   2003-09-27 11:38:40.604355584 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-mips/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/cacheflush.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/cacheflush.h    2003-09-27 11:38:40.606355280 +0800
+@@ -43,7 +43,15 @@
+ 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);
+Index: linux-2.6.0-test5/include/asm-mips/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/highmem.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/highmem.h       2003-09-27 11:38:40.608354976 +0800
+@@ -54,6 +54,8 @@
+ 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 */
+Index: linux-2.6.0-test5/include/asm-mips/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/lockmeter.h        2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-mips/lockmeter.h     2003-09-27 11:38:40.608354976 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-mips/pgtable-32.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/pgtable-32.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/pgtable-32.h    2003-09-27 11:38:40.624352544 +0800
+@@ -79,7 +79,6 @@
+ #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)
+Index: linux-2.6.0-test5/include/asm-mips/pgtable-64.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/pgtable-64.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/pgtable-64.h    2003-09-27 11:38:40.626352240 +0800
+@@ -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))
+Index: linux-2.6.0-test5/include/asm-mips/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/posix_types.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/posix_types.h   2003-09-27 11:38:40.628351936 +0800
+@@ -17,7 +17,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned int  __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned int  __kernel_mode_t;
+ #if (_MIPS_SZLONG == 32)
+Index: linux-2.6.0-test5/include/asm-mips/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/processor.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/processor.h     2003-09-27 11:38:40.631351480 +0800
+@@ -135,12 +135,6 @@
+ /*
+  * Bus types (default is ISA, but people can check others with these..)
+  */
+-#ifdef CONFIG_EISA
+-extern int EISA_bus;
+-#else
+-#define EISA_bus (0)
+-#endif
+-
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-mips/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/signal.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/signal.h        2003-09-27 11:38:40.634351024 +0800
+@@ -59,7 +59,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-mips/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/spinlock.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/spinlock.h      2003-09-27 11:38:40.635350872 +0800
+@@ -91,9 +91,18 @@
+ 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)
+Index: linux-2.6.0-test5/include/asm-mips/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-mips/stat.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-mips/stat.h  2003-09-27 11:38:40.636350720 +0800
+@@ -16,14 +16,14 @@
+ #if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
+ struct stat {
+-      dev_t           st_dev;
++      unsigned        st_dev;
+       long            st_pad1[3];             /* Reserved for network id */
+       ino_t           st_ino;
+       mode_t          st_mode;
+       nlink_t         st_nlink;
+       uid_t           st_uid;
+       gid_t           st_gid;
+-      dev_t           st_rdev;
++      unsigned        st_rdev;
+       long            st_pad2[2];
+       off_t           st_size;
+       long            st_pad3;
+@@ -90,7 +90,7 @@
+ /* The memory layout is the same as of struct stat64 of the 32-bit kernel.  */
+ struct stat {
+-      dev_t                   st_dev;
++      unsigned int            st_dev;
+       unsigned int            st_pad0[3]; /* Reserved for st_dev expansion */
+       unsigned long           st_ino;
+@@ -101,7 +101,7 @@
+       uid_t                   st_uid;
+       gid_t                   st_gid;
+-      dev_t                   st_rdev;
++      unsigned int            st_rdev;
+       unsigned int            st_pad1[3]; /* Reserved for st_rdev expansion */
+       off_t                   st_size;
+Index: linux-2.6.0-test5/include/asm-parisc/atomic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/atomic.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/atomic.h      2003-09-27 11:38:40.639350264 +0800
+@@ -49,27 +49,14 @@
+  * Cache-line alignment would conflict with, for example, linux/module.h
+  */
+-typedef struct {
+-      volatile int counter;
+-} atomic_t;
++typedef struct { volatile long counter; } atomic_t;
+-/*
+-** xchg/cmpxchg moved from asm/system.h - ggg
+-*/
+-
+-#if 1
+ /* This should get optimized out since it's never called.
+ ** Or get a link error if xchg is used "wrong".
+ */
+ extern void __xchg_called_with_bad_pointer(void);
+-#else
+-static inline void __xchg_called_with_bad_pointer(void)
+-{
+-      extern void panic(const char * fmt, ...);
+-      panic("xchg called with bad pointer");
+-}
+-#endif
++
+ /* __xchg32/64 defined in arch/parisc/lib/bitops.c */
+ extern unsigned long __xchg8(char, char *);
+Index: linux-2.6.0-test5/include/asm-parisc/bitops.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/bitops.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/bitops.h      2003-09-27 11:38:40.642349808 +0800
+@@ -203,55 +203,102 @@
+       return !!(*addr & mask);
+ }
+-extern __inline__ unsigned long ffz(unsigned long word)
+-{
+-      unsigned long result;
+-
+-      result = 0;
+-      while (word & 1) {
+-              result++;
+-              word >>= 1;
+-      }
+-
+-      return result;
+-}
+-
+ #ifdef __KERNEL__
+ /**
+- * __ffs - find first bit in word.
++ * __ffs - find first bit in word. returns 0 to "BITS_PER_LONG-1".
+  * @word: The word to search
+  *
+- * Undefined if no bit exists, so code should check against 0 first.
++ * __ffs() return is undefined if no bit is set.
++ *
++ * 32-bit fast __ffs by LaMont Jones "lamont At hp com".
++ * 64-bit enhancement by Grant Grundler "grundler At parisc-linux org".
++ * (with help from willy/jejb to get the semantics right)
++ *
++ * This algorithm avoids branches by making use of nullification.
++ * One side effect of "extr" instructions is it sets PSW[N] bit.
++ * How PSW[N] (nullify next insn) gets set is determined by the 
++ * "condition" field (eg "<>" or "TR" below) in the extr* insn.
++ * Only the 1st and one of either the 2cd or 3rd insn will get executed.
++ * Each set of 3 insn will get executed in 2 cycles on PA8x00 vs 16 or so
++ * cycles for each mispredicted branch.
+  */
+-static __inline__ unsigned long __ffs(unsigned long word)
++
++static __inline__ unsigned long __ffs(unsigned long x)
+ {
+-      unsigned long result = 0;
++      unsigned long ret;
+-      while (!(word & 1UL)) {
+-              result++;
+-              word >>= 1;
+-      }
+-      return result;
++      __asm__(
++#if BITS_PER_LONG > 32
++              " ldi       63,%1\n"
++              " extrd,u,*<>  %0,63,32,%%r0\n"
++              " extrd,u,*TR  %0,31,32,%0\n"
++              " addi    -32,%1,%1\n"
++#else
++              " ldi       31,%1\n"
++#endif
++              " extru,<>  %0,31,16,%%r0\n"
++              " extru,TR  %0,15,16,%0\n"
++              " addi    -16,%1,%1\n"
++              " extru,<>  %0,31,8,%%r0\n"
++              " extru,TR  %0,23,8,%0\n"
++              " addi    -8,%1,%1\n"
++              " extru,<>  %0,31,4,%%r0\n"
++              " extru,TR  %0,27,4,%0\n"
++              " addi    -4,%1,%1\n"
++              " extru,<>  %0,31,2,%%r0\n"
++              " extru,TR  %0,29,2,%0\n"
++              " addi    -2,%1,%1\n"
++              " extru,=  %0,31,1,%%r0\n"
++              " addi    -1,%1,%1\n"
++                      : "+r" (x), "=r" (ret) );
++      return ret;
+ }
++/* Undefined if no bit is zero. */
++#define ffz(x)        __ffs(~x)
++
+ /*
+- * ffs: find first bit set. This is defined the same way as
+- * the libc and compiler builtin ffs routines, therefore
+- * differs in spirit from the above ffz (man ffs).
++ * ffs: find first bit set. returns 1 to BITS_PER_LONG or 0 (if none set)
++ * This is defined the same way as the libc and compiler builtin
++ * ffs routines, therefore differs in spirit from the above ffz (man ffs).
+  */
+ static __inline__ int ffs(int x)
+ {
+-      if (!x)
+-              return 0;
+-      return __ffs((unsigned long)x);
++      return x ? (__ffs((unsigned long)x) + 1) : 0;
+ }
+ /*
+- * fls: find last bit set.
++ * fls: find last (most significant) bit set.
++ * fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+  */
+-#define fls(x) generic_fls(x)
++static __inline__ int fls(int x)
++{
++      int ret;
++      if (!x)
++              return 0;
++
++      __asm__(
++      "       ldi             1,%1\n"
++      "       extru,<>        %0,15,16,%%r0\n"
++      "       zdep,TR         %0,15,16,%0\n"          /* xxxx0000 */
++      "       addi            16,%1,%1\n"
++      "       extru,<>        %0,7,8,%%r0\n"
++      "       zdep,TR         %0,23,24,%0\n"          /* xx000000 */
++      "       addi            8,%1,%1\n"
++      "       extru,<>        %0,3,4,%%r0\n"
++      "       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 */
++      "       addi            2,%1,%1\n"
++      "       extru,=         %0,0,1,%%r0\n"
++      "       addi            1,%1,%1\n"              /* if y & 8, add 1 */
++              : "+r" (x), "=r" (ret) );
++
++      return ret;
++}
+ /*
+  * hweightN: returns the hamming weight (i.e. the number
+Index: linux-2.6.0-test5/include/asm-parisc/byteorder.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/byteorder.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/byteorder.h   2003-09-27 11:38:40.644349504 +0800
+@@ -5,6 +5,25 @@
+ #ifdef __GNUC__
++static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
++{
++      __asm__("dep %0, 15, 8, %0\n\t"         /* deposit 00ab -> 0bab */
++              "shd %%r0, %0, 8, %0"           /* shift 000000ab -> 00ba */
++              : "=r" (x)
++              : "0" (x));
++      return x;
++}
++
++static __inline__ __const__ __u32 ___arch__swab24(__u32 x)
++{
++      __asm__("shd %0, %0, 8, %0\n\t"         /* shift xabcxabc -> cxab */
++              "dep %0, 15, 8, %0\n\t"         /* deposit cxab -> cbab */
++              "shd %%r0, %0, 8, %0"           /* shift 0000cbab -> 0cba */
++              : "=r" (x)
++              : "0" (x));
++      return x;
++}
++
+ static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+ {
+       unsigned int temp;
+@@ -39,34 +58,21 @@
+       return x;
+ }
+ #define __arch__swab64(x) ___arch__swab64(x)
+-#else
++#define __BYTEORDER_HAS_U64__
++#elif !defined(__STRICT_ANSI__)
+ static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
+ {
+-      __u32 t1 = (__u32) x;
+-      __u32 t2 = (__u32) ((x) >> 32);
+-      ___arch__swab32(t1);
+-      ___arch__swab32(t2);
+-      return (((__u64) t1 << 32) + ((__u64) t2));
++      __u32 t1 = ___arch__swab32((__u32) x);
++      __u32 t2 = ___arch__swab32((__u32) (x >> 32));
++      return (((__u64) t1 << 32) | t2);
+ }
++#define __arch__swab64(x) ___arch__swab64(x)
++#define __BYTEORDER_HAS_U64__
+ #endif
+-
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+-{
+-      __asm__("dep %0, 15, 8, %0\n\t"         /* deposit 00ab -> 0bab */
+-              "shd %r0, %0, 8, %0"            /* shift 000000ab -> 00ba */
+-              : "=r" (x)
+-              : "0" (x));
+-      return x;
+-}
+-
+-#define __arch__swab32(x) ___arch__swab32(x)
+ #define __arch__swab16(x) ___arch__swab16(x)
+-
+-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+-#  define __BYTEORDER_HAS_U64__
+-#  define __SWAB_64_THRU_32__
+-#endif
++#define __arch__swab24(x) ___arch__swab24(x)
++#define __arch__swab32(x) ___arch__swab32(x)
+ #endif /* __GNUC__ */
+Index: linux-2.6.0-test5/include/asm-parisc/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/cacheflush.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/cacheflush.h  2003-09-27 11:38:40.646349200 +0800
+@@ -30,6 +30,9 @@
+       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.
+  */
+@@ -78,8 +81,16 @@
+ #define flush_icache_range(s,e)               do { flush_kernel_dcache_range_asm(s,e); flush_kernel_icache_range_asm(s,e); } while (0)
+-#define flush_icache_user_range(vma, page, addr, len) \
+-      flush_icache_page((vma), (page))
++#define flush_icache_user_range(vma, page, addr, len) do { \
++        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)
+Index: linux-2.6.0-test5/include/asm-parisc/elf.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/elf.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/elf.h 2003-09-27 11:38:40.650348592 +0800
+@@ -283,6 +283,7 @@
+  */
+ #define ELF_DATA      ELFDATA2MSB
+ #define ELF_ARCH      EM_PARISC
++#define ELF_OSABI     ELFOSABI_LINUX
+ /* %r23 is set by ld.so to a pointer to a function which might be 
+    registered using atexit.  This provides a mean for the dynamic
+Index: linux-2.6.0-test5/include/asm-parisc/io.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/io.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/io.h  2003-09-27 11:38:40.653348136 +0800
+@@ -291,4 +291,11 @@
+ #define dma_cache_wback(_start,_size)         do { flush_kernel_dcache_range(_start,_size); } while (0)
+ #define dma_cache_wback_inv(_start,_size)     do { flush_kernel_dcache_range(_start,_size); } while (0)
++/* PA machines have an MM I/O space from 0xf0000000-0xffffffff in 32
++ * bit mode and from 0xfffffffff0000000-0xfffffffffffffff in 64 bit
++ * mode (essentially just sign extending.  This macro takes in a 32
++ * bit I/O address (still with the leading f) and outputs the correct
++ * value for either 32 or 64 bit mode */
++#define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL)))
++
+ #endif
+Index: linux-2.6.0-test5/include/asm-parisc/local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/local.h  2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-parisc/local.h       2003-09-27 11:38:40.654347984 +0800
+@@ -0,0 +1,40 @@
++#ifndef _ARCH_PARISC_LOCAL_H
++#define _ARCH_PARISC_LOCAL_H
++
++#include <linux/percpu.h>
++#include <asm/atomic.h>
++
++typedef atomic_t local_t;
++
++#define LOCAL_INIT(i) ATOMIC_INIT(i)
++#define local_read(v) atomic_read(v)
++#define local_set(v,i)        atomic_set(v,i)
++
++#define local_inc(v)  atomic_inc(v)
++#define local_dec(v)  atomic_dec(v)
++#define local_add(i, v)       atomic_add(i, v)
++#define local_sub(i, v)       atomic_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_PARISC_LOCAL_H */
+Index: linux-2.6.0-test5/include/asm-parisc/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/pgtable.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/pgtable.h     2003-09-27 11:38:40.658347376 +0800
+@@ -108,7 +108,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
+Index: linux-2.6.0-test5/include/asm-parisc/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/posix_types.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/posix_types.h 2003-09-27 11:38:40.660347072 +0800
+@@ -6,7 +6,6 @@
+  * be a little careful about namespace pollution etc.  Also, we cannot
+  * assume GCC is being used.
+  */
+-typedef unsigned int          __kernel_dev_t;
+ typedef unsigned long         __kernel_ino_t;
+ typedef unsigned short                __kernel_mode_t;
+ typedef unsigned short                __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-parisc/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/processor.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/processor.h   2003-09-27 11:38:40.663346616 +0800
+@@ -101,12 +101,6 @@
+ #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
+-#ifdef CONFIG_EISA
+-extern int EISA_bus;
+-#else
+-#define EISA_bus 0
+-#endif
+-
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-parisc/sections.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/sections.h       2003-09-27 11:38:18.480718888 +0800
++++ linux-2.6.0-test5/include/asm-parisc/sections.h    2003-09-27 11:38:40.663346616 +0800
+@@ -0,0 +1,7 @@
++#ifndef _PARISC_SECTIONS_H
++#define _PARISC_SECTIONS_H
++
++/* nothing to see, move along */
++#include <asm-generic/sections.h>
++
++#endif
+Index: linux-2.6.0-test5/include/asm-parisc/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/signal.h      2003-09-27 11:38:40.666346160 +0800
+@@ -42,7 +42,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      37
+-#define SIGRTMAX      (_NSIG-1) /* it's 44 under HP/UX */
++#define SIGRTMAX      _NSIG /* it's 44 under HP/UX */
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-parisc/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/stat.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/stat.h        2003-09-27 11:38:40.667346008 +0800
+@@ -4,13 +4,13 @@
+ #include <linux/types.h>
+ struct stat {
+-      dev_t           st_dev;         /* dev_t is 32 bits on parisc */
++      unsigned int    st_dev;         /* dev_t is 32 bits on parisc */
+       ino_t           st_ino;         /* 32 bits */
+       mode_t          st_mode;        /* 16 bits */
+       nlink_t         st_nlink;       /* 16 bits */
+       unsigned short  st_reserved1;   /* old st_uid */
+       unsigned short  st_reserved2;   /* old st_gid */
+-      dev_t           st_rdev;
++      unsigned int    st_rdev;
+       off_t           st_size;
+       time_t          st_atime;
+       unsigned int    st_atime_nsec;
+@@ -21,12 +21,12 @@
+       int             st_blksize;
+       int             st_blocks;
+       unsigned int    __unused1;      /* ACL stuff */
+-      dev_t           __unused2;      /* network */
++      unsigned int    __unused2;      /* network */
+       ino_t           __unused3;      /* network */
+       unsigned int    __unused4;      /* cnodes */
+       unsigned short  __unused5;      /* netsite */
+       short           st_fstype;
+-      dev_t           st_realdev;
++      unsigned int    st_realdev;
+       unsigned short  st_basemode;
+       unsigned short  st_spareshort;
+       uid_t           st_uid;
+@@ -39,13 +39,13 @@
+ typedef __kernel_off64_t      off64_t;
+ struct hpux_stat64 {
+-      dev_t           st_dev;         /* dev_t is 32 bits on parisc */
++      unsigned int    st_dev;         /* dev_t is 32 bits on parisc */
+       ino_t           st_ino;         /* 32 bits */
+       mode_t          st_mode;        /* 16 bits */
+       nlink_t         st_nlink;       /* 16 bits */
+       unsigned short  st_reserved1;   /* old st_uid */
+       unsigned short  st_reserved2;   /* old st_gid */
+-      dev_t           st_rdev;
++      unsigned int    st_rdev;
+       off64_t         st_size;
+       time_t          st_atime;
+       unsigned int    st_spare1;
+@@ -56,12 +56,12 @@
+       int             st_blksize;
+       __u64           st_blocks;
+       unsigned int    __unused1;      /* ACL stuff */
+-      dev_t           __unused2;      /* network */
++      unsigned int    __unused2;      /* network */
+       ino_t           __unused3;      /* network */
+       unsigned int    __unused4;      /* cnodes */
+       unsigned short  __unused5;      /* netsite */
+       short           st_fstype;
+-      dev_t           st_realdev;
++      unsigned int    st_realdev;
+       unsigned short  st_basemode;
+       unsigned short  st_spareshort;
+       uid_t           st_uid;
+Index: linux-2.6.0-test5/include/asm-parisc/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-parisc/uaccess.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-parisc/uaccess.h     2003-09-27 11:38:40.671345400 +0800
+@@ -28,6 +28,11 @@
+  * that put_user is the same as __put_user, etc.
+  */
++extern int __get_kernel_bad(void);
++extern int __get_user_bad(void);
++extern int __put_kernel_bad(void);
++extern int __put_user_bad(void);
++
+ #define access_ok(type,addr,size)   (1)
+ #define verify_area(type,addr,size) (0)
+@@ -35,8 +40,8 @@
+ #define get_user __get_user
+ #if BITS_PER_LONG == 32
+-#define LDD_KERNEL(ptr)               BUG()
+-#define LDD_USER(ptr)         BUG()
++#define LDD_KERNEL(ptr) __get_kernel_bad();
++#define LDD_USER(ptr) __get_user_bad();
+ #define STD_KERNEL(x, ptr) __put_kernel_asm64((u32)x,ptr)
+ #define STD_USER(x, ptr) __put_user_asm64((u32)x,ptr)
+ #else
+@@ -72,7 +77,7 @@
+           case 2: __get_kernel_asm("ldh",ptr); break; \
+           case 4: __get_kernel_asm("ldw",ptr); break; \
+           case 8: LDD_KERNEL(ptr); break;             \
+-          default: BUG(); break;                      \
++          default: __get_kernel_bad(); break;         \
+           }                                           \
+       }                                               \
+       else {                                          \
+@@ -81,7 +86,7 @@
+           case 2: __get_user_asm("ldh",ptr); break;   \
+           case 4: __get_user_asm("ldw",ptr); break;   \
+           case 8: LDD_USER(ptr);  break;              \
+-          default: BUG(); break;                      \
++          default: __get_user_bad(); break;           \
+           }                                           \
+       }                                               \
+                                                       \
+@@ -141,7 +146,7 @@
+           case 2: __put_kernel_asm("sth",x,ptr); break;       \
+           case 4: __put_kernel_asm("stw",x,ptr); break;       \
+           case 8: STD_KERNEL(x,ptr); break;                   \
+-          default: BUG(); break;                              \
++          default: __put_kernel_bad(); break;                 \
+           }                                                   \
+       }                                                       \
+       else {                                                  \
+@@ -150,7 +155,7 @@
+           case 2: __put_user_asm("sth",x,ptr); break;         \
+           case 4: __put_user_asm("stw",x,ptr); break;         \
+           case 8: STD_USER(x,ptr); break;                     \
+-          default: BUG(); break;                              \
++          default: __put_user_bad(); break;                   \
+           }                                                   \
+       }                                                       \
+                                                               \
+Index: linux-2.6.0-test5/include/asm-ppc64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/cacheflush.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/cacheflush.h   2003-09-27 11:38:40.672345248 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-ppc64/hvcall.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/hvcall.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/hvcall.h       2003-09-27 11:38:40.674344944 +0800
+@@ -59,9 +59,6 @@
+ #define H_XIRR                        0x74
+ #define H_PERFMON             0x7c
+-#define HSC                   ".long 0x44000022\n"
+-#define H_ENTER_r3            "li     3, 0x08\n"
+-
+ /* plpar_hcall() -- Generic call interface using above opcodes
+  *
+  * The actual call interface is a hypervisor call instruction with
+Index: linux-2.6.0-test5/include/asm-ppc64/ioctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/ioctl.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/ioctl.h        2003-09-27 11:38:40.675344792 +0800
+@@ -42,11 +42,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 them.. */
+ #define _IOC_DIR(nr)          (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+Index: linux-2.6.0-test5/include/asm-ppc64/local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/local.h   2003-09-27 11:38:18.481718736 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/local.h        2003-09-27 11:38:40.676344640 +0800
+@@ -0,0 +1 @@
++#include <asm-generic/local.h>
+Index: linux-2.6.0-test5/include/asm-ppc64/mmu_context.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/mmu_context.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/mmu_context.h  2003-09-27 11:38:40.678344336 +0800
+@@ -127,7 +127,8 @@
+ #endif
+       mmu_context_queue.size++;
+-      mmu_context_queue.elements[index] = mm->context;
++      mmu_context_queue.elements[index] =
++              mm->context & ~CONTEXT_LOW_HPAGES;
+       spin_unlock_irqrestore(&mmu_context_queue.lock, flags);
+ }
+@@ -189,6 +190,8 @@
+ {
+       unsigned long ordinal, vsid;
++      context &= ~CONTEXT_LOW_HPAGES;
++
+       ordinal = (((ea >> 28) & 0x1fffff) * LAST_USER_CONTEXT) | context;
+       vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK;
+Index: linux-2.6.0-test5/include/asm-ppc64/mmu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/mmu.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/mmu.h  2003-09-27 11:38:40.681343880 +0800
+@@ -18,6 +18,12 @@
+ /* Default "unsigned long" context */
+ typedef unsigned long mm_context_t;
++#ifdef CONFIG_HUGETLB_PAGE
++#define CONTEXT_LOW_HPAGES    (1UL<<63)
++#else
++#define CONTEXT_LOW_HPAGES    0
++#endif
++
+ /*
+  * Define the size of the cache used for segment table entries.  The first
+  * entry is used as a cache pointer, therefore the actual number of entries
+Index: linux-2.6.0-test5/include/asm-ppc64/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/mmzone.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/mmzone.h       2003-09-27 11:38:40.683343576 +0800
+@@ -20,7 +20,7 @@
+ extern int numa_cpu_lookup_table[];
+ extern int numa_memory_lookup_table[];
+-extern unsigned long numa_cpumask_lookup_table[];
++extern cpumask_t numa_cpumask_lookup_table[];
+ extern int nr_cpus_in_node[];
+ #define MAX_MEMORY (1UL << 41)
+Index: linux-2.6.0-test5/include/asm-ppc64/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/numnodes.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/numnodes.h     2003-09-27 11:38:40.684343424 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-ppc64/paca.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/paca.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/paca.h 2003-09-27 11:38:40.687342968 +0800
+@@ -63,7 +63,7 @@
+       u16 xPacaIndex;                 /* Logical processor number             0x18 */
+       u16 active;                     /* Is this cpu active?                  0x1a */
+       u32 default_decr;               /* Default decrementer value            0x1c */ 
+-      u64 xHrdIntStack;               /* Stack for hardware interrupts        0x20 */
++      u64 unused1;
+       u64 xKsave;                     /* Saved Kernel stack addr or zero      0x28 */
+       u64 pvr;                        /* Processor version register           0x30 */
+       u8 *exception_sp;               /*                                      0x38 */
+@@ -73,7 +73,7 @@
+       STAB xStab_data;                /* Segment table information            0x50,0x58,0x60 */
+       u8 xSegments[STAB_CACHE_SIZE];  /* Cache of used stab entries           0x68,0x70 */
+       u8 xProcEnabled;                /* 1=soft enabled                       0x78 */
+-      u8 xHrdIntCount;                /* Count of active hardware interrupts  0x79  */
++      u8 unused2;
+       u8 prof_enabled;                /* 1=iSeries profiling enabled          0x7A */
+       u8 stab_cache_pointer;  
+       u8 resv1[4];                    /*                                      0x7B-0x7F */
+Index: linux-2.6.0-test5/include/asm-ppc64/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/page.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/page.h 2003-09-27 11:38:40.689342664 +0800
+@@ -22,6 +22,39 @@
+ #define PAGE_MASK     (~(PAGE_SIZE-1))
+ #define PAGE_OFFSET_MASK (PAGE_SIZE-1)
++#ifdef CONFIG_HUGETLB_PAGE
++
++#define HPAGE_SHIFT   24
++#define HPAGE_SIZE    ((1UL) << HPAGE_SHIFT)
++#define HPAGE_MASK    (~(HPAGE_SIZE - 1))
++#define HUGETLB_PAGE_ORDER    (HPAGE_SHIFT - PAGE_SHIFT)
++
++/* For 64-bit processes the hugepage range is 1T-1.5T */
++#define TASK_HPAGE_BASE       (0x0000010000000000UL)
++#define TASK_HPAGE_END        (0x0000018000000000UL)
++/* For 32-bit processes the hugepage range is 2-3G */
++#define TASK_HPAGE_BASE_32    (0x80000000UL)
++#define TASK_HPAGE_END_32     (0xc0000000UL)
++
++#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
++#define is_hugepage_only_range(addr, len) \
++      ( ((addr > (TASK_HPAGE_BASE-len)) && (addr < TASK_HPAGE_END)) || \
++        ((current->mm->context & CONTEXT_LOW_HPAGES) && \
++         (addr > (TASK_HPAGE_BASE_32-len)) && (addr < TASK_HPAGE_END_32)) )
++#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
++
++#define in_hugepage_area(context, addr) \
++      ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) && \
++       ((((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \
++        (((context) & CONTEXT_LOW_HPAGES) && \
++         (((addr) >= TASK_HPAGE_BASE_32) && ((addr) < TASK_HPAGE_END_32)))))
++
++#else /* !CONFIG_HUGETLB_PAGE */
++
++#define in_hugepage_area(mm, addr)    0
++
++#endif /* !CONFIG_HUGETLB_PAGE */
++
+ #define SID_SHIFT       28
+ #define SID_MASK        0xfffffffff
+ #define GET_ESID(x)     (((x) >> SID_SHIFT) & SID_MASK)
+Index: linux-2.6.0-test5/include/asm-ppc64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/pgtable.h      2003-09-27 11:38:40.693342056 +0800
+@@ -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)
+ /*
+@@ -149,6 +148,25 @@
+ /* shift to put page number into pte */
+ #define PTE_SHIFT (16)
++/* We allow 2^41 bytes of real memory, so we need 29 bits in the PMD
++ * to give the PTE page number.  The bottom two bits are for flags. */
++#define PMD_TO_PTEPAGE_SHIFT (2)
++
++#ifdef CONFIG_HUGETLB_PAGE
++#define _PMD_HUGEPAGE 0x00000001U
++#define HUGEPTE_BATCH_SIZE (1<<(HPAGE_SHIFT-PMD_SHIFT))
++
++int hash_huge_page(struct mm_struct *mm, unsigned long access,
++                 unsigned long ea, unsigned long vsid, int local);
++
++#define HAVE_ARCH_UNMAPPED_AREA
++#else
++
++#define hash_huge_page(mm,a,ea,vsid,local)    -1
++#define _PMD_HUGEPAGE 0
++
++#endif
++
+ #ifndef __ASSEMBLY__
+ /*
+@@ -178,12 +196,16 @@
+ #define pte_pfn(x)            ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
+ #define pte_page(x)           pfn_to_page(pte_pfn(x))
+-#define pmd_set(pmdp, ptep)   (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep)))
++#define pmd_set(pmdp, ptep)   \
++      (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep) << PMD_TO_PTEPAGE_SHIFT))
+ #define pmd_none(pmd)         (!pmd_val(pmd))
+-#define       pmd_bad(pmd)            ((pmd_val(pmd)) == 0)
+-#define       pmd_present(pmd)        ((pmd_val(pmd)) != 0)
++#define       pmd_hugepage(pmd)       (!!(pmd_val(pmd) & _PMD_HUGEPAGE))
++#define       pmd_bad(pmd)            (((pmd_val(pmd)) == 0) || pmd_hugepage(pmd))
++#define       pmd_present(pmd)        ((!pmd_hugepage(pmd)) \
++                               && (pmd_val(pmd) & ~_PMD_HUGEPAGE) != 0)
+ #define       pmd_clear(pmdp)         (pmd_val(*(pmdp)) = 0)
+-#define pmd_page_kernel(pmd)  (__bpn_to_ba(pmd_val(pmd)))
++#define pmd_page_kernel(pmd)  \
++      (__bpn_to_ba(pmd_val(pmd) >> PMD_TO_PTEPAGE_SHIFT))
+ #define pmd_page(pmd)         virt_to_page(pmd_page_kernel(pmd))
+ #define pgd_set(pgdp, pmdp)   (pgd_val(*(pgdp)) = (__ba_to_bpn(pmdp)))
+ #define pgd_none(pgd)         (!pgd_val(pgd))
+Index: linux-2.6.0-test5/include/asm-ppc64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/posix_types.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/posix_types.h  2003-09-27 11:38:40.695341752 +0800
+@@ -12,7 +12,6 @@
+  * 2 of the License, or (at your option) any later version.
+  */
+-typedef unsigned long __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned long         __kernel_nlink_t;
+ typedef unsigned int  __kernel_mode_t;
+Index: linux-2.6.0-test5/include/asm-ppc64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/processor.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/processor.h    2003-09-27 11:38:40.703340536 +0800
+@@ -612,8 +612,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-ppc64/prom.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/prom.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/prom.h 2003-09-27 11:38:40.705340232 +0800
+@@ -183,8 +183,6 @@
+ extern struct device_node *find_path_device(const char *path);
+ extern struct device_node *find_compatible_devices(const char *type,
+                                                  const char *compat);
+-extern struct device_node *find_pci_device_OFnode(unsigned char bus,
+-      unsigned char dev_fn);
+ extern struct device_node *find_all_nodes(void);
+ extern int device_is_compatible(struct device_node *device, const char *);
+ extern int machine_is_compatible(const char *compat);
+Index: linux-2.6.0-test5/include/asm-ppc64/rtas.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/rtas.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/rtas.h 2003-09-27 11:38:40.708339776 +0800
+@@ -166,6 +166,13 @@
+ extern void rtas_power_off(void);
+ extern void rtas_halt(void);
++/* Given an RTAS status code of 9900..9905 compute the hinted delay */
++unsigned int rtas_extended_busy_delay_time(int status);
++static inline int rtas_is_extended_busy(int status)
++{
++      return status >= 9900 && status <= 9909;
++}
++
+ /* Some RTAS ops require a data buffer and that buffer must be < 4G.
+  * Rather than having a memory allocator, just use this buffer
+  * (get the lock first), make the RTAS call.  Copy the data instead
+Index: linux-2.6.0-test5/include/asm-ppc64/rwsem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/rwsem.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/rwsem.h        2003-09-27 11:38:40.709339624 +0800
+@@ -1,5 +1,5 @@
+ /*
+- * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
++ * include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff
+  * in lib/rwsem.c.  Adapted largely from include/asm-i386/rwsem.h
+  * by Paul Mackerras <paulus@samba.org>.
+  *
+@@ -74,9 +74,7 @@
+  */
+ static inline void __down_read(struct rw_semaphore *sem)
+ {
+-      if (atomic_inc_return((atomic_t *)(&sem->count)) > 0)
+-              smp_wmb();
+-      else
++      if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0))
+               rwsem_down_read_failed(sem);
+ }
+@@ -87,7 +85,6 @@
+       while ((tmp = sem->count) >= 0) {
+               if (tmp == cmpxchg(&sem->count, tmp,
+                                  tmp + RWSEM_ACTIVE_READ_BIAS)) {
+-                      smp_wmb();
+                       return 1;
+               }
+       }
+@@ -103,9 +100,7 @@
+       tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+                               (atomic_t *)(&sem->count));
+-      if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
+-              smp_wmb();
+-      else
++      if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
+               rwsem_down_write_failed(sem);
+ }
+@@ -115,7 +110,6 @@
+       tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+                     RWSEM_ACTIVE_WRITE_BIAS);
+-      smp_wmb();
+       return tmp == RWSEM_UNLOCKED_VALUE;
+ }
+@@ -126,9 +120,8 @@
+ {
+       int tmp;
+-      smp_wmb();
+       tmp = atomic_dec_return((atomic_t *)(&sem->count));
+-      if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
++      if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
+               rwsem_wake(sem);
+ }
+@@ -137,9 +130,8 @@
+  */
+ static inline void __up_write(struct rw_semaphore *sem)
+ {
+-      smp_wmb();
+-      if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+-                            (atomic_t *)(&sem->count)) < 0)
++      if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
++                            (atomic_t *)(&sem->count)) < 0))
+               rwsem_wake(sem);
+ }
+@@ -158,7 +150,6 @@
+ {
+       int tmp;
+-      smp_wmb();
+       tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
+       if (tmp < 0)
+               rwsem_downgrade_wake(sem);
+@@ -169,7 +160,6 @@
+  */
+ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+ {
+-      smp_mb();
+       return atomic_add_return(delta, (atomic_t *)(&sem->count));
+ }
+Index: linux-2.6.0-test5/include/asm-ppc64/semaphore.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/semaphore.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/semaphore.h    2003-09-27 11:38:40.711339320 +0800
+@@ -22,6 +22,7 @@
+        * sleeping on `wait'.
+        */
+       atomic_t count;
++      int sleepers;
+       wait_queue_head_t wait;
+ #ifdef WAITQUEUE_DEBUG
+       long __magic;
+@@ -37,6 +38,7 @@
+ #define __SEMAPHORE_INITIALIZER(name, count) \
+       { ATOMIC_INIT(count), \
++        0, \
+         __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+         __SEM_DEBUG_INIT(name) }
+@@ -52,6 +54,7 @@
+ 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;
+@@ -82,9 +85,8 @@
+       /*
+        * Try to get the semaphore, take the slow path if we fail.
+        */
+-      if (atomic_dec_return(&sem->count) < 0)
++      if (unlikely(atomic_dec_return(&sem->count) < 0))
+               __down(sem);
+-      smp_wmb();
+ }
+ static inline int down_interruptible(struct semaphore * sem)
+@@ -96,23 +98,18 @@
+ #endif
+       might_sleep();
+-      if (atomic_dec_return(&sem->count) < 0)
++      if (unlikely(atomic_dec_return(&sem->count) < 0))
+               ret = __down_interruptible(sem);
+-      smp_wmb();
+       return ret;
+ }
+ static inline int down_trylock(struct semaphore * sem)
+ {
+-      int ret;
+-
+ #ifdef WAITQUEUE_DEBUG
+       CHECK_MAGIC(sem->__magic);
+ #endif
+-      ret = atomic_dec_if_positive(&sem->count) < 0;
+-      smp_wmb();
+-      return ret;
++      return atomic_dec_if_positive(&sem->count) < 0;
+ }
+ static inline void up(struct semaphore * sem)
+@@ -121,8 +118,7 @@
+       CHECK_MAGIC(sem->__magic);
+ #endif
+-      smp_wmb();
+-      if (atomic_inc_return(&sem->count) <= 0)
++      if (unlikely(atomic_inc_return(&sem->count) <= 0))
+               __up(sem);
+ }
+Index: linux-2.6.0-test5/include/asm-ppc64/serial.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/serial.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/serial.h       2003-09-27 11:38:40.713339016 +0800
+@@ -26,11 +26,9 @@
+ /* Standard COM flags (except for COM4, because of the 8514 problem) */
+ #ifdef CONFIG_SERIAL_DETECT_IRQ
+-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
+-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
++#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+ #else
+-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
++#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
+ #endif
+ #ifdef CONFIG_SERIAL_MANY_PORTS
+@@ -60,8 +58,8 @@
+       /* UART CLK   PORT IRQ     FLAGS        */                      \
+       { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },      /* ttyS0 */     \
+       { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },      /* ttyS1 */     \
+-      { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },      /* ttyS2 */     \
+-      { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },     /* ttyS3 */
++      { 0, BASE_BAUD, 0x890, 0xf, STD_COM_FLAGS },    /* ttyS2 */     \
++      { 0, BASE_BAUD, 0x898, 0xe, STD_COM_FLAGS },    /* ttyS3 */
+ #ifdef CONFIG_SERIAL_MANY_PORTS
+Index: linux-2.6.0-test5/include/asm-ppc64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/signal.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/signal.h       2003-09-27 11:38:40.715338712 +0800
+@@ -57,7 +57,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-ppc64/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/stat.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/stat.h 2003-09-27 11:38:40.717338408 +0800
+@@ -11,13 +11,13 @@
+ #include <linux/types.h>
+ struct stat {
+-      dev_t           st_dev;
++      unsigned long   st_dev;
+       ino_t           st_ino;
+       nlink_t         st_nlink;
+       mode_t          st_mode;
+       uid_t           st_uid;
+       gid_t           st_gid;
+-      dev_t           st_rdev;
++      unsigned long   st_rdev;
+       off_t           st_size;
+       unsigned long   st_blksize;
+       unsigned long   st_blocks;
+Index: linux-2.6.0-test5/include/asm-ppc64/topology.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/topology.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/topology.h     2003-09-27 11:38:40.718338256 +0800
+@@ -24,14 +24,16 @@
+ #define parent_node(node)     (node)
+-static inline unsigned long node_to_cpumask(int node)
++static inline cpumask_t node_to_cpumask(int node)
+ {
+       return numa_cpumask_lookup_table[node];
+ }
+ static inline int node_to_first_cpu(int node)
+ {
+-      return __ffs(node_to_cpumask(node));
++      cpumask_t tmp;
++      tmp = node_to_cpumask(node);
++      return first_cpu(tmp);
+ }
+ #define node_to_memblk(node)  (node)
+Index: linux-2.6.0-test5/include/asm-ppc64/uaccess.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc64/uaccess.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc64/uaccess.h      2003-09-27 11:38:40.722337648 +0800
+@@ -132,6 +132,7 @@
+ #define __put_user_size(x,ptr,size,retval,errret)                     \
+ do {                                                                  \
++      might_sleep();                                                  \
+       retval = 0;                                                     \
+       switch (size) {                                                 \
+         case 1: __put_user_asm(x,ptr,retval,"stb",errret); break;     \
+@@ -185,6 +186,7 @@
+ #define __get_user_size(x,ptr,size,retval,errret)                     \
+ do {                                                                  \
++      might_sleep();                                                  \
+       retval = 0;                                                     \
+       switch (size) {                                                 \
+         case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break;     \
+@@ -220,6 +222,7 @@
+ static inline unsigned long
+ __copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
++      might_sleep();
+       if (__builtin_constant_p(n)) {
+               unsigned long ret;
+@@ -244,6 +247,7 @@
+ static inline unsigned long
+ __copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++      might_sleep();
+       if (__builtin_constant_p(n)) {
+               unsigned long ret;
+@@ -289,6 +293,7 @@
+ static inline unsigned long
+ copy_in_user(void *to, const void *from, unsigned long n)
+ {
++      might_sleep();
+       if (likely(access_ok(VERIFY_READ, from, n) &&
+           access_ok(VERIFY_WRITE, to, n)))
+               n =__copy_tofrom_user(to, from, n);
+@@ -300,6 +305,7 @@
+ static inline unsigned long
+ clear_user(void *addr, unsigned long size)
+ {
++      might_sleep();
+       if (likely(access_ok(VERIFY_WRITE, addr, size)))
+               size = __clear_user(addr, size);
+       return size;
+@@ -310,6 +316,7 @@
+ static inline long
+ strncpy_from_user(char *dst, const char *src, long count)
+ {
++      might_sleep();
+       if (likely(access_ok(VERIFY_READ, src, 1)))
+               return __strncpy_from_user(dst, src, count);
+       return -EFAULT;
+@@ -329,6 +336,7 @@
+  */
+ static inline int strnlen_user(const char *str, long len)
+ {
++      might_sleep();
+       if (likely(access_ok(VERIFY_READ, str, 1)))
+               return __strnlen_user(str, len);
+       return 0;
+Index: linux-2.6.0-test5/include/asm-ppc/bitops.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/bitops.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/bitops.h 2003-09-27 11:38:40.725337192 +0800
+@@ -276,7 +276,7 @@
+  * Find the first bit set in a 140-bit bitmap.
+  * The first 100 bits are unlikely to be set.
+  */
+-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]);
+@@ -295,7 +295,7 @@
+  * @offset: The bitnumber to start searching at
+  * @size: The maximum size to search
+  */
+-static __inline__ unsigned long find_next_bit(unsigned long *addr,
++static __inline__ unsigned long find_next_bit(const unsigned long *addr,
+       unsigned long size, unsigned long offset)
+ {
+       unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+@@ -352,7 +352,7 @@
+ #define find_first_zero_bit(addr, size) \
+       find_next_zero_bit((addr), (size), 0)
+-static __inline__ unsigned long find_next_zero_bit(unsigned long * addr,
++static __inline__ unsigned long find_next_zero_bit(const unsigned long *addr,
+       unsigned long size, unsigned long offset)
+ {
+       unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
+@@ -411,7 +411,7 @@
+ #define ext2_find_first_zero_bit(addr, size) \
+         ext2_find_next_zero_bit((addr), (size), 0)
+-static __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
++static __inline__ unsigned long ext2_find_next_zero_bit(const void *addr,
+       unsigned long size, unsigned long offset)
+ {
+       unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+Index: linux-2.6.0-test5/include/asm-ppc/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/cacheflush.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/cacheflush.h     2003-09-27 11:38:40.726337040 +0800
+@@ -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);
+Index: linux-2.6.0-test5/include/asm-ppc/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/highmem.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/highmem.h        2003-09-27 11:38:40.728336736 +0800
+@@ -26,6 +26,7 @@
+ #include <linux/interrupt.h>
+ #include <asm/kmap_types.h>
+ #include <asm/tlbflush.h>
++#include <asm/page.h>
+ /* undef for production */
+ #define HIGHMEM_DEBUG 1
+@@ -41,8 +42,8 @@
+  * easily, subsequent pte tables have to be allocated in one physical
+  * chunk of RAM.
+  */
+-#define PKMAP_BASE CONFIG_HIGHMEM_START
+-#define LAST_PKMAP 1024
++#define PKMAP_BASE    CONFIG_HIGHMEM_START
++#define LAST_PKMAP    (1 << PTE_SHIFT)
+ #define LAST_PKMAP_MASK (LAST_PKMAP-1)
+ #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+ #define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+@@ -131,6 +132,8 @@
+       return pte_page(kmap_pte[idx]);
+ }
++#define flush_cache_kmaps()   flush_cache_all()
++
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_HIGHMEM_H */
+Index: linux-2.6.0-test5/include/asm-ppc/ioctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/ioctl.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/ioctl.h  2003-09-27 11:38:40.729336584 +0800
+@@ -37,11 +37,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 them.. */
+ #define _IOC_DIR(nr)          (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+Index: linux-2.6.0-test5/include/asm-ppc/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/pgtable.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/pgtable.h        2003-09-27 11:38:40.736335520 +0800
+@@ -129,7 +129,6 @@
+ #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
+ /*
+Index: linux-2.6.0-test5/include/asm-ppc/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/posix_types.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/posix_types.h    2003-09-27 11:38:40.738335216 +0800
+@@ -7,7 +7,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned int  __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned int  __kernel_mode_t;
+ typedef unsigned short        __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-ppc/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/processor.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/processor.h      2003-09-27 11:38:40.749333544 +0800
+@@ -803,7 +803,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+@@ -848,6 +847,7 @@
+       /* AltiVec status */
+       vector128       vscr __attribute((aligned(16)));
+       unsigned long   vrsave;
++      int             used_vr;        /* set if process has used altivec */
+ #endif /* CONFIG_ALTIVEC */
+ };
+Index: linux-2.6.0-test5/include/asm-ppc/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/signal.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/signal.h 2003-09-27 11:38:40.750333392 +0800
+@@ -61,7 +61,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-ppc/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/stat.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/stat.h   2003-09-27 11:38:40.752333088 +0800
+@@ -22,13 +22,13 @@
+ #define STAT_HAVE_NSEC 1
+ struct stat {
+-      dev_t           st_dev;
++      unsigned        st_dev;
+       ino_t           st_ino;
+       mode_t          st_mode;
+       nlink_t         st_nlink;
+       uid_t           st_uid;
+       gid_t           st_gid;
+-      dev_t           st_rdev;
++      unsigned        st_rdev;
+       off_t           st_size;
+       unsigned long   st_blksize;
+       unsigned long   st_blocks;
+Index: linux-2.6.0-test5/include/asm-ppc/time.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/time.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/time.h   2003-09-27 11:38:40.753332936 +0800
+@@ -97,6 +97,13 @@
+       return rtcl;
+ }
++extern __inline__ unsigned long get_rtcu(void)
++{
++      unsigned long rtcu;
++      asm volatile("mfrtcu %0" : "=r" (rtcu));
++      return rtcu;
++}
++
+ extern __inline__ unsigned get_native_tbl(void) {
+       if (__USE_RTC())
+               return get_rtcl();
+@@ -140,6 +147,7 @@
+ #endif
+ /* Use mulhwu to scale processor timebase to timeval */
++/* Specifically, this computes (x * y) / 2^32.  -- paulus */
+ #define mulhwu(x,y) \
+ ({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+Index: linux-2.6.0-test5/include/asm-ppc/ucontext.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-ppc/ucontext.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-ppc/ucontext.h       2003-09-27 11:38:40.755332632 +0800
+@@ -1,14 +1,28 @@
+ #ifndef _ASMPPC_UCONTEXT_H
+ #define _ASMPPC_UCONTEXT_H
+-/* Copied from i386. */
++#include <asm/elf.h>
++#include <asm/signal.h>
++
++struct mcontext {
++      elf_gregset_t   mc_gregs;
++      elf_fpregset_t  mc_fregs;
++      unsigned long   mc_pad[2];
++      elf_vrregset_t  mc_vregs __attribute__((__aligned__(16)));
++};
+ struct ucontext {
+-      unsigned long     uc_flags;
+-      struct ucontext  *uc_link;
+-      stack_t           uc_stack;
+-      struct sigcontext uc_mcontext;
+-      sigset_t          uc_sigmask;   /* mask last for extensibility */
++      unsigned long    uc_flags;
++      struct ucontext *uc_link;
++      stack_t          uc_stack;
++      int              uc_pad[7];
++      struct mcontext *uc_regs;       /* backward compat */
++      sigset_t         uc_oldsigmask; /* backward compat */
++      int              uc_pad2;
++      sigset_t         uc_sigmask;
++      /* glibc has 1024-bit signal masks, ours are 64-bit */
++      int              uc_maskext[30];
++      struct mcontext  uc_mcontext;
+ };
+ #endif /* !_ASMPPC_UCONTEXT_H */
+Index: linux-2.6.0-test5/include/asm-s390/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/cacheflush.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/cacheflush.h    2003-09-27 11:38:40.756332480 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-s390/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/pgtable.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/pgtable.h       2003-09-27 11:38:40.762331568 +0800
+@@ -117,7 +117,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))
+ #ifndef __s390x__
+ # define VMALLOC_END     (0x7fffffffL)
+ #else /* __s390x__ */
+Index: linux-2.6.0-test5/include/asm-s390/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/posix_types.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/posix_types.h   2003-09-27 11:38:40.764331264 +0800
+@@ -34,7 +34,6 @@
+ #ifndef __s390x__
+-typedef unsigned short  __kernel_dev_t;
+ typedef unsigned long   __kernel_ino_t;
+ typedef unsigned short  __kernel_mode_t;
+ typedef unsigned short  __kernel_nlink_t;
+@@ -51,7 +50,6 @@
+ #else /* __s390x__ */
+-typedef unsigned int    __kernel_dev_t;
+ typedef unsigned int    __kernel_ino_t;
+ typedef unsigned int    __kernel_mode_t;
+ typedef unsigned int    __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-s390/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-s390/signal.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-s390/signal.h        2003-09-27 11:38:40.766330960 +0800
+@@ -78,7 +78,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN        32
+-#define SIGRTMAX        (_NSIG-1)
++#define SIGRTMAX        _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-sh/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/cacheflush.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/cacheflush.h      2003-09-27 11:38:40.768330656 +0800
+@@ -10,4 +10,14 @@
+ /* 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 */
+Index: linux-2.6.0-test5/include/asm-sh/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/mmzone.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/mmzone.h  2003-09-27 11:38:40.769330504 +0800
+@@ -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 @@
+ {
+       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;
+Index: linux-2.6.0-test5/include/asm-sh/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/numnodes.h   2003-09-27 11:38:18.482718584 +0800
++++ linux-2.6.0-test5/include/asm-sh/numnodes.h        2003-09-27 11:38:40.769330504 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-sh/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/pgtable.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/pgtable.h 2003-09-27 11:38:40.773329896 +0800
+@@ -51,7 +51,6 @@
+  * 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 */
+Index: linux-2.6.0-test5/include/asm-sh/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/posix_types.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/posix_types.h     2003-09-27 11:38:40.774329744 +0800
+@@ -7,7 +7,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned short        __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned short        __kernel_mode_t;
+ typedef unsigned short        __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-sh/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/processor.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/processor.h       2003-09-27 11:38:40.777329288 +0800
+@@ -169,8 +169,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-sh/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sh/signal.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sh/signal.h  2003-09-27 11:38:40.778329136 +0800
+@@ -57,7 +57,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-sparc64/bugs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/bugs.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/bugs.h       2003-09-27 11:38:40.779328984 +0800
+@@ -4,4 +4,13 @@
+  *  Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+  */
+-static void check_bugs(void) { }
++#include <linux/config.h>
++
++extern unsigned long loops_per_jiffy;
++
++static void check_bugs(void)
++{
++#ifndef CONFIG_SMP
++      cpu_data(0).udelay_val = loops_per_jiffy;
++#endif
++}
+Index: linux-2.6.0-test5/include/asm-sparc64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/cacheflush.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/cacheflush.h 2003-09-27 11:38:40.781328680 +0800
+@@ -48,6 +48,14 @@
+ #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)          flush_cache_all()
++#define flush_cache_vunmap(start, end)                flush_cache_all()
++
+ #endif /* _SPARC64_CACHEFLUSH_H */
+Index: linux-2.6.0-test5/include/asm-sparc64/delay.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/delay.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/delay.h      2003-09-27 11:38:40.782328528 +0800
+@@ -13,12 +13,6 @@
+ #ifndef __ASSEMBLY__
+-#ifdef CONFIG_SMP
+-#include <asm/smp.h>
+-#else
+-extern unsigned long loops_per_jiffy;
+-#endif 
+-
+ static __inline__ void __delay(unsigned long loops)
+ {
+       __asm__ __volatile__(
+Index: linux-2.6.0-test5/include/asm-sparc64/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/lockmeter.h     2003-09-27 11:38:18.482718584 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/lockmeter.h  2003-09-27 11:38:40.782328528 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-sparc64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/pgtable.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/pgtable.h    2003-09-27 11:38:40.787327768 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-sparc64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/posix_types.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/posix_types.h        2003-09-27 11:38:40.789327464 +0800
+@@ -16,7 +16,6 @@
+ typedef int                    __kernel_ipc_pid_t;
+ typedef unsigned int           __kernel_uid_t;
+ typedef unsigned int           __kernel_gid_t;
+-typedef unsigned int           __kernel_dev_t;
+ typedef unsigned long          __kernel_ino_t;
+ typedef unsigned int           __kernel_mode_t;
+ typedef unsigned short         __kernel_umode_t;
+Index: linux-2.6.0-test5/include/asm-sparc64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/processor.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/processor.h  2003-09-27 11:38:40.791327160 +0800
+@@ -22,7 +22,6 @@
+ #include <asm/page.h>
+ /* Bus types */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-sparc64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/signal.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/signal.h     2003-09-27 11:38:40.794326704 +0800
+@@ -89,7 +89,7 @@
+ #define _NSIG_WORDS           (__NEW_NSIG / _NSIG_BPW)
+ #define SIGRTMIN       32
+-#define SIGRTMAX       (__NEW_NSIG - 1)
++#define SIGRTMAX       __NEW_NSIG
+ #if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+ #define _NSIG                 __NEW_NSIG
+Index: linux-2.6.0-test5/include/asm-sparc64/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/spinlock.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/spinlock.h   2003-09-27 11:38:40.796326400 +0800
+@@ -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 @@
+ #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)
+Index: linux-2.6.0-test5/include/asm-sparc64/stat.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/stat.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/stat.h       2003-09-27 11:38:40.798326096 +0800
+@@ -5,13 +5,13 @@
+ #include <linux/types.h>
+ struct stat {
+-      dev_t   st_dev;
++      unsigned   st_dev;
+       ino_t   st_ino;
+       mode_t  st_mode;
+       short   st_nlink;
+       uid_t   st_uid;
+       gid_t   st_gid;
+-      dev_t   st_rdev;
++      unsigned   st_rdev;
+       off_t   st_size;
+       time_t  st_atime;
+       time_t  st_mtime;
+Index: linux-2.6.0-test5/include/asm-sparc64/vga.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc64/vga.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc64/vga.h        2003-09-27 11:38:40.799325944 +0800
+@@ -13,18 +13,16 @@
+ static inline void scr_writew(u16 val, u16 *addr)
+ {
+-      if ((long) addr < 0)
+-              *addr = val;
+-      else
+-              writew(val, (unsigned long) addr);
++      BUG_ON((long) addr >= 0);
++
++      *addr = val;
+ }
+ static inline u16 scr_readw(const u16 *addr)
+ {
+-      if ((long) addr < 0)
+-              return *addr;
+-      else
+-              return readw((unsigned long) addr);
++      BUG_ON((long) addr >= 0);
++
++      return *addr;
+ }
+ #define VGA_MAP_MEM(x) (x)
+Index: linux-2.6.0-test5/include/asm-sparc/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/cacheflush.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/cacheflush.h   2003-09-27 11:38:40.800325792 +0800
+@@ -56,6 +56,11 @@
+ #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 @@
+ #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 */
+Index: linux-2.6.0-test5/include/asm-sparc/highmem.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/highmem.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/highmem.h      2003-09-27 11:38:40.802325488 +0800
+@@ -89,6 +89,8 @@
+       return pte_page(*pte);
+ }
++#define flush_cache_kmaps()   flush_cache_all()
++
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_HIGHMEM_H */
+Index: linux-2.6.0-test5/include/asm-sparc/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/pgtable.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/pgtable.h      2003-09-27 11:38:40.806324880 +0800
+@@ -101,8 +101,6 @@
+ 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()
+Index: linux-2.6.0-test5/include/asm-sparc/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/posix_types.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/posix_types.h  2003-09-27 11:38:40.808324576 +0800
+@@ -17,7 +17,6 @@
+ 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;
+ typedef unsigned long          __kernel_ino_t;
+ typedef unsigned short         __kernel_mode_t;
+ typedef unsigned short         __kernel_umode_t;
+Index: linux-2.6.0-test5/include/asm-sparc/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/processor.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/processor.h    2003-09-27 11:38:40.810324272 +0800
+@@ -27,7 +27,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-sparc/sfp-machine.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/sfp-machine.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/sfp-machine.h  2003-09-27 11:38:40.813323816 +0800
+@@ -77,9 +77,9 @@
+ /* Some assembly to speed things up. */
+ #define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                   \
+-  __asm__ ("addcc %r7,%8,%2
+-          addxcc %r5,%6,%1
+-          addx %r3,%4,%0"                                             \
++  __asm__ ("addcc %r7,%8,%2\n\t"                                      \
++         "addxcc %r5,%6,%1\n\t"                                       \
++         "addx %r3,%4,%0\n"                                           \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+@@ -92,9 +92,9 @@
+          : "cc")
+ #define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                   \
+-  __asm__ ("subcc %r7,%8,%2
+-          subxcc %r5,%6,%1
+-          subx %r3,%4,%0"                                             \
++  __asm__ ("subcc %r7,%8,%2\n\t"                                      \
++          "subxcc %r5,%6,%1\n\t"                                      \
++          "subx %r3,%4,%0\n"                                          \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+@@ -111,11 +111,11 @@
+     /* We need to fool gcc,  as we need to pass more than 10          \
+        input/outputs.  */                                             \
+     register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");          \
+-    __asm__ __volatile__ ("
+-          addcc %r8,%9,%1
+-          addxcc %r6,%7,%0
+-          addxcc %r4,%5,%%g2
+-          addx %r2,%3,%%g1"                                           \
++    __asm__ __volatile__ (                                            \
++          "addcc %r8,%9,%1\n\t"                                       \
++          "addxcc %r6,%7,%0\n\t"                                      \
++          "addxcc %r4,%5,%%g2\n\t"                                    \
++          "addx %r2,%3,%%g1\n\t"                                      \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+@@ -136,11 +136,11 @@
+     /* We need to fool gcc,  as we need to pass more than 10          \
+        input/outputs.  */                                             \
+     register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");          \
+-    __asm__ __volatile__ ("
+-          subcc %r8,%9,%1
+-          subxcc %r6,%7,%0
+-          subxcc %r4,%5,%%g2
+-          subx %r2,%3,%%g1"                                           \
++    __asm__ __volatile__ (                                            \
++          "subcc %r8,%9,%1\n\t"                                       \
++          "subxcc %r6,%7,%0\n\t"                                      \
++          "subxcc %r4,%5,%%g2\n\t"                                    \
++          "subx %r2,%3,%%g1\n\t"                                      \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+@@ -161,10 +161,10 @@
+ #define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+ #define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                       \
+-  __asm__ ("addcc %3,%4,%3
+-          addxcc %2,%%g0,%2
+-          addxcc %1,%%g0,%1
+-          addx %0,%%g0,%0"                                            \
++  __asm__ ("addcc %3,%4,%3\n\t"                                               \
++         "addxcc %2,%%g0,%2\n\t"                                      \
++         "addxcc %1,%%g0,%1\n\t"                                      \
++         "addx %0,%%g0,%0\n\t"                                        \
+          : "=&r" ((USItype)(x3)),                                     \
+            "=&r" ((USItype)(x2)),                                     \
+            "=&r" ((USItype)(x1)),                                     \
+Index: linux-2.6.0-test5/include/asm-sparc/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-sparc/signal.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-sparc/signal.h       2003-09-27 11:38:40.815323512 +0800
+@@ -89,7 +89,7 @@
+ #define _NSIG_WORDS   (__NEW_NSIG / _NSIG_BPW)
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (__NEW_NSIG - 1)
++#define SIGRTMAX      __NEW_NSIG
+ #if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+ #define       _NSIG           __NEW_NSIG
+Index: linux-2.6.0-test5/include/asm-um/archparam-i386.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/archparam-i386.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/archparam-i386.h  2003-09-27 11:38:40.816323360 +0800
+@@ -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;
+Index: linux-2.6.0-test5/include/asm-um/common.lds.S
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/common.lds.S 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/common.lds.S      2003-09-27 11:38:40.818323056 +0800
+@@ -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)
++  }
++ 
+Index: linux-2.6.0-test5/include/asm-um/cpufeature.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/cpufeature.h 2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/cpufeature.h      2003-09-27 11:38:40.818323056 +0800
+@@ -0,0 +1,6 @@
++#ifndef __UM_CPUFEATURE_H
++#define __UM_CPUFEATURE_H
++
++#include "asm/arch/cpufeature.h"
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/current.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/current.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/current.h 2003-09-27 11:38:40.820322752 +0800
+@@ -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__ */
+Index: linux-2.6.0-test5/include/asm-um/fixmap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/fixmap.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/fixmap.h  2003-09-27 11:38:40.821322600 +0800
+@@ -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);
+ /*
+Index: linux-2.6.0-test5/include/asm-um/irq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/irq.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/irq.h     2003-09-27 11:38:40.823322296 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-um/local.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/local.h      2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/local.h   2003-09-27 11:38:40.823322296 +0800
+@@ -0,0 +1,6 @@
++#ifndef __UM_LOCAL_H
++#define __UM_LOCAL_H
++
++#include "asm/arch/local.h"
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/module-generic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/module-generic.h     2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/module-generic.h  2003-09-27 11:38:40.823322296 +0800
+@@ -0,0 +1,6 @@
++#ifndef __UM_MODULE_GENERIC_H
++#define __UM_MODULE_GENERIC_H
++
++#include "asm/arch/module.h"
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/module-i386.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/module-i386.h        2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/module-i386.h     2003-09-27 11:38:40.823322296 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-um/page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/page.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/page.h    2003-09-27 11:38:40.825321992 +0800
+@@ -4,7 +4,6 @@
+ struct page;
+ #include "asm/arch/page.h"
+-#include "asm/bug.h"
+ #undef __pa
+ #undef __va
+Index: linux-2.6.0-test5/include/asm-um/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/pgtable.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/pgtable.h 2003-09-27 11:38:40.829321384 +0800
+@@ -69,7 +69,6 @@
+ #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 @@
+ #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 @@
+ #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 @@
+  * 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 @@
+              !(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 @@
+ #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 @@
+       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 @@
+ #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 })
+Index: linux-2.6.0-test5/include/asm-um/processor-generic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/processor-generic.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/processor-generic.h       2003-09-27 11:38:40.831321080 +0800
+@@ -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)
+ /*
+Index: linux-2.6.0-test5/include/asm-um/processor-i386.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/processor-i386.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/processor-i386.h  2003-09-27 11:38:40.832320928 +0800
+@@ -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];
+Index: linux-2.6.0-test5/include/asm-um/sections.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/sections.h   2003-09-27 11:38:18.483718432 +0800
++++ linux-2.6.0-test5/include/asm-um/sections.h        2003-09-27 11:38:40.833320776 +0800
+@@ -0,0 +1,7 @@
++#ifndef _UM_SECTIONS_H
++#define _UM_SECTIONS_H
++
++/* nothing to see, move along */
++#include <asm-generic/sections.h>
++
++#endif
+Index: linux-2.6.0-test5/include/asm-um/smp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/smp.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/smp.h     2003-09-27 11:38:40.834320624 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/asm-um/system-generic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/system-generic.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/system-generic.h  2003-09-27 11:38:40.836320320 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-um/thread_info.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/thread_info.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/thread_info.h     2003-09-27 11:38:40.837320168 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-um/timex.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-um/timex.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-um/timex.h   2003-09-27 11:38:40.838320016 +0800
+@@ -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)
+Index: linux-2.6.0-test5/include/asm-v850/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/cacheflush.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/cacheflush.h    2003-09-27 11:38:40.840319712 +0800
+@@ -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 @@
+ #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__ */
+Index: linux-2.6.0-test5/include/asm-v850/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/posix_types.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/posix_types.h   2003-09-27 11:38:40.841319560 +0800
+@@ -14,7 +14,6 @@
+ #ifndef __V850_POSIX_TYPES_H__
+ #define __V850_POSIX_TYPES_H__
+-typedef unsigned int  __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned long long __kernel_ino64_t;
+ typedef unsigned int  __kernel_mode_t;
+Index: linux-2.6.0-test5/include/asm-v850/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/processor.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/processor.h     2003-09-27 11:38:40.843319256 +0800
+@@ -52,8 +52,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
+Index: linux-2.6.0-test5/include/asm-v850/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-v850/signal.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-v850/signal.h        2003-09-27 11:38:40.845318952 +0800
+@@ -71,7 +71,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/asm-x86_64/cacheflush.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/cacheflush.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/cacheflush.h  2003-09-27 11:38:40.846318800 +0800
+@@ -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);
+Index: linux-2.6.0-test5/include/asm-x86_64/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/mmzone.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/mmzone.h      2003-09-27 11:38:40.848318496 +0800
+@@ -10,7 +10,6 @@
+ #define VIRTUAL_BUG_ON(x) 
+-#include <asm/numnodes.h>
+ #include <asm/smp.h>
+ #define MAXNODE 8 
+Index: linux-2.6.0-test5/include/asm-x86_64/numnodes.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/numnodes.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/numnodes.h    2003-09-27 11:38:40.849318344 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-x86_64/pgtable.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/pgtable.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/pgtable.h     2003-09-27 11:38:40.853317736 +0800
+@@ -126,7 +126,6 @@
+ #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)
+Index: linux-2.6.0-test5/include/asm-x86_64/posix_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/posix_types.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/posix_types.h 2003-09-27 11:38:40.855317432 +0800
+@@ -7,7 +7,6 @@
+  * assume GCC is being used.
+  */
+-typedef unsigned long __kernel_dev_t;
+ typedef unsigned long __kernel_ino_t;
+ typedef unsigned int  __kernel_mode_t;
+ typedef unsigned long __kernel_nlink_t;
+Index: linux-2.6.0-test5/include/asm-x86_64/processor.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/processor.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/processor.h   2003-09-27 11:38:40.858316976 +0800
+@@ -160,7 +160,6 @@
+ /*
+  * Bus types
+  */
+-#define EISA_bus 0
+ #define MCA_bus 0
+ #define MCA_bus__is_a_macro
+Index: linux-2.6.0-test5/include/asm-x86_64/signal.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-x86_64/signal.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-x86_64/signal.h      2003-09-27 11:38:40.861316520 +0800
+@@ -77,7 +77,7 @@
+ /* These should not be considered constants from userland.  */
+ #define SIGRTMIN      32
+-#define SIGRTMAX      (_NSIG-1)
++#define SIGRTMAX      _NSIG
+ /*
+  * SA_FLAGS values:
+Index: linux-2.6.0-test5/include/linux/acpi.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/acpi.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/acpi.h     2003-09-27 11:38:40.864316064 +0800
+@@ -424,17 +424,17 @@
+ #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*/
+Index: linux-2.6.0-test5/include/linux/aio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/aio.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/aio.h      2003-09-27 11:38:40.867315608 +0800
+@@ -29,21 +29,26 @@
+ #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 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 @@
+       __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 @@
+               (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 @@
+ #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)
+Index: linux-2.6.0-test5/include/linux/atmclip.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/atmclip.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/atmclip.h  2003-09-27 11:38:40.868315456 +0800
+@@ -18,8 +18,4 @@
+ #define       SIOCMKCLIP      _IO('a',ATMIOC_CLIP)    /* create IP interface */
+-#ifdef __KERNEL__
+-extern const unsigned char llc_oui[6];
+-#endif
+-
+ #endif
+Index: linux-2.6.0-test5/include/linux/bio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/bio.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/bio.h      2003-09-27 11:38:40.871315000 +0800
+@@ -20,7 +20,6 @@
+ #ifndef __LINUX_BIO_H
+ #define __LINUX_BIO_H
+-#include <linux/kdev_t.h>
+ #include <linux/highmem.h>
+ #include <linux/mempool.h>
+Index: linux-2.6.0-test5/include/linux/blkdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/blkdev.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/blkdev.h   2003-09-27 11:38:40.877314088 +0800
+@@ -262,6 +262,7 @@
+       int busy;                       /* current depth */
+       int max_depth;                  /* what we will send to device */
+       int real_max_depth;             /* what the array can hold */
++      atomic_t refcnt;                /* map can be shared */
+ };
+ struct request_queue
+@@ -579,11 +580,12 @@
+ extern int blk_queue_start_tag(request_queue_t *, struct request *);
+ extern struct request *blk_queue_find_tag(request_queue_t *, int);
+ extern void blk_queue_end_tag(request_queue_t *, struct request *);
+-extern int blk_queue_init_tags(request_queue_t *, int);
++extern int blk_queue_init_tags(request_queue_t *, int, struct blk_queue_tag *);
+ extern void blk_queue_free_tags(request_queue_t *);
+ 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 *);
+Index: linux-2.6.0-test5/include/linux/buffer_head.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/buffer_head.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/buffer_head.h      2003-09-27 11:38:40.880313632 +0800
+@@ -162,6 +162,7 @@
+ 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 __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,11 +210,6 @@
+ 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 +228,13 @@
+ 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 +251,12 @@
+ }
+ 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 +280,34 @@
+  * __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 */
+Index: linux-2.6.0-test5/include/linux/coda_cache.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_cache.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_cache.h       2003-09-27 11:38:40.882313328 +0800
+@@ -13,7 +13,7 @@
+ /* credential cache */
+ void coda_cache_enter(struct inode *inode, int mask);
+ void coda_cache_clear_inode(struct inode *);
+-void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred);
++void coda_cache_clear_all(struct super_block *sb);
+ int coda_cache_check(struct inode *inode, int mask);
+ /* for downcalls and attributes and lookups */
+Index: linux-2.6.0-test5/include/linux/coda_fs_i.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_fs_i.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_fs_i.h        2003-09-27 11:38:40.883313176 +0800
+@@ -17,11 +17,12 @@
+  * coda fs inode data
+  */
+ struct coda_inode_info {
+-        struct ViceFid     c_fid;     /* Coda identifier */
++        struct CodaFid           c_fid;       /* Coda identifier */
+         u_short                  c_flags;     /* flags (see below) */
+       struct list_head   c_cilist;    /* list of all coda inodes */
+       unsigned int       c_mapcount;  /* nr of times this inode is mapped */
+-        struct coda_cred   c_cached_cred; /* credentials of cached perms */
++      unsigned int       c_cached_epoch; /* epoch for cached permissions */
++      vuid_t             c_uid;       /* fsuid for cached permissions */
+         unsigned int       c_cached_perm; /* cached access permissions */
+       struct inode       vfs_inode;
+ };
+@@ -34,7 +35,6 @@
+       int                cfi_magic;     /* magic number */
+       struct file       *cfi_container; /* container file for this cnode */
+       unsigned int       cfi_mapcount;  /* nr of times this file is mapped */
+-      struct coda_cred   cfi_cred;      /* credentials of opener */
+ };
+ #define CODA_FTOC(file) ((struct coda_file_info *)((file)->private_data))
+@@ -45,11 +45,11 @@
+ #define C_DYING       0x4   /* from venus (which died) */
+ #define C_PURGE       0x8
+-int coda_cnode_make(struct inode **, struct ViceFid *, struct super_block *);
+-struct inode *coda_iget(struct super_block *sb, struct ViceFid *fid, struct coda_vattr *attr);
++int coda_cnode_make(struct inode **, struct CodaFid *, struct super_block *);
++struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr);
+ int coda_cnode_makectl(struct inode **inode, struct super_block *sb);
+-struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb);
+-void coda_replace_fid(struct inode *, ViceFid *, ViceFid *);
++struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb);
++void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *);
+ #endif
+ #endif
+Index: linux-2.6.0-test5/include/linux/coda.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda.h     2003-09-27 11:38:40.889312264 +0800
+@@ -59,7 +59,7 @@
+ #ifndef _CODA_HEADER_
+ #define _CODA_HEADER_
+-
++#include <linux/config.h>
+ /* Catch new _KERNEL defn for NetBSD and DJGPP/__CYGWIN32__ */
+ #if defined(__NetBSD__) || \
+@@ -163,11 +163,11 @@
+ #ifndef _VENUS_DIRENT_T_
+ #define _VENUS_DIRENT_T_ 1
+ struct venus_dirent {
+-        unsigned long d_fileno;               /* file number of entry */
+-        unsigned short        d_reclen;               /* length of this record */
+-        unsigned char         d_type;                 /* file type, see below */
+-        unsigned char d_namlen;               /* length of string in d_name */
+-        char          d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
++        u_int32_t d_fileno;           /* file number of entry */
++        u_int16_t d_reclen;           /* length of this record */
++        u_int8_t  d_type;                     /* file type, see below */
++        u_int8_t  d_namlen;           /* length of string in d_name */
++        char    d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
+ };
+ #undef DIRSIZ
+ #define DIRSIZ(dp)      ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) + \
+@@ -194,54 +194,42 @@
+ #endif
+-#ifndef       _FID_T_
+-#define _FID_T_       1
+-typedef u_long VolumeId;
+-typedef u_long VnodeId;
+-typedef u_long Unique_t;
+-typedef u_long FileVersion;
+-#endif 
+-
+-#ifndef       _VICEFID_T_
+-#define _VICEFID_T_   1
+-typedef struct ViceFid {
+-    VolumeId Volume;
+-    VnodeId Vnode;
+-    Unique_t Unique;
+-} ViceFid;
+-#endif        /* VICEFID */
++#ifndef _VUID_T_
++#define _VUID_T_
++typedef u_int32_t vuid_t;
++typedef u_int32_t vgid_t;
++#endif /*_VUID_T_ */
++#ifdef CODA_FS_OLD_API
++struct CodaFid {
++      u_int32_t opaque[3];
++};
+-#ifdef __linux__
+-static __inline__ ino_t  coda_f2i(struct ViceFid *fid)
++static __inline__ ino_t  coda_f2i(struct CodaFid *fid)
+ {
+       if ( ! fid ) 
+               return 0; 
+-      if (fid->Vnode == 0xfffffffe || fid->Vnode == 0xffffffff)
+-              return ((fid->Volume << 20) | (fid->Unique & 0xfffff));
++      if (fid->opaque[1] == 0xfffffffe || fid->opaque[1] == 0xffffffff)
++              return ((fid->opaque[0] << 20) | (fid->opaque[2] & 0xfffff));
+       else
+-              return (fid->Unique + (fid->Vnode<<10) + (fid->Volume<<20));
++              return (fid->opaque[2] + (fid->opaque[1]<<10) + (fid->opaque[0]<<20));
+ }
+-      
+-#else
+-#define coda_f2i(fid)\
+-      ((fid) ? ((fid)->Unique + ((fid)->Vnode<<10) + ((fid)->Volume<<20)) : 0)
+-#endif
+-
+-
+-#ifndef _VUID_T_
+-#define _VUID_T_
+-typedef u_int32_t vuid_t;
+-typedef u_int32_t vgid_t;
+-#endif /*_VUID_T_ */
+-#ifndef _CODACRED_T_
+-#define _CODACRED_T_
+ struct coda_cred {
+     vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/
+-    vgid_t cr_groupid,     cr_egid, cr_sgid, cr_fsgid; /* same for groups */
++    vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
+ };
+-#endif 
++
++#else /* not defined(CODA_FS_OLD_API) */
++
++struct CodaFid {
++      u_int32_t opaque[4];
++};
++
++#define coda_f2i(fid)\
++      (fid ? (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]) : 0)
++
++#endif
+ #ifndef _VENUS_VATTR_T_
+ #define _VENUS_VATTR_T_
+@@ -330,31 +318,41 @@
+ #define CODA_KERNEL_VERSION 0 /* don't care about kernel version number */
+ #define CODA_KERNEL_VERSION 1 /* The old venus 4.6 compatible interface */
+ #endif
+-#define CODA_KERNEL_VERSION 2 /* venus_lookup gets an extra parameter */
++#ifdef CODA_FS_OLD_API
++#define CODA_KERNEL_VERSION 2 /* venus_lookup got an extra parameter */
++#else
++#define CODA_KERNEL_VERSION 3 /* 128-bit file identifiers */
++#endif
+ /*
+  *        Venus <-> Coda  RPC arguments
+  */
+ struct coda_in_hdr {
+-    unsigned long opcode;
+-    unsigned long unique;         /* Keep multiple outstanding msgs distinct */
+-    u_short pid;                  /* Common to all */
+-    u_short pgid;                 /* Common to all */
+-    u_short sid;                    /* Common to all */
+-    struct coda_cred cred;        /* Common to all */
++    u_int32_t opcode;
++    u_int32_t unique;     /* Keep multiple outstanding msgs distinct */
++#ifdef CODA_FS_OLD_API
++    u_int16_t pid;        /* Common to all */
++    u_int16_t pgid;       /* Common to all */
++    u_int16_t sid;          /* Common to all */
++    struct coda_cred cred;  /* Common to all */
++#else
++    pid_t pid;
++    pid_t pgid;
++    vuid_t uid;
++#endif
+ };
+ /* Really important that opcode and unique are 1st two fields! */
+ struct coda_out_hdr {
+-    unsigned long opcode;
+-    unsigned long unique;     
+-    unsigned long result;
++    u_int32_t opcode;
++    u_int32_t unique; 
++    u_int32_t result;
+ };
+ /* coda_root: NO_IN */
+ struct coda_root_out {
+     struct coda_out_hdr oh;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+ };
+ struct coda_root_in {
+@@ -364,7 +362,7 @@
+ /* coda_open: */
+ struct coda_open_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int       flags;
+ };
+@@ -378,7 +376,7 @@
+ /* coda_store: */
+ struct coda_store_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int       flags;
+ };
+@@ -389,7 +387,7 @@
+ /* coda_release: */
+ struct coda_release_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int       flags;
+ };
+@@ -400,7 +398,7 @@
+ /* coda_close: */
+ struct coda_close_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int       flags;
+ };
+@@ -411,7 +409,7 @@
+ /* coda_ioctl: */
+ struct coda_ioctl_in {
+     struct coda_in_hdr ih;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+     int       cmd;
+     int       len;
+     int       rwflag;
+@@ -428,7 +426,7 @@
+ /* coda_getattr: */
+ struct coda_getattr_in {
+     struct coda_in_hdr ih;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+ };
+ struct coda_getattr_out {
+@@ -440,7 +438,7 @@
+ /* coda_setattr: NO_OUT */
+ struct coda_setattr_in {
+     struct coda_in_hdr ih;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+     struct coda_vattr attr;
+ };
+@@ -451,7 +449,7 @@
+ /* coda_access: NO_OUT */
+ struct coda_access_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int       flags;
+ };
+@@ -467,14 +465,14 @@
+ /* coda_lookup: */
+ struct  coda_lookup_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int         name;         /* Place holder for data. */
+     int         flags;        
+ };
+ struct coda_lookup_out {
+     struct coda_out_hdr oh;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+     int       vtype;
+ };
+@@ -482,7 +480,7 @@
+ /* coda_create: */
+ struct coda_create_in {
+     struct coda_in_hdr ih;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+     struct coda_vattr attr;
+     int excl;
+     int mode;
+@@ -491,7 +489,7 @@
+ struct coda_create_out {
+     struct coda_out_hdr oh;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+     struct coda_vattr attr;
+ };
+@@ -499,7 +497,7 @@
+ /* coda_remove: NO_OUT */
+ struct coda_remove_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int name;         /* Place holder for data. */
+ };
+@@ -510,8 +508,8 @@
+ /* coda_link: NO_OUT */
+ struct coda_link_in {
+     struct coda_in_hdr ih;
+-    ViceFid sourceFid;          /* cnode to link *to* */
+-    ViceFid destFid;            /* Directory in which to place link */
++    struct CodaFid sourceFid; /* cnode to link *to* */
++    struct CodaFid destFid;   /* Directory in which to place link */
+     int tname;                /* Place holder for data. */
+ };
+@@ -523,9 +521,9 @@
+ /* coda_rename: NO_OUT */
+ struct coda_rename_in {
+     struct coda_in_hdr ih;
+-    ViceFid   sourceFid;
++    struct CodaFid sourceFid;
+     int       srcname;
+-    ViceFid destFid;
++    struct CodaFid destFid;
+     int       destname;
+ };
+@@ -536,14 +534,14 @@
+ /* coda_mkdir: */
+ struct coda_mkdir_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     struct coda_vattr attr;
+     int          name;                /* Place holder for data. */
+ };
+ struct coda_mkdir_out {
+     struct coda_out_hdr oh;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+     struct coda_vattr attr;
+ };
+@@ -551,7 +549,7 @@
+ /* coda_rmdir: NO_OUT */
+ struct coda_rmdir_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int name;         /* Place holder for data. */
+ };
+@@ -562,7 +560,7 @@
+ /* coda_symlink: NO_OUT */
+ struct coda_symlink_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;          /* Directory to put symlink in */
++    struct CodaFid VFid;      /* Directory to put symlink in */
+     int srcname;
+     struct coda_vattr attr;
+     int tname;
+@@ -575,7 +573,7 @@
+ /* coda_readlink: */
+ struct coda_readlink_in {
+     struct coda_in_hdr ih;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+ };
+ struct coda_readlink_out {
+@@ -588,7 +586,7 @@
+ /* coda_fsync: NO_OUT */
+ struct coda_fsync_in {
+     struct coda_in_hdr ih;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+ };
+ struct coda_fsync_out {
+@@ -598,12 +596,12 @@
+ /* coda_vget: */
+ struct coda_vget_in {
+     struct coda_in_hdr ih;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+ };
+ struct coda_vget_out {
+     struct coda_out_hdr oh;
+-    ViceFid VFid;
++    struct CodaFid VFid;
+     int       vtype;
+ };
+@@ -616,50 +614,46 @@
+ /* CODA_PURGEUSER is a venus->kernel call */
+ struct coda_purgeuser_out {
+     struct coda_out_hdr oh;
++#ifdef CODA_FS_OLD_API
+     struct coda_cred cred;
++#else
++    vuid_t uid;
++#endif
+ };
+ /* coda_zapfile: */
+ /* CODA_ZAPFILE is a venus->kernel call */
+ struct coda_zapfile_out {  
+     struct coda_out_hdr oh;
+-    ViceFid CodaFid;
++    struct CodaFid CodaFid;
+ };
+ /* coda_zapdir: */
+ /* CODA_ZAPDIR is a venus->kernel call */     
+ struct coda_zapdir_out {        
+     struct coda_out_hdr oh;
+-    ViceFid CodaFid;
+-};
+-
+-/* coda_zapnode: */
+-/* CODA_ZAPVNODE is a venus->kernel call */   
+-struct coda_zapvnode_out { 
+-    struct coda_out_hdr oh;
+-    struct coda_cred cred;
+-    ViceFid VFid;
++    struct CodaFid CodaFid;
+ };
+ /* coda_purgefid: */
+ /* CODA_PURGEFID is a venus->kernel call */   
+ struct coda_purgefid_out { 
+     struct coda_out_hdr oh;
+-    ViceFid CodaFid;
++    struct CodaFid CodaFid;
+ };
+ /* coda_replace: */
+ /* CODA_REPLACE is a venus->kernel call */    
+ struct coda_replace_out { /* coda_replace is a venus->kernel call */
+     struct coda_out_hdr oh;
+-    ViceFid NewFid;
+-    ViceFid OldFid;
++    struct CodaFid NewFid;
++    struct CodaFid OldFid;
+ };
+ /* coda_open_by_fd: */
+ struct coda_open_by_fd_in {
+     struct coda_in_hdr ih;
+-    ViceFid    VFid;
++    struct CodaFid VFid;
+     int        flags;
+ };
+@@ -675,7 +669,7 @@
+ /* coda_open_by_path: */
+ struct coda_open_by_path_in {
+     struct coda_in_hdr ih;
+-    ViceFid   VFid;
++    struct CodaFid VFid;
+     int       flags;
+ };
+@@ -741,7 +735,6 @@
+     struct coda_purgeuser_out coda_purgeuser;
+     struct coda_zapfile_out coda_zapfile;
+     struct coda_zapdir_out coda_zapdir;
+-    struct coda_zapvnode_out coda_zapvnode;
+     struct coda_purgefid_out coda_purgefid;
+     struct coda_replace_out coda_replace;
+     struct coda_open_by_fd_out coda_open_by_fd;
+@@ -755,7 +748,6 @@
+     struct coda_purgeuser_out purgeuser;
+     struct coda_zapfile_out zapfile;
+     struct coda_zapdir_out zapdir;
+-    struct coda_zapvnode_out zapvnode;
+     struct coda_purgefid_out purgefid;
+     struct coda_replace_out replace;
+ };
+@@ -778,18 +770,9 @@
+         struct ViceIoctl vi;
+ };
+-#define       CODA_CONTROL            ".CONTROL"
+-#define CODA_CONTROLLEN           8
+-#define       CTL_VOL                 -1
+-#define       CTL_VNO                 -1
+-#define       CTL_UNI                 -1
+-#define CTL_INO                 -1
+-#define       CTL_FILE                "/coda/.CONTROL"
+-
+-
+-#define       IS_CTL_FID(fidp)        ((fidp)->Volume == CTL_VOL &&\
+-                               (fidp)->Vnode == CTL_VNO &&\
+-                               (fidp)->Unique == CTL_UNI)
++#define CODA_CONTROL          ".CONTROL"
++#define CODA_CONTROLLEN               8
++#define CTL_INO                       -1
+ /* Data passed to mount */
+Index: linux-2.6.0-test5/include/linux/coda_linux.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_linux.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_linux.h       2003-09-27 11:38:40.891311960 +0800
+@@ -42,26 +42,21 @@
+ int coda_revalidate_inode(struct dentry *);
+ int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+ int coda_setattr(struct dentry *, struct iattr *);
+-int coda_isnullfid(ViceFid *fid);
+ /* global variables */
+ extern int coda_fake_statfs;
+ /* this file:  heloers */
+-static __inline__ struct ViceFid *coda_i2f(struct inode *);
++static __inline__ struct CodaFid *coda_i2f(struct inode *);
+ static __inline__ char *coda_i2s(struct inode *);
+ static __inline__ void coda_flag_inode(struct inode *, int flag);
+-char *coda_f2s(ViceFid *f);
++char *coda_f2s(struct CodaFid *f);
+ int coda_isroot(struct inode *i);
+ int coda_iscontrol(const char *name, size_t length);
+-void coda_load_creds(struct coda_cred *cred);
+ void coda_vattr_to_iattr(struct inode *, struct coda_vattr *);
+ void coda_iattr_to_vattr(struct iattr *, struct coda_vattr *);
+ unsigned short coda_flags_to_cflags(unsigned short);
+-void print_vattr( struct coda_vattr *attr );
+-int coda_cred_ok(struct coda_cred *cred);
+-int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2);
+ /* sysctl.h */
+ void coda_sysctl_init(void);
+@@ -88,7 +83,7 @@
+       return list_entry(inode, struct coda_inode_info, vfs_inode);
+ }
+-static __inline__ struct ViceFid *coda_i2f(struct inode *inode)
++static __inline__ struct CodaFid *coda_i2f(struct inode *inode)
+ {
+       return &(ITOC(inode)->c_fid);
+ }
+Index: linux-2.6.0-test5/include/linux/coda_psdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/coda_psdev.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/coda_psdev.h       2003-09-27 11:38:40.893311656 +0800
+@@ -6,13 +6,11 @@
+ #define CODA_SUPER_MAGIC      0x73757245
+-struct statfs;
++struct kstatfs;
+ struct coda_sb_info
+ {
+-      struct venus_comm * sbi_vcomm;
+-      struct super_block *sbi_sb;
+-      struct list_head    sbi_cihead;
++      struct venus_comm *sbi_vcomm;
+ };
+ /* communication pending/processing queues */
+@@ -33,46 +31,45 @@
+ /* upcalls */
+-int venus_rootfid(struct super_block *sb, ViceFid *fidp);
+-int venus_getattr(struct super_block *sb, struct ViceFid *fid, 
+-                   struct coda_vattr *attr);
+-int venus_setattr(struct super_block *, struct ViceFid *, 
+-                   struct coda_vattr *);
+-int venus_lookup(struct super_block *sb, struct ViceFid *fid, 
+-                  const char *name, int length, int *type, 
+-                  struct ViceFid *resfid);
+-int venus_store(struct super_block *sb, struct ViceFid *fid, int flags,
+-              struct coda_cred *);
+-int venus_release(struct super_block *sb, struct ViceFid *fid, int flags);
+-int venus_close(struct super_block *sb, struct ViceFid *fid, int flags,
+-              struct coda_cred *);
+-int venus_open(struct super_block *sb, struct ViceFid *fid,
+-              int flags, struct file **f);
+-int venus_mkdir(struct super_block *sb, struct ViceFid *dirfid, 
++int venus_rootfid(struct super_block *sb, struct CodaFid *fidp);
++int venus_getattr(struct super_block *sb, struct CodaFid *fid,
++                struct coda_vattr *attr);
++int venus_setattr(struct super_block *, struct CodaFid *, struct coda_vattr *);
++int venus_lookup(struct super_block *sb, struct CodaFid *fid, 
++               const char *name, int length, int *type, 
++               struct CodaFid *resfid);
++int venus_store(struct super_block *sb, struct CodaFid *fid, int flags,
++              vuid_t uid);
++int venus_release(struct super_block *sb, struct CodaFid *fid, int flags);
++int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
++              vuid_t uid);
++int venus_open(struct super_block *sb, struct CodaFid *fid, int flags,
++             struct file **f);
++int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid, 
+               const char *name, int length, 
+-              struct ViceFid *newfid, struct coda_vattr *attrs);
+-int venus_create(struct super_block *sb, struct ViceFid *dirfid, 
++              struct CodaFid *newfid, struct coda_vattr *attrs);
++int venus_create(struct super_block *sb, struct CodaFid *dirfid, 
+                const char *name, int length, int excl, int mode, dev_t rdev,
+-               struct ViceFid *newfid, struct coda_vattr *attrs) ;
+-int venus_rmdir(struct super_block *sb, struct ViceFid *dirfid, 
++               struct CodaFid *newfid, struct coda_vattr *attrs) ;
++int venus_rmdir(struct super_block *sb, struct CodaFid *dirfid, 
+               const char *name, int length);
+-int venus_remove(struct super_block *sb, struct ViceFid *dirfid, 
++int venus_remove(struct super_block *sb, struct CodaFid *dirfid, 
+                const char *name, int length);
+-int venus_readlink(struct super_block *sb, struct ViceFid *fid, 
++int venus_readlink(struct super_block *sb, struct CodaFid *fid, 
+                  char *buffer, int *length);
+-int venus_rename(struct super_block *, struct ViceFid *new_fid, 
+-               struct ViceFid *old_fid, size_t old_length, 
++int venus_rename(struct super_block *, struct CodaFid *new_fid, 
++               struct CodaFid *old_fid, size_t old_length, 
+                size_t new_length, const char *old_name, 
+                const char *new_name);
+-int venus_link(struct super_block *sb, struct ViceFid *fid, 
+-                struct ViceFid *dirfid, const char *name, int len );
+-int venus_symlink(struct super_block *sb, struct ViceFid *fid,
++int venus_link(struct super_block *sb, struct CodaFid *fid, 
++                struct CodaFid *dirfid, const char *name, int len );
++int venus_symlink(struct super_block *sb, struct CodaFid *fid,
+                 const char *name, int len, const char *symname, int symlen);
+-int venus_access(struct super_block *sb, struct ViceFid *fid, int mask);
+-int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
++int venus_access(struct super_block *sb, struct CodaFid *fid, int mask);
++int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
+                unsigned int cmd, struct PioctlData *data);
+ int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb);
+-int venus_fsync(struct super_block *sb, struct ViceFid *fid);
++int venus_fsync(struct super_block *sb, struct CodaFid *fid);
+ int venus_statfs(struct super_block *sb, struct kstatfs *sfs);
+Index: linux-2.6.0-test5/include/linux/compiler-gcc2.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc2.h       2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc2.h    2003-09-27 11:38:40.893311656 +0800
+@@ -0,0 +1,23 @@
++/* Never include this file directly.  Include <linux/compiler.h> instead.  */
++
++/* These definitions are for GCC v2.x.  */
++
++/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
++   a mechanism by which the user can annotate likely branch directions and
++   expect the blocks to be reordered appropriately.  Define __builtin_expect
++   to nothing for earlier compilers.  */
++#include <linux/compiler-gcc.h>
++
++#if __GNUC_MINOR__ < 96
++# define __builtin_expect(x, expected_value) (x)
++#endif
++
++#define __attribute_used__    __attribute__((__unused__))
++
++/*
++ * The attribute `pure' is not implemented in GCC versions earlier
++ * than 2.96.
++ */
++#if __GNUC_MINOR__ >= 96
++# define __attribute_pure__   __attribute__((pure))
++#endif
+Index: linux-2.6.0-test5/include/linux/compiler-gcc3.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc3.h       2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc3.h    2003-09-27 11:38:40.894311504 +0800
+@@ -0,0 +1,22 @@
++/* Never include this file directly.  Include <linux/compiler.h> instead.  */
++
++/* These definitions are for GCC v3.x.  */
++#include <linux/compiler-gcc.h>
++
++#if __GNUC_MINOR__ >= 1
++# define inline               __inline__ __attribute__((always_inline))
++# define __inline__   __inline__ __attribute__((always_inline))
++# define __inline     __inline__ __attribute__((always_inline))
++#endif
++
++#if __GNUC_MINOR__ > 0
++# define __deprecated __attribute__((deprecated))
++#endif
++
++#if __GNUC_MINOR__ >= 3
++# define __attribute_used__   __attribute__((__used__))
++#else
++# define __attribute_used__   __attribute__((__unused__))
++#endif
++
++#define __attribute_pure__    __attribute__((pure))
+Index: linux-2.6.0-test5/include/linux/compiler-gcc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc.h        2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc.h     2003-09-27 11:38:40.894311504 +0800
+@@ -0,0 +1,17 @@
++/* Never include this file directly.  Include <linux/compiler.h> instead.  */
++
++/*
++ * Common definitions for all gcc versions go here.
++ */
++
++
++/* Optimization barrier */
++/* The "volatile" is due to gcc bugs */
++#define barrier() __asm__ __volatile__("": : :"memory")
++
++/* This macro obfuscates arithmetic on a variable address so that gcc
++   shouldn't recognize the original var, and make assumptions about it */
++#define RELOC_HIDE(ptr, off)                                  \
++  ({ unsigned long __ptr;                                     \
++      __asm__ ("" : "=r"(__ptr) : "0"(ptr));                  \
++    (typeof(ptr)) (__ptr + (off)); })
+Index: linux-2.6.0-test5/include/linux/compiler-gcc+.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-gcc+.h       2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-gcc+.h    2003-09-27 11:38:40.894311504 +0800
+@@ -0,0 +1,14 @@
++/* Never include this file directly.  Include <linux/compiler.h> instead.  */
++
++/*
++ * These definitions are for Ueber-GCC: always newer than the latest
++ * version and hence sporting everything plus a kitchen-sink.
++ */
++#include <linux/compiler-gcc.h>
++
++#define inline                        __inline__ __attribute__((always_inline))
++#define __inline__            __inline__ __attribute__((always_inline))
++#define __inline              __inline__ __attribute__((always_inline))
++#define __deprecated          __attribute__((deprecated))
++#define __attribute_used__    __attribute__((__used__))
++#define __attribute_pure__    __attribute__((pure))
+Index: linux-2.6.0-test5/include/linux/compiler.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/compiler.h 2003-09-27 11:38:40.896311200 +0800
+@@ -2,28 +2,36 @@
+ #define __LINUX_COMPILER_H
+ #ifdef __CHECKER__
+-  #define __user      __attribute__((noderef, address_space(1)))
+-  #define __kernel    /* default address space */
++# define __user               __attribute__((noderef, address_space(1)))
++# define __kernel     /* default address space */
+ #else
+-  #define __user
+-  #define __kernel
++# define __user
++# define __kernel
+ #endif
+-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+-#define inline                __inline__ __attribute__((always_inline))
+-#define __inline__    __inline__ __attribute__((always_inline))
+-#define __inline      __inline__ __attribute__((always_inline))
++#if __GNUC__ > 3
++# include <linux/compiler-gcc+.h>     /* catch-all for GCC 4, 5, etc. */
++#elif __GNUC__ == 3
++# include <linux/compiler-gcc3.h>
++#elif __GNUC__ == 2
++# include <linux/compiler-gcc2.h>
++#else
++# error Sorry, your compiler is too old/not recognized.
+ #endif
+-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
+-   a mechanism by which the user can annotate likely branch directions and
+-   expect the blocks to be reordered appropriately.  Define __builtin_expect
+-   to nothing for earlier compilers.  */
+-
+-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
+-#define __builtin_expect(x, expected_value) (x)
++/* Intel compiler defines __GNUC__. So we will overwrite implementations
++ * coming from above header files here
++ */
++#ifdef __INTEL_COMPILER
++# include <linux/compiler-intel.h>
+ #endif
++/*
++ * Generic compiler-dependent macros required for kernel
++ * build go below this comment. Actual compiler/compiler version
++ * specific implementations come from the above header files
++ */
++
+ #define likely(x)     __builtin_expect(!!(x), 1)
+ #define unlikely(x)   __builtin_expect(!!(x), 0)
+@@ -33,10 +41,8 @@
+  * Usage is:
+  *            int __deprecated foo(void)
+  */
+-#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
+-#define __deprecated  __attribute__((deprecated))
+-#else
+-#define __deprecated
++#ifndef __deprecated
++# define __deprecated         /* unimplemented */
+ #endif
+ /*
+@@ -50,10 +56,8 @@
+  * In prior versions of gcc, such functions and data would be emitted, but
+  * would be warned about except with attribute((unused)).
+  */
+-#if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3
+-#define __attribute_used__    __attribute__((__used__))
+-#else
+-#define __attribute_used__    __attribute__((__unused__))
++#ifndef __attribute_used__
++# define __attribute_used__   /* unimplemented */
+ #endif
+ /*
+@@ -65,19 +69,21 @@
+  * elimination and loop optimization just as an arithmetic operator
+  * would be.
+  * [...]
+- * The attribute `pure' is not implemented in GCC versions earlier
+- * than 2.96.
+  */
+-#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || __GNUC__ > 2
+-#define __attribute_pure__    __attribute__((pure))
+-#else
+-#define __attribute_pure__    /* unimplemented */
++#ifndef __attribute_pure__
++# define __attribute_pure__   /* unimplemented */
++#endif
++
++/* Optimization barrier */
++#ifndef barrier
++# define barrier() __memory_barrier()
+ #endif
+-/* This macro obfuscates arithmetic on a variable address so that gcc
+-   shouldn't recognize the original var, and make assumptions about it */
+-#define RELOC_HIDE(ptr, off)                                  \
++#ifndef RELOC_HIDE
++# define RELOC_HIDE(ptr, off)                                 \
+   ({ unsigned long __ptr;                                     \
+-    __asm__ ("" : "=g"(__ptr) : "0"(ptr));            \
++     __ptr = (unsigned long) (ptr);                           \
+     (typeof(ptr)) (__ptr + (off)); })
++#endif
++
+ #endif /* __LINUX_COMPILER_H */
+Index: linux-2.6.0-test5/include/linux/compiler-intel.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/compiler-intel.h      2003-09-27 11:38:18.484718280 +0800
++++ linux-2.6.0-test5/include/linux/compiler-intel.h   2003-09-27 11:38:40.897311048 +0800
+@@ -0,0 +1,24 @@
++/* Never include this file directly.  Include <linux/compiler.h> instead.  */
++
++#ifdef __ECC
++
++/* Some compiler specific definitions are overwritten here
++ * for Intel ECC compiler
++ */
++
++#include <asm/intrinsics.h>
++
++/* Intel ECC compiler doesn't support gcc specific asm stmts.
++ * It uses intrinsics to do the equivalent things.
++ */
++#undef barrier
++#undef RELOC_HIDE
++
++#define barrier() __memory_barrier()
++
++#define RELOC_HIDE(ptr, off)                                  \
++  ({ unsigned long __ptr;                                     \
++     __ptr = (unsigned long) (ptr);                           \
++    (typeof(ptr)) (__ptr + (off)); })
++
++#endif
+Index: linux-2.6.0-test5/include/linux/config.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/config.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/config.h   2003-09-27 11:38:40.898310896 +0800
+@@ -2,5 +2,8 @@
+ #define _LINUX_CONFIG_H
+ #include <linux/autoconf.h>
++#if defined(__i386__) && !defined(IN_BOOTLOADER)
++#include <asm/kgdb.h>
++#endif
+ #endif
+Index: linux-2.6.0-test5/include/linux/console.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/console.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/console.h  2003-09-27 11:38:40.899310744 +0800
+@@ -15,7 +15,6 @@
+ #define _LINUX_CONSOLE_H_ 1
+ #include <linux/types.h>
+-#include <linux/kdev_t.h>
+ #include <linux/spinlock.h>
+ struct vc_data;
+Index: linux-2.6.0-test5/include/linux/cpufreq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/cpufreq.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/cpufreq.h  2003-09-27 11:38:40.903310136 +0800
+@@ -60,6 +60,13 @@
+       unsigned int            transition_latency; /* in 10^(-9) s */
+ };
++struct cpufreq_real_policy {
++      unsigned int            min;    /* in kHz */
++      unsigned int            max;    /* in kHz */
++        unsigned int          policy; /* see above */
++      struct cpufreq_governor *governor; /* see below */
++};
++
+ struct cpufreq_policy {
+       unsigned int            cpu;    /* cpu nr */
+       struct cpufreq_cpuinfo  cpuinfo;/* see above */
+@@ -74,6 +81,8 @@
+       struct semaphore        lock;   /* CPU ->setpolicy or ->target may
+                                          only be called once a time */
++      struct cpufreq_real_policy      user_policy;
++
+       struct kobject          kobj;
+       struct completion       kobj_unregister;
+ };
+@@ -217,6 +226,7 @@
+  *********************************************************************/
+ int cpufreq_set_policy(struct cpufreq_policy *policy);
+ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
++int cpufreq_update_policy(unsigned int cpu);
+ /* the proc_intf.c needs this */
+ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
+@@ -290,7 +300,7 @@
+ #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+ extern struct cpufreq_governor cpufreq_gov_performance;
+ #define CPUFREQ_DEFAULT_GOVERNOR      &cpufreq_gov_performance
+-#elif CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
++#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE)
+ extern struct cpufreq_governor cpufreq_gov_userspace;
+ #define CPUFREQ_DEFAULT_GOVERNOR      &cpufreq_gov_userspace
+ #endif
+Index: linux-2.6.0-test5/include/linux/devfs_fs_kernel.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/devfs_fs_kernel.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/devfs_fs_kernel.h  2003-09-27 11:38:40.904309984 +0800
+@@ -4,7 +4,6 @@
+ #include <linux/fs.h>
+ #include <linux/config.h>
+ #include <linux/spinlock.h>
+-#include <linux/kdev_t.h>
+ #include <linux/types.h>
+ #include <asm/semaphore.h>
+Index: linux-2.6.0-test5/include/linux/dm-ioctl-v1.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dm-ioctl-v1.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/dm-ioctl-v1.h      2003-09-27 11:38:40.906309680 +0800
+@@ -50,7 +50,7 @@
+       uint32_t open_count;    /* out */
+       uint32_t flags;         /* in/out */
+-      __kernel_dev_t dev;     /* in/out */
++      __kernel_old_dev_t dev; /* in/out */
+       char name[DM_NAME_LEN]; /* device name */
+       char uuid[DM_UUID_LEN]; /* unique identifier for
+@@ -87,7 +87,7 @@
+ struct dm_target_deps {
+       uint32_t count;
+-      __kernel_dev_t dev[0];  /* out */
++      __kernel_old_dev_t dev[0];      /* out */
+ };
+ /*
+Index: linux-2.6.0-test5/include/linux/dwarf2.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dwarf2.h      2003-09-27 11:38:18.485718128 +0800
++++ linux-2.6.0-test5/include/linux/dwarf2.h   2003-09-27 11:38:40.908309376 +0800
+@@ -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(};)
++\f
++/* @@@ 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 */
+Index: linux-2.6.0-test5/include/linux/dwarf2-lang.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dwarf2-lang.h 2003-09-27 11:38:18.485718128 +0800
++++ linux-2.6.0-test5/include/linux/dwarf2-lang.h      2003-09-27 11:38:40.909309224 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/linux/eisa.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/eisa.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/eisa.h     2003-09-27 11:38:40.910309072 +0800
+@@ -1,6 +1,19 @@
+ #ifndef _LINUX_EISA_H
+ #define _LINUX_EISA_H
++#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
+Index: linux-2.6.0-test5/include/linux/elevator.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/elevator.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/elevator.h 2003-09-27 11:38:40.913308616 +0800
+@@ -15,7 +15,6 @@
+ 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 *);
+ typedef int (elevator_may_queue_fn) (request_queue_t *, int);
+@@ -95,6 +94,11 @@
+  */
+ 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 *);
+Index: linux-2.6.0-test5/include/linux/elf.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/elf.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/elf.h      2003-09-27 11:38:40.916308160 +0800
+@@ -360,7 +360,8 @@
+ #define       EI_CLASS        4
+ #define       EI_DATA         5
+ #define       EI_VERSION      6
+-#define       EI_PAD          7
++#define       EI_OSABI        7
++#define       EI_PAD          8
+ #define       ELFMAG0         0x7f            /* EI_MAG */
+ #define       ELFMAG1         'E'
+@@ -382,6 +383,13 @@
+ #define EV_CURRENT    1
+ #define EV_NUM                2
++#define ELFOSABI_NONE 0
++#define ELFOSABI_LINUX        3
++
++#ifndef ELF_OSABI
++#define ELF_OSABI ELFOSABI_NONE
++#endif
++
+ /* Notes used in ET_CORE */
+ #define NT_PRSTATUS   1
+ #define NT_PRFPREG    2
+Index: linux-2.6.0-test5/include/linux/errno.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/errno.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/errno.h    2003-09-27 11:38:40.917308008 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/linux/eventpoll.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/eventpoll.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/eventpoll.h        2003-09-27 11:38:40.919307704 +0800
+@@ -48,9 +48,10 @@
+ /* Kernel space functions implementing the user space "epoll" API */
+ asmlinkage long sys_epoll_create(int size);
+-asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+-asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+-                             int timeout);
++asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
++                            struct epoll_event __user *event);
++asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
++                             int maxevents, int timeout);
+ #ifdef CONFIG_EPOLL
+Index: linux-2.6.0-test5/include/linux/fb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/fb.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/fb.h       2003-09-27 11:38:40.925306792 +0800
+@@ -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_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_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 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;
+Index: linux-2.6.0-test5/include/linux/fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/fs.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/fs.h       2003-09-27 11:38:40.939304664 +0800
+@@ -388,6 +388,7 @@
+       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;
+@@ -749,6 +750,11 @@
+ #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.
+@@ -1199,6 +1205,7 @@
+ }
+ extern void invalidate_inode_pages2(struct address_space *mapping);
+ extern void write_inode_now(struct inode *, int);
++extern int do_fdatasync(struct file *);
+ extern int filemap_fdatawrite(struct address_space *);
+ extern int filemap_flush(struct address_space *);
+ extern int filemap_fdatawait(struct address_space *);
+@@ -1392,9 +1399,6 @@
+ extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
+ extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count);
+ extern void simple_release_fs(struct vfsmount **mount, int *count);
+-extern int old_valid_dev(dev_t);
+-extern u16 old_encode_dev(dev_t);
+-extern dev_t old_decode_dev(u16);
+ extern int inode_change_ok(struct inode *, struct iattr *);
+ extern int inode_setattr(struct inode *, struct iattr *);
+Index: linux-2.6.0-test5/include/linux/ftape.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/ftape.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/ftape.h    2003-09-27 11:38:40.942304208 +0800
+@@ -199,8 +199,6 @@
+ #define ABS(a)          ((a) < 0 ? -(a) : (a))
+ #define NR_ITEMS(x)     (int)(sizeof(x)/ sizeof(*x))
+-extern int ftape_init(void);
+-
+ #endif  /* __KERNEL__ */
+ #endif
+Index: linux-2.6.0-test5/include/linux/hugetlb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/hugetlb.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/hugetlb.h  2003-09-27 11:38:40.943304056 +0800
+@@ -98,6 +98,8 @@
+ extern struct file_operations hugetlbfs_file_operations;
+ extern struct vm_operations_struct hugetlb_vm_ops;
+ struct file *hugetlb_zero_setup(size_t);
++int hugetlb_get_quota(struct address_space *mapping);
++void hugetlb_put_quota(struct address_space *mapping);
+ static inline int is_file_hugepages(struct file *file)
+ {
+Index: linux-2.6.0-test5/include/linux/if_frad.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/if_frad.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/if_frad.h  2003-09-27 11:38:40.946303600 +0800
+@@ -191,9 +191,6 @@
+    int               buffer;          /* current buffer for S508 firmware */
+ };
+-int register_frad(const char *name);
+-int unregister_frad(const char *name);
+-
+ extern void dlci_ioctl_set(int (*hook)(unsigned int, void *));
+ #endif /* __KERNEL__ */
+Index: linux-2.6.0-test5/include/linux/init_task.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/init_task.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/init_task.h        2003-09-27 11:38:40.947303448 +0800
+@@ -108,6 +108,7 @@
+       .proc_lock      = SPIN_LOCK_UNLOCKED,                           \
+       .switch_lock    = SPIN_LOCK_UNLOCKED,                           \
+       .journal_info   = NULL,                                         \
++      .io_wait        = NULL,                                         \
+ }
+Index: linux-2.6.0-test5/include/linux/input.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/input.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/input.h    2003-09-27 11:38:40.953302536 +0800
+@@ -751,7 +751,7 @@
+ #define LONG(x) ((x)/BITS_PER_LONG)
+ #define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
+-      ((dev->keycodesize == 1) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
++      ((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
+ #define init_input_dev(dev)   do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
+Index: linux-2.6.0-test5/include/linux/interrupt.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/interrupt.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/interrupt.h        2003-09-27 11:38:40.956302080 +0800
+@@ -3,6 +3,7 @@
+ #define _LINUX_INTERRUPT_H
+ #include <linux/config.h>
++#include <linux/kernel.h>
+ #include <linux/linkage.h>
+ #include <linux/bitops.h>
+ #include <linux/preempt.h>
+Index: linux-2.6.0-test5/include/linux/ipv6.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/ipv6.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/ipv6.h     2003-09-27 11:38:40.958301776 +0800
+@@ -122,6 +122,52 @@
+       struct  in6_addr        daddr;
+ };
++/*
++ * This structure contains configuration options per IPv6 link.
++ */
++struct ipv6_devconf {
++      __s32           forwarding;
++      __s32           hop_limit;
++      __s32           mtu6;
++      __s32           accept_ra;
++      __s32           accept_redirects;
++      __s32           autoconf;
++      __s32           dad_transmits;
++      __s32           rtr_solicits;
++      __s32           rtr_solicit_interval;
++      __s32           rtr_solicit_delay;
++#ifdef CONFIG_IPV6_PRIVACY
++      __s32           use_tempaddr;
++      __s32           temp_valid_lft;
++      __s32           temp_prefered_lft;
++      __s32           regen_max_retry;
++      __s32           max_desync_factor;
++#endif
++      void            *sysctl;
++};
++
++/* index values for the variables in ipv6_devconf */
++enum {
++      DEVCONF_FORWARDING = 0,
++      DEVCONF_HOPLIMIT,
++      DEVCONF_MTU6,
++      DEVCONF_ACCEPT_RA,
++      DEVCONF_ACCEPT_REDIRECTS,
++      DEVCONF_AUTOCONF,
++      DEVCONF_DAD_TRANSMITS,
++      DEVCONF_RTR_SOLICITS,
++      DEVCONF_RTR_SOLICIT_INTERVAL,
++      DEVCONF_RTR_SOLICIT_DELAY,
++#ifdef CONFIG_IPV6_PRIVACY
++      DEVCONF_USE_TEMPADDR,
++      DEVCONF_TEMP_VALID_LFT,
++      DEVCONF_TEMP_PREFERED_LFT,
++      DEVCONF_REGEN_MAX_RETRY,
++      DEVCONF_MAX_DESYNC_FACTOR,
++#endif
++      DEVCONF_MAX
++};
++
+ #ifdef __KERNEL__
+ #include <linux/in6.h>          /* struct sockaddr_in6 */
+ #include <linux/icmpv6.h>
+Index: linux-2.6.0-test5/include/linux/kdev_t.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/kdev_t.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/kdev_t.h   2003-09-27 11:38:40.960301472 +0800
+@@ -1,8 +1,7 @@
+ #ifndef _LINUX_KDEV_T_H
+ #define _LINUX_KDEV_T_H
+ #ifdef __KERNEL__
+-/* These are for user-level "dev_t" */
+-#define MINORBITS     8
++#define MINORBITS     20
+ #define MINORMASK     ((1U << MINORBITS) - 1)
+ #define MAJOR(dev)    ((unsigned int) ((dev) >> MINORBITS))
+@@ -18,6 +17,77 @@
+               buffer;                                                 \
+       })
++/* acceptable for old filesystems */
++static inline int old_valid_dev(dev_t dev)
++{
++      return MAJOR(dev) < 256 && MINOR(dev) < 256;
++}
++
++static inline u16 old_encode_dev(dev_t dev)
++{
++      return (MAJOR(dev) << 8) | MINOR(dev);
++}
++
++static inline dev_t old_decode_dev(u16 val)
++{
++      return MKDEV((val >> 8) & 255, val & 255);
++}
++
++static inline int new_valid_dev(dev_t dev)
++{
++      return 1;
++}
++
++static inline u32 new_encode_dev(dev_t dev)
++{
++      unsigned major = MAJOR(dev);
++      unsigned minor = MINOR(dev);
++      return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
++}
++
++static inline dev_t new_decode_dev(u32 dev)
++{
++      unsigned major = (dev & 0xfff00) >> 8;
++      unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
++      return MKDEV(major, minor);
++}
++
++static inline int huge_valid_dev(dev_t dev)
++{
++      return 1;
++}
++
++static inline u64 huge_encode_dev(dev_t dev)
++{
++      return new_encode_dev(dev);
++}
++
++static inline dev_t huge_decode_dev(u64 dev)
++{
++      return new_decode_dev(dev);
++}
++
++static inline int sysv_valid_dev(dev_t dev)
++{
++      return MAJOR(dev) < (1<<14) && MINOR(dev) < (1<<18);
++}
++
++static inline u32 sysv_encode_dev(dev_t dev)
++{
++      return MINOR(dev) | (MAJOR(dev) << 18);
++}
++
++static inline unsigned sysv_major(u32 dev)
++{
++      return (dev >> 18) & 0x3fff;
++}
++
++static inline unsigned sysv_minor(u32 dev)
++{
++      return dev & 0x3ffff;
++}
++
++
+ #else /* __KERNEL__ */
+ /*
+Index: linux-2.6.0-test5/include/linux/kernel.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/kernel.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/kernel.h   2003-09-27 11:38:40.962301168 +0800
+@@ -15,10 +15,6 @@
+ #include <asm/byteorder.h>
+ #include <asm/bug.h>
+-/* Optimization barrier */
+-/* The "volatile" is due to gcc bugs */
+-#define barrier() __asm__ __volatile__("": : :"memory")
+-
+ #define INT_MAX               ((int)(~0U>>1))
+ #define INT_MIN               (-INT_MAX - 1)
+ #define UINT_MAX      (~0U)
+Index: linux-2.6.0-test5/include/linux/linux_logo.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/linux_logo.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/linux_logo.h       2003-09-27 11:38:40.964300864 +0800
+@@ -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 @@
+       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 */
+Index: linux-2.6.0-test5/include/linux/list.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/list.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/list.h     2003-09-27 11:38:40.969300104 +0800
+@@ -142,8 +142,11 @@
+  * 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;
+Index: linux-2.6.0-test5/include/linux/llc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/llc.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/llc.h      2003-09-27 11:38:40.971299800 +0800
+@@ -79,13 +79,5 @@
+ #define LLC_SAP_DYN_TRIES     4
+ #define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
+-
+-#ifdef CONFIG_LLC_UI
+-extern int llc_ui_init(void);
+-extern void llc_ui_exit(void);
+-#else
+-#define llc_ui_init()
+-#define llc_ui_exit()
+-#endif
+ #endif /* __KERNEL__ */
+ #endif /* __LINUX_LLC_H */
+Index: linux-2.6.0-test5/include/linux/lockmeter.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/lockmeter.h   2003-09-27 11:38:18.485718128 +0800
++++ linux-2.6.0-test5/include/linux/lockmeter.h        2003-09-27 11:38:40.972299648 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/linux/major.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/major.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/major.h    2003-09-27 11:38:40.974299344 +0800
+@@ -40,7 +40,7 @@
+ #define MFM_ACORN_MAJOR               21      /* ARM Linux /dev/mfm */
+ #define SCSI_GENERIC_MAJOR    21
+ #define IDE1_MAJOR            22
+-#define DIGICU_MAJOR          22
++#define DIGI_DGAP_MAJOR               22
+ #define DIGI_MAJOR            23
+ #define MITSUMI_CDROM_MAJOR   23
+ #define CDU535_CDROM_MAJOR    24
+@@ -160,34 +160,4 @@
+ #define IBM_TTY3270_MAJOR     227
+ #define IBM_FS3270_MAJOR      228
+-/*
+- * Tests for SCSI devices.
+- */
+-
+-#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
+-  ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) || \
+-  ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
+-  
+-#define SCSI_BLK_MAJOR(M) \
+-  (SCSI_DISK_MAJOR(M) \
+-   || (M) == SCSI_CDROM_MAJOR)
+-
+-static __inline__ int scsi_blk_major(int m) {
+-      return SCSI_BLK_MAJOR(m);
+-}
+-
+-/*
+- * Tests for IDE devices
+- */
+-#define IDE_DISK_MAJOR(M)     ((M) == IDE0_MAJOR || (M) == IDE1_MAJOR || \
+-                              (M) == IDE2_MAJOR || (M) == IDE3_MAJOR || \
+-                              (M) == IDE4_MAJOR || (M) == IDE5_MAJOR || \
+-                              (M) == IDE6_MAJOR || (M) == IDE7_MAJOR || \
+-                              (M) == IDE8_MAJOR || (M) == IDE9_MAJOR)
+-
+-static __inline__ int ide_blk_major(int m)
+-{
+-      return IDE_DISK_MAJOR(m);
+-}
+-
+ #endif
+Index: linux-2.6.0-test5/include/linux/miscdevice.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/miscdevice.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/miscdevice.h       2003-09-27 11:38:40.976299040 +0800
+@@ -36,14 +36,12 @@
+ #define TUN_MINOR          200
+-extern int misc_init(void);
+-
+ struct miscdevice 
+ {
+       int minor;
+       const char *name;
+       struct file_operations *fops;
+-      struct miscdevice * next, * prev;
++      struct list_head list;
+       char devfs_name[64];
+ };
+Index: linux-2.6.0-test5/include/linux/mm.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/mm.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/mm.h       2003-09-27 11:38:40.982298128 +0800
+@@ -323,7 +323,6 @@
+  * 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;
+@@ -432,6 +431,7 @@
+ 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));
+ extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
++extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, 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);
+ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+Index: linux-2.6.0-test5/include/linux/mmzone.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/mmzone.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/mmzone.h   2003-09-27 11:38:40.986297520 +0800
+@@ -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 @@
+ #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);
+Index: linux-2.6.0-test5/include/linux/mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/mount.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/mount.h    2003-09-27 11:38:40.988297216 +0800
+@@ -14,9 +14,10 @@
+ #include <linux/list.h>
+-#define MNT_NOSUID    1
+-#define MNT_NODEV     2
+-#define MNT_NOEXEC    4
++#define MNT_RDONLY    1
++#define MNT_NOSUID    2
++#define MNT_NODEV     4
++#define MNT_NOEXEC    8
+ struct vfsmount
+ {
+@@ -33,6 +34,8 @@
+       struct list_head mnt_list;
+ };
++#define       MNT_IS_RDONLY(m)        ((m)->mnt_flags & MNT_RDONLY)
++
+ static inline struct vfsmount *mntget(struct vfsmount *mnt)
+ {
+       if (mnt)
+Index: linux-2.6.0-test5/include/linux/netdevice.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/netdevice.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/netdevice.h        2003-09-27 11:38:40.995296152 +0800
+@@ -28,8 +28,6 @@
+ #include <linux/if.h>
+ #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>
+@@ -37,6 +35,8 @@
+ #ifdef __KERNEL__
+ #include <linux/config.h>
++#include <linux/device.h>
++#include <linux/percpu.h>
+ struct divert_blk;
+ struct vlan_group;
+@@ -456,6 +456,13 @@
+       /* 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. */
+@@ -502,7 +509,11 @@
+ extern void           dev_add_pack(struct packet_type *pt);
+ extern void           dev_remove_pack(struct packet_type *pt);
+ extern void           __dev_remove_pack(struct packet_type *pt);
+-extern int            dev_get(const char *name);
++extern int            __dev_get(const char *name);
++static inline int __deprecated dev_get(const char *name)
++{
++      return __dev_get(name);
++}
+ extern struct net_device      *dev_get_by_flags(unsigned short flags,
+                                                 unsigned short mask);
+ extern struct net_device      *__dev_get_by_flags(unsigned short flags,
+@@ -525,6 +536,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
++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);
+@@ -583,12 +599,22 @@
+ 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);
+ }
+Index: linux-2.6.0-test5/include/linux/netfilter_ipv4/ipt_physdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/netfilter_ipv4/ipt_physdev.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/netfilter_ipv4/ipt_physdev.h       2003-09-27 11:38:40.996296000 +0800
+@@ -13,12 +13,12 @@
+ #define IPT_PHYSDEV_OP_MASK           (0x20 - 1)
+ struct ipt_physdev_info {
+-      u_int8_t invert;
+-      u_int8_t bitmask;
+       char physindev[IFNAMSIZ];
+       char in_mask[IFNAMSIZ];
+       char physoutdev[IFNAMSIZ];
+       char out_mask[IFNAMSIZ];
++      u_int8_t invert;
++      u_int8_t bitmask;
+ };
+ #endif /*_IPT_PHYSDEV_H*/
+Index: linux-2.6.0-test5/include/linux/nfsd/export.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfsd/export.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfsd/export.h      2003-09-27 11:38:40.998295696 +0800
+@@ -65,7 +65,7 @@
+       struct auth_domain *    ek_client;
+       int                     ek_fsidtype;
+-      u32                     ek_fsid[2];
++      u32                     ek_fsid[3];
+       struct svc_export *     ek_export;
+ };
+Index: linux-2.6.0-test5/include/linux/nfsd/nfsd.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfsd/nfsd.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfsd/nfsd.h        2003-09-27 11:38:41.001295240 +0800
+@@ -15,6 +15,7 @@
+ #include <linux/unistd.h>
+ #include <linux/dirent.h>
+ #include <linux/fs.h>
++#include <linux/mount.h>
+ #include <linux/nfsd/debug.h>
+ #include <linux/nfsd/nfsfh.h>
+@@ -207,6 +208,17 @@
+  */
+ extern struct timeval nfssvc_boot;
++static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
++{
++      if (fh->fh_export->ex_flags & NFSEXP_FSID) {
++              struct vfsmount *mnt = fh->fh_export->ex_mnt;
++              if (!old_valid_dev(mnt->mnt_sb->s_dev) ||
++                  (reffh->fh_version == 1 && reffh->fh_fsid_type == 1))
++                      return 1;
++      }
++      return 0;
++}
++
+ #ifdef CONFIG_NFSD_V4
+Index: linux-2.6.0-test5/include/linux/nfsd/nfsfh.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfsd/nfsfh.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfsd/nfsfh.h       2003-09-27 11:38:41.005294632 +0800
+@@ -117,26 +117,6 @@
+ #ifdef __KERNEL__
+-/*
+- * Conversion macros for the filehandle fields.
+- *
+- * Keep the device numbers in "backwards compatible
+- * format", ie the low 16 bits contain the low 8 bits
+- * of the 20-bit minor and the 12-bit major number.
+- *
+- * The high 16 bits contain the rest (4 bits major
+- * and 12 bits minor),
+- */
+-
+-static inline dev_t u32_to_dev_t(__u32 udev)
+-{
+-      unsigned int minor, major;
+-
+-      minor = (udev & 0xff) | ((udev >> 8) & 0xfff00);
+-      major = ((udev >> 8) & 0xff) | ((udev >> 20) & 0xf00);
+-      return MKDEV(major, minor);
+-}
+-
+ static inline __u32 ino_t_to_u32(ino_t ino)
+ {
+       return (__u32) ino;
+@@ -196,6 +176,12 @@
+       fsidv[0] = fsid;
+ }
++static inline void mk_fsid_v2(u32 *fsidv, dev_t dev, ino_t ino)
++{
++      fsidv[0] = htonl(MAJOR(dev));
++      fsidv[1] = htonl(MINOR(dev));
++      fsidv[2] = ino_t_to_u32(ino);
++}
+ /*
+  * Shorthand for dprintk()'s
+Index: linux-2.6.0-test5/include/linux/nfs_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfs_fs.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfs_fs.h   2003-09-27 11:38:41.009294024 +0800
+@@ -271,7 +271,7 @@
+ /*
+  * 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);
+ /*
+Index: linux-2.6.0-test5/include/linux/nfs_page.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfs_page.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfs_page.h 2003-09-27 11:38:41.011293720 +0800
+@@ -46,7 +46,6 @@
+                                           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_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;
+Index: linux-2.6.0-test5/include/linux/nfs_xdr.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nfs_xdr.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nfs_xdr.h  2003-09-27 11:38:41.016292960 +0800
+@@ -591,6 +591,7 @@
+ #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_write_data {
++      int                     flags;
+       struct rpc_task         task;
+       struct inode            *inode;
+       struct rpc_cred         *cred;
+@@ -634,16 +636,9 @@
+                           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 *);
+Index: linux-2.6.0-test5/include/linux/nls.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/nls.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/nls.h      2003-09-27 11:38:41.017292808 +0800
+@@ -8,6 +8,7 @@
+ struct nls_table {
+       char *charset;
++      char *alias;
+       int (*uni2char) (wchar_t uni, unsigned char *out, int boundlen);
+       int (*char2uni) (const unsigned char *rawstring, int boundlen,
+                        wchar_t *uni);
+@@ -32,5 +33,7 @@
+ extern int utf8_wctomb(__u8 *, wchar_t, int);
+ extern int utf8_wcstombs(__u8 *, const wchar_t *, int);
++#define MODULE_ALIAS_NLS(name)        MODULE_ALIAS("nls_" __stringify(name))
++
+ #endif /* _LINUX_NLS_H */
+Index: linux-2.6.0-test5/include/linux/numa.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/numa.h        2003-09-27 11:38:18.486717976 +0800
++++ linux-2.6.0-test5/include/linux/numa.h     2003-09-27 11:38:41.018292656 +0800
+@@ -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 */
+Index: linux-2.6.0-test5/include/linux/pagemap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pagemap.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pagemap.h  2003-09-27 11:38:41.020292352 +0800
+@@ -71,7 +71,7 @@
+ 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 @@
+ 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 @@
+  * 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);
+Index: linux-2.6.0-test5/include/linux/pagevec.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pagevec.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pagevec.h  2003-09-27 11:38:41.022292048 +0800
+@@ -23,7 +23,7 @@
+ 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)
+ {
+Index: linux-2.6.0-test5/include/linux/parser.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/parser.h      2003-09-27 11:38:18.486717976 +0800
++++ linux-2.6.0-test5/include/linux/parser.h   2003-09-27 11:38:41.022292048 +0800
+@@ -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 *);
+Index: linux-2.6.0-test5/include/linux/pci_ids.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pci_ids.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pci_ids.h  2003-09-27 11:38:41.043288856 +0800
+@@ -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
+@@ -1060,6 +1061,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
+Index: linux-2.6.0-test5/include/linux/pnpbios.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/pnpbios.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/pnpbios.h  2003-09-27 11:38:41.045288552 +0800
+@@ -26,7 +26,7 @@
+ #ifdef __KERNEL__
+ #include <linux/types.h>
+-#include <linux/pci.h>
++#include <linux/pnp.h>
+ /*
+  * Return codes
+@@ -131,13 +131,7 @@
+ #ifdef CONFIG_PNPBIOS
+ /* non-exported */
+-extern int  pnpbios_dont_use_current_config;
+ extern struct pnp_dev_node_info node_info;
+-extern void *pnpbios_kmalloc(size_t size, int f);
+-extern int pnpbios_init (void);
+-extern int pnpbios_interface_attach_device(struct pnp_bios_node * node);
+-extern int pnpbios_proc_init (void);
+-extern void pnpbios_proc_exit (void);
+ extern int pnp_bios_dev_node_info (struct pnp_dev_node_info *data);
+ extern int pnp_bios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data);
+Index: linux-2.6.0-test5/include/linux/proc_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/proc_fs.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/proc_fs.h  2003-09-27 11:38:41.048288096 +0800
+@@ -185,9 +185,10 @@
+ #else
+ #define proc_root_driver NULL
+-#define proc_net_fops_create(name,mode,fops) do {} while(0)
+-static inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode, 
+-      get_info_t *get_info) {return NULL;}
++#define proc_net NULL
++
++#define proc_net_fops_create(name, mode, fops)  ({ (void)(mode), NULL; })
++#define proc_net_create(name, mode, info)     ({ (void)(mode), NULL; })
+ static inline void proc_net_remove(const char *name) {}
+ static inline struct dentry *proc_pid_unhash(struct task_struct *p) { return NULL; }
+Index: linux-2.6.0-test5/include/linux/raid/md_k.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/raid/md_k.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/raid/md_k.h        2003-09-27 11:38:41.051287640 +0800
+@@ -64,11 +64,7 @@
+ 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:
+Index: linux-2.6.0-test5/include/linux/random.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/random.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/random.h   2003-09-27 11:38:41.053287336 +0800
+@@ -42,7 +42,6 @@
+ #ifdef __KERNEL__
+-extern void rand_initialize(void);
+ extern void rand_initialize_irq(int irq);
+ extern void batch_entropy_store(u32 a, u32 b, int num);
+Index: linux-2.6.0-test5/include/linux/reiserfs_fs.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/reiserfs_fs.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/reiserfs_fs.h      2003-09-27 11:38:41.076283840 +0800
+@@ -1931,32 +1931,13 @@
+ int reiserfs_proc_info_init( struct super_block *sb );
+ int reiserfs_proc_info_done( struct super_block *sb );
+-struct proc_dir_entry *reiserfs_proc_register( struct super_block *sb, 
+-                                                                                         char *name, read_proc_t *func );
+-void reiserfs_proc_unregister( struct super_block *sb, const char *name );
+ struct proc_dir_entry *reiserfs_proc_register_global( char *name, 
+                                                                                                         read_proc_t *func );
+ void reiserfs_proc_unregister_global( const char *name );
+ int reiserfs_proc_info_global_init( void );
+ int reiserfs_proc_info_global_done( void );
+-int reiserfs_proc_tail( int len, char *buffer, char **start, 
+-                                              off_t offset, int count, int *eof );
+ int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset,
+                                                                        int count, int *eof, void *data );
+-int reiserfs_version_in_proc( char *buffer, char **start, off_t offset,
+-                                                        int count, int *eof, void *data );
+-int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
+-                                                      int count, int *eof, void *data );
+-int reiserfs_per_level_in_proc( char *buffer, char **start, off_t offset,
+-                                                              int count, int *eof, void *data );
+-int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset,
+-                                                              int count, int *eof, void *data );
+-int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
+-                                                                      int count, int *eof, void *data );
+-int reiserfs_oidmap_in_proc( char *buffer, char **start, off_t offset,
+-                                                       int count, int *eof, void *data );
+-int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
+-                                                        int count, int *eof, void *data );
+ #if defined( REISERFS_PROC_INFO )
+Index: linux-2.6.0-test5/include/linux/reiserfs_fs_sb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/reiserfs_fs_sb.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/reiserfs_fs_sb.h   2003-09-27 11:38:41.082282928 +0800
+@@ -468,7 +468,7 @@
+ void reiserfs_file_buffer (struct buffer_head * bh, int list);
+-int is_reiserfs_super(struct super_block *s)  ;
++extern struct file_system_type reiserfs_fs_type;
+ int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ;
+ int flush_old_commits(struct super_block *s, int) ;
+ int show_reiserfs_locks(void) ;
+Index: linux-2.6.0-test5/include/linux/rtnetlink.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/rtnetlink.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/rtnetlink.h        2003-09-27 11:38:41.088282016 +0800
+@@ -508,10 +508,12 @@
+ #define IFLA_MASTER IFLA_MASTER
+       IFLA_WIRELESS,          /* Wireless Extension event - see wireless.h */
+ #define IFLA_WIRELESS IFLA_WIRELESS
++      IFLA_PROTINFO,          /* Protocol specific information for a link */
++#define IFLA_PROTINFO IFLA_PROTINFO
+ };
+-#define IFLA_MAX IFLA_WIRELESS
++#define IFLA_MAX IFLA_PROTINFO
+ #define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+ #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+@@ -545,6 +547,18 @@
+    for IPIP tunnels, when route to endpoint is allowed to change)
+  */
++/* Subtype attributes for IFLA_PROTINFO */
++enum
++{
++      IFLA_INET6_UNSPEC,
++      IFLA_INET6_FLAGS,       /* link flags                   */
++      IFLA_INET6_CONF,        /* sysctl parameters            */
++      IFLA_INET6_STATS,       /* statistics                   */
++      IFLA_INET6_MCAST,       /* MC things. What of them?     */
++};
++
++#define IFLA_INET6_MAX        IFLA_INET6_MCAST
++
+ /*****************************************************************
+  *            Traffic control messages.
+  ****/
+Index: linux-2.6.0-test5/include/linux/sched.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/sched.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/sched.h    2003-09-27 11:38:41.095280952 +0800
+@@ -151,6 +151,7 @@
+ 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
+@@ -281,7 +282,9 @@
+ #define MAX_RT_PRIO           MAX_USER_RT_PRIO
+ #define MAX_PRIO              (MAX_RT_PRIO + 40)
+- 
++
++#define rt_task(p)            ((p)->prio < MAX_RT_PRIO)
++
+ /*
+  * Some day this will be a full-fledged user tracking system..
+  */
+@@ -340,7 +343,9 @@
+       prio_array_t *array;
+       unsigned long sleep_avg;
+-      unsigned long last_run;
++      long interactive_credit;
++      unsigned long long timestamp;
++      int activated;
+       unsigned long policy;
+       cpumask_t cpus_allowed;
+@@ -360,7 +365,7 @@
+       unsigned long personality;
+       int did_exec:1;
+       pid_t pid;
+-      pid_t pgrp;
++      pid_t __pgrp;           /* Accessed via process_group() */
+       pid_t tty_old_pgrp;
+       pid_t session;
+       pid_t tgid;
+@@ -375,7 +380,7 @@
+       struct task_struct *parent;     /* parent process */
+       struct list_head children;      /* list of my children */
+       struct list_head sibling;       /* linkage in my parent's children list */
+-      struct task_struct *group_leader;
++      struct task_struct *group_leader;       /* threadgroup leader */
+       /* PID/PID hash table linkage. */
+       struct pid_link pids[PIDTYPE_MAX];
+@@ -459,8 +464,20 @@
+       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;
++}
++
+ 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) \
+@@ -499,6 +516,8 @@
+ }
+ #endif
++extern unsigned long long sched_clock(void);
++
+ #ifdef CONFIG_NUMA
+ extern void sched_balance_exec(void);
+ extern void node_nr_running_init(void);
+Index: linux-2.6.0-test5/include/linux/seq_file.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/seq_file.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/seq_file.h 2003-09-27 11:38:41.097280648 +0800
+@@ -65,5 +65,8 @@
+ int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
+ int single_release(struct inode *, struct file *);
+ int seq_release_private(struct inode *, struct file *);
++
++#define SEQ_START_TOKEN ((void *)1)
++
+ #endif
+ #endif
+Index: linux-2.6.0-test5/include/linux/serial_core.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/serial_core.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/serial_core.h      2003-09-27 11:38:41.100280192 +0800
+@@ -67,6 +67,12 @@
+ #define PORT_PC9861   45
+ #define PORT_PC9801_101       46
++/* DZ */
++#define PORT_DZ               47
++
++/* Parisc type numbers. */
++#define PORT_MUX      48
++
+ /* Macintosh Zilog type numbers */
+ #define PORT_MAC_ZILOG        50      /* m68k : not yet implemented */
+ #define PORT_PMAC_ZILOG       51
+@@ -152,7 +158,9 @@
+       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)
+@@ -319,8 +327,8 @@
+ /*
+  * Power Management
+  */
+-int uart_suspend_port(struct uart_driver *reg, struct uart_port *port, u32 level);
+-int uart_resume_port(struct uart_driver *reg, struct uart_port *port, u32 level);
++int uart_suspend_port(struct uart_driver *reg, struct uart_port *port);
++int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
+ #define uart_circ_empty(circ)         ((circ)->head == (circ)->tail)
+ #define uart_circ_clear(circ)         ((circ)->head = (circ)->tail = 0)
+Index: linux-2.6.0-test5/include/linux/serio.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/serio.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/serio.h    2003-09-27 11:38:41.102279888 +0800
+@@ -65,7 +65,9 @@
+ 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_unregister_port(struct serio *serio);
++void serio_unregister_slave_port(struct serio *serio);
+ void serio_register_device(struct serio_dev *dev);
+ void serio_unregister_device(struct serio_dev *dev);
+@@ -104,6 +106,7 @@
+ #define SERIO_RS232   0x02000000UL
+ #define SERIO_HIL_MLC 0x03000000UL
+ #define SERIO_PC9800  0x04000000UL
++#define SERIO_PS_PSTHRU       0x05000000UL
+ #define SERIO_PROTO   0xFFUL
+ #define SERIO_MSC     0x01
+Index: linux-2.6.0-test5/include/linux/skbuff.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/skbuff.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/skbuff.h   2003-09-27 11:38:41.111278520 +0800
+@@ -306,7 +306,7 @@
+  *
+  *    Returns true if the queue is empty, false otherwise.
+  */
+-static inline int skb_queue_empty(struct sk_buff_head *list)
++static inline int skb_queue_empty(const struct sk_buff_head *list)
+ {
+       return list->next == (struct sk_buff *)list;
+ }
+@@ -357,7 +357,7 @@
+  *    one of multiple shared copies of the buffer. Cloned buffers are
+  *    shared data so must not be written to under normal circumstances.
+  */
+-static inline int skb_cloned(struct sk_buff *skb)
++static inline int skb_cloned(const struct sk_buff *skb)
+ {
+       return skb->cloned && atomic_read(&skb_shinfo(skb)->dataref) != 1;
+ }
+@@ -369,7 +369,7 @@
+  *    Returns true if more than one person has a reference to this
+  *    buffer.
+  */
+-static inline int skb_shared(struct sk_buff *skb)
++static inline int skb_shared(const struct sk_buff *skb)
+ {
+       return atomic_read(&skb->users) != 1;
+ }
+@@ -477,7 +477,7 @@
+  *
+  *    Return the length of an &sk_buff queue.
+  */
+-static inline __u32 skb_queue_len(struct sk_buff_head *list_)
++static inline __u32 skb_queue_len(const struct sk_buff_head *list_)
+ {
+       return list_->qlen;
+ }
+Index: linux-2.6.0-test5/include/linux/smb_mount.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/smb_mount.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/smb_mount.h        2003-09-27 11:38:41.112278368 +0800
+@@ -43,11 +43,11 @@
+ struct smb_mount_data_kernel {
+       int version;
+-      __kernel_uid_t mounted_uid;     /* Who may umount() this filesystem? */
+-      __kernel_uid_t uid;
+-      __kernel_gid_t gid;
+-      __kernel_mode_t file_mode;
+-      __kernel_mode_t dir_mode;
++      uid_t mounted_uid;      /* Who may umount() this filesystem? */
++      uid_t uid;
++      gid_t gid;
++      mode_t file_mode;
++      mode_t dir_mode;
+       u32 flags;
+Index: linux-2.6.0-test5/include/linux/spinlock.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/spinlock.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/spinlock.h 2003-09-27 11:38:41.116277760 +0800
+@@ -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 @@
+       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 @@
+               (x)->module = __FILE__; \
+               (x)->owner = NULL; \
+               (x)->oline = 0; \
++                SET_WHO(x, NULL) \
+       } while (0)
+ #define CHECK_LOCK(x) \
+@@ -88,6 +98,7 @@
+               (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 @@
+               (x)->lock = 1; \
+               (x)->owner = __FILE__; \
+               (x)->oline = __LINE__; \
++                SET_WHO(x, current)       \
+               1; \
+       })
+@@ -184,6 +196,17 @@
+ #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 @@
+                               _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>
+Index: linux-2.6.0-test5/include/linux/suspend.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/suspend.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/suspend.h  2003-09-27 11:38:41.118277456 +0800
+@@ -10,7 +10,7 @@
+ #include <linux/init.h>
+ #include <linux/pm.h>
+-#ifdef CONFIG_SOFTWARE_SUSPEND
++#ifdef CONFIG_PM
+ /* page backup entry */
+ typedef struct pbe {
+       unsigned long address;          /* address of the copy */
+@@ -53,10 +53,17 @@
+ extern void do_suspend_lowlevel(int resume);
+ extern void do_suspend_lowlevel_s4bios(int resume);
++#endif /* CONFIG_PM */
++
++#ifdef CONFIG_SOFTWARE_SUSPEND
++
++extern unsigned char software_suspend_enabled;
++
++extern void software_suspend(void);
+ #else /* CONFIG_SOFTWARE_SUSPEND */
+-static inline int software_suspend(void)
++static inline void software_suspend(void)
+ {
+-      return -EPERM;
++      printk("Warning: fake suspend called\n");
+ }
+ #endif        /* CONFIG_SOFTWARE_SUSPEND */
+Index: linux-2.6.0-test5/include/linux/swap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/swap.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/swap.h     2003-09-27 11:38:41.121277000 +0800
+@@ -3,7 +3,6 @@
+ #include <linux/config.h>
+ #include <linux/spinlock.h>
+-#include <linux/kdev_t.h>
+ #include <linux/linkage.h>
+ #include <linux/mmzone.h>
+ #include <linux/list.h>
+Index: linux-2.6.0-test5/include/linux/tty.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/tty.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/tty.h      2003-09-27 11:38:41.125276392 +0800
+@@ -264,7 +264,6 @@
+       char name[64];
+       int pgrp;
+       int session;
+-      dev_t   device;
+       unsigned long flags;
+       int count;
+       struct winsize winsize;
+@@ -351,7 +350,6 @@
+ extern int lp_init(void);
+ extern int pty_init(void);
+-extern void tty_init(void);
+ extern int mxser_init(void);
+ extern int moxa_init(void);
+ extern int ip2_init(void);
+@@ -420,5 +418,10 @@
+ extern int vt_ioctl(struct tty_struct *tty, struct file * file,
+                   unsigned int cmd, unsigned long arg);
++static inline dev_t tty_devnum(struct tty_struct *tty)
++{
++      return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
++}
++
+ #endif /* __KERNEL__ */
+ #endif
+Index: linux-2.6.0-test5/include/linux/types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/types.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/types.h    2003-09-27 11:38:41.127276088 +0800
+@@ -17,6 +17,8 @@
+ #ifndef __KERNEL_STRICT_NAMES
++typedef __u32 __kernel_dev_t;
++
+ typedef __kernel_fd_set               fd_set;
+ typedef __kernel_dev_t                dev_t;
+ typedef __kernel_ino_t                ino_t;
+Index: linux-2.6.0-test5/include/linux/usb_gadget.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/usb_gadget.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/usb_gadget.h       2003-09-27 11:38:41.134275024 +0800
+@@ -72,9 +72,9 @@
+       unsigned                length;
+       dma_addr_t              dma;
+-      unsigned                no_interrupt : 1,
+-                              zero : 1,
+-                              short_not_ok : 1;
++      unsigned                no_interrupt:1;
++      unsigned                zero:1;
++      unsigned                short_not_ok:1;
+       void                    (*complete)(struct usb_ep *ep,
+                                       struct usb_request *req);
+@@ -122,9 +122,11 @@
+ /**
+  * struct usb_ep - device side representation of USB endpoint
+  * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk"
++ * @ops: Function pointers used to access hardware-specific operations.
+  * @ep_list:the gadget's ep_list holds all of its endpoints
+- * @maxpacket:the maximum packet size used on this endpoint, as
+- *    configured when the endpoint was enabled.
++ * @maxpacket:The maximum packet size used on this endpoint.  The initial
++ *    value can sometimes be reduced (hardware allowing), according to
++ *      the endpoint descriptor used to configure the endpoint.
+  * @driver_data:for use by the gadget driver.  all other fields are
+  *    read-only to gadget drivers.
+  *
+@@ -138,7 +140,7 @@
+       const char              *name;
+       const struct usb_ep_ops *ops;
+       struct list_head        ep_list;
+-      unsigned                maxpacket : 16;
++      unsigned                maxpacket:16;
+ };
+ /*-------------------------------------------------------------------------*/
+@@ -443,18 +445,21 @@
+ /**
+  * struct usb_gadget - represents a usb slave device
++ * @ops: Function pointers used to access hardware-specific operations.
+  * @ep0: Endpoint zero, used when reading or writing responses to
+  *    driver setup() requests
+  * @ep_list: List of other endpoints supported by the device.
+  * @speed: Speed of current connection to USB host.
+  * @name: Identifies the controller hardware type.  Used in diagnostics
+  *    and sometimes configuration.
++ * @dev: Driver model state for this abstract device.
+  *
+  * Gadgets have a mostly-portable "gadget driver" implementing device
+- * functions, handling all usb configurations and interfaces.  They
+- * also have a hardware-specific driver (accessed through ops vectors),
+- * which insulates the gadget driver from hardware details and packages
+- * the hardware endpoints through generic i/o queues.
++ * functions, handling all usb configurations and interfaces.  Gadget
++ * drivers talk to hardware-specific code indirectly, through ops vectors.
++ * That insulates the gadget driver from hardware details, and packages
++ * the hardware endpoints through generic i/o queues.  The "usb_gadget"
++ * and "usb_ep" interfaces provide that insulation from the hardware.
+  *
+  * Except for the driver data, all fields in this structure are
+  * read-only to the gadget driver.  That driver data is part of the
+@@ -469,10 +474,6 @@
+       struct list_head                ep_list;        /* of usb_ep */
+       enum usb_device_speed           speed;
+       const char                      *name;
+-
+-      /* use this to allocate dma-coherent buffers or set up
+-       * dma mappings.  or print diagnostics, etc.
+-       */
+       struct device                   dev;
+ };
+@@ -576,6 +577,7 @@
+  *    Called in a context that permits sleeping.
+  * @suspend: Invoked on USB suspend.  May be called in_interrupt.
+  * @resume: Invoked on USB resume.  May be called in_interrupt.
++ * @driver: Driver model state for this driver.
+  *
+  * Devices are disabled till a gadget driver successfully bind()s, which
+  * means the driver will handle setup() requests needed to enumerate (and
+Index: linux-2.6.0-test5/include/linux/usb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/usb.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/usb.h      2003-09-27 11:38:41.145273352 +0800
+@@ -80,7 +80,6 @@
+  * @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: 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.
+@@ -118,7 +117,6 @@
+       unsigned act_altsetting;        /* active alternate setting */
+       unsigned num_altsetting;        /* number of alternate settings */
+-      unsigned max_altsetting;        /* total memory allocated */
+       struct usb_driver *driver;      /* driver */
+       int minor;                      /* minor number this interface is bound to */
+Index: linux-2.6.0-test5/include/linux/wait.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/wait.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/wait.h     2003-09-27 11:38:41.148272896 +0800
+@@ -80,6 +80,15 @@
+       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));
+Index: linux-2.6.0-test5/include/linux/writeback.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/writeback.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/writeback.h        2003-09-27 11:38:41.149272744 +0800
+@@ -80,14 +80,17 @@
+ struct ctl_table;
+ struct file;
+-int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *, 
+-                                        void *, size_t *);
++int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *,
++                                    void __user *, 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_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
+Index: linux-2.6.0-test5/include/net/bluetooth/bluetooth.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/bluetooth/bluetooth.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/bluetooth/bluetooth.h        2003-09-27 11:38:41.152272288 +0800
+@@ -131,7 +131,7 @@
+ void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
+ int  bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int len, int flags);
+ uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
+-int  bt_sock_w4_connect(struct sock *sk, int flags);
++int  bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
+ void bt_accept_enqueue(struct sock *parent, struct sock *sk);
+ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
+Index: linux-2.6.0-test5/include/net/bluetooth/hci.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/bluetooth/hci.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/bluetooth/hci.h      2003-09-27 11:38:41.156271680 +0800
+@@ -304,6 +304,8 @@
+       __u8     num_rsp;
+ } __attribute__ ((packed));
++#define OCF_INQUIRY_CANCEL    0x0002
++
+ #define OCF_LINK_KEY_REPLY    0x000B
+ #define OCF_LINK_KEY_NEG_REPLY        0x000C
+ struct hci_cp_link_key_reply {
+Index: linux-2.6.0-test5/include/net/bluetooth/l2cap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/bluetooth/l2cap.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/bluetooth/l2cap.h    2003-09-27 11:38:41.159271224 +0800
+@@ -220,6 +220,7 @@
+       __u32           link_mode;
+       __u8            conf_state;
++      __u8            conf_retry;
+       __u16           conf_mtu;
+       __u8            ident;
+@@ -234,6 +235,7 @@
+ #define L2CAP_CONF_REQ_SENT    0x01
+ #define L2CAP_CONF_INPUT_DONE  0x02
+ #define L2CAP_CONF_OUTPUT_DONE 0x04
++#define L2CAP_CONF_MAX_RETRIES 2
+ void l2cap_load(void);
+Index: linux-2.6.0-test5/include/net/if_inet6.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/if_inet6.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/if_inet6.h   2003-09-27 11:38:41.161270920 +0800
+@@ -16,7 +16,12 @@
+ #define _NET_IF_INET6_H
+ #include <net/snmp.h>
++#include <linux/ipv6.h>
++/* inet6_dev.if_flags */
++
++#define IF_RA_OTHERCONF       0x80
++#define IF_RA_MANAGED 0x40
+ #define IF_RA_RCVD    0x20
+ #define IF_RS_SENT    0x10
+@@ -132,28 +137,6 @@
+ #define       IFA_SITE        IPV6_ADDR_SITELOCAL
+ #define       IFA_GLOBAL      0x0000U
+-struct ipv6_devconf
+-{
+-      int             forwarding;
+-      int             hop_limit;
+-      int             mtu6;
+-      int             accept_ra;
+-      int             accept_redirects;
+-      int             autoconf;
+-      int             dad_transmits;
+-      int             rtr_solicits;
+-      int             rtr_solicit_interval;
+-      int             rtr_solicit_delay;
+-#ifdef CONFIG_IPV6_PRIVACY
+-      int             use_tempaddr;
+-      int             temp_valid_lft;
+-      int             temp_prefered_lft;
+-      int             regen_max_retry;
+-      int             max_desync_factor;
+-#endif
+-      void            *sysctl;
+-};
+-
+ struct ipv6_devstat {
+       struct proc_dir_entry   *proc_dir_entry;
+       DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
+Index: linux-2.6.0-test5/include/net/llc_conn.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_conn.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_conn.h   2003-09-27 11:38:41.163270616 +0800
+@@ -15,6 +15,14 @@
+ #include <net/llc_if.h>
+ #include <linux/llc.h>
++#define LLC_EVENT                1
++#define LLC_PACKET               2
++
++#define LLC_P_TIME               2
++#define LLC_ACK_TIME             1
++#define LLC_REJ_TIME             3
++#define LLC_BUSY_TIME            3
++
+ struct llc_timer {
+       struct timer_list timer;
+       u16               expire;       /* timer expire time */
+@@ -69,6 +77,16 @@
+ #define llc_sk(__sk) ((struct llc_opt *)(__sk)->sk_protinfo)
++static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type)
++{
++      skb->cb[sizeof(skb->cb) - 1] = type;
++}
++
++static __inline__ char llc_backlog_type(struct sk_buff *skb)
++{
++      return skb->cb[sizeof(skb->cb) - 1];
++}
++
+ extern struct sock *llc_sk_alloc(int family, int priority);
+ extern void llc_sk_free(struct sock *sk);
+@@ -90,9 +108,10 @@
+                                          struct llc_addr *laddr);
+ extern struct sock *llc_lookup_listener(struct llc_sap *sap,
+                                       struct llc_addr *laddr);
+-extern struct sock *llc_lookup_dgram(struct llc_sap *sap,
+-                                   struct llc_addr *laddr);
+-extern void llc_save_primitive(struct sk_buff* skb, u8 prim);
++extern void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk);
++extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
++
+ extern u8 llc_data_accept_state(u8 state);
+ extern void llc_build_offset_table(void);
++extern int llc_release_sockets(struct llc_sap *sap);
+ #endif /* LLC_CONN_H */
+Index: linux-2.6.0-test5/include/net/llc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc.h   2003-09-27 11:38:18.487717824 +0800
++++ linux-2.6.0-test5/include/net/llc.h        2003-09-27 11:38:41.163270616 +0800
+@@ -0,0 +1,91 @@
++#ifndef LLC_H
++#define LLC_H
++/*
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++
++#include <linux/if.h>
++#include <linux/if_ether.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++
++struct net_device;
++struct packet_type;
++struct sk_buff;
++
++struct llc_addr {
++      unsigned char lsap;
++      unsigned char mac[IFHWADDRLEN];
++};
++
++#define LLC_SAP_STATE_INACTIVE        1
++#define LLC_SAP_STATE_ACTIVE  2
++
++/**
++ * struct llc_sap - Defines the SAP component
++ *
++ * @station - station this sap belongs to
++ * @state - sap state
++ * @p_bit - only lowest-order bit used
++ * @f_bit - only lowest-order bit used
++ * @laddr - SAP value in this 'lsap'
++ * @node - entry in station sap_list
++ * @sk_list - LLC sockets this one manages
++ */
++struct llc_sap {
++      unsigned char    state;
++      unsigned char    p_bit;
++      unsigned char    f_bit;
++      int              (*rcv_func)(struct sk_buff *skb,
++                                   struct net_device *dev,
++                                   struct packet_type *pt);
++      struct llc_addr  laddr;
++      struct list_head node;
++      struct {
++              rwlock_t          lock;
++              struct hlist_head list;
++      } sk_list;
++};
++
++#define LLC_DEST_INVALID         0      /* Invalid LLC PDU type */
++#define LLC_DEST_SAP             1      /* Type 1 goes here */
++#define LLC_DEST_CONN            2      /* Type 2 goes here */
++
++extern struct list_head llc_sap_list;
++extern rwlock_t llc_sap_list_lock;
++extern unsigned char llc_station_mac_sa[ETH_ALEN];
++
++extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
++                 struct packet_type *pt);
++
++extern int llc_mac_hdr_init(struct sk_buff *skb,
++                          unsigned char *sa, unsigned char *da);
++
++extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
++                                                 struct sk_buff *skb));
++extern void llc_remove_pack(int type);
++
++extern void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
++
++extern struct llc_sap *llc_sap_open(unsigned char lsap,
++                                  int (*rcv)(struct sk_buff *skb,
++                                             struct net_device *dev,
++                                             struct packet_type *pt));
++extern void llc_sap_close(struct llc_sap *sap);
++
++extern struct llc_sap *llc_sap_find(unsigned char sap_value);
++
++extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
++                                   unsigned char *dmac, unsigned char dsap);
++
++extern int llc_station_init(void);
++extern void llc_station_exit(void);
++#endif /* LLC_H */
+Index: linux-2.6.0-test5/include/net/llc_if.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_if.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_if.h     2003-09-27 11:38:41.165270312 +0800
+@@ -16,6 +16,7 @@
+ #include <linux/if.h>
+ #include <linux/if_arp.h>
+ #include <linux/llc.h>
++#include <net/llc.h>
+ #define LLC_DATAUNIT_PRIM     1
+ #define LLC_CONN_PRIM         2
+@@ -60,29 +61,41 @@
+ #define LLC_STATUS_CONFLICT   7 /* disconnect conn */
+ #define LLC_STATUS_RESET_DONE 8 /*  */
+-/* Structures and types */
+-/* SAP/MAC Address pair */
+-struct llc_addr {
+-      u8 lsap;
+-      u8 mac[IFHWADDRLEN];
+-};
+-
+-struct llc_sap;
+-
+-extern struct llc_sap *llc_sap_open(u8 lsap,
+-                                  int (*func)(struct sk_buff *skb,
+-                                              struct net_device *dev,
+-                                              struct packet_type *pt));
+-extern void llc_sap_close(struct llc_sap *sap);
++extern u8 llc_mac_null_var[IFHWADDRLEN];
++
++/**
++ *      llc_mac_null - determines if a address is a null mac address
++ *      @mac: Mac address to test if null.
++ *
++ *      Determines if a given address is a null mac address.  Returns 0 if the
++ *      address is not a null mac, 1 if the address is a null mac.
++ */
++static __inline__ int llc_mac_null(u8 *mac)
++{
++      return !memcmp(mac, llc_mac_null_var, IFHWADDRLEN);
++}
++
++static __inline__ int llc_addrany(struct llc_addr *addr)
++{
++      return llc_mac_null(addr->mac) && !addr->lsap;
++}
++
++/**
++ *    llc_mac_match - determines if two mac addresses are the same
++ *    @mac1: First mac address to compare.
++ *    @mac2: Second mac address to compare.
++ *
++ *    Determines if two given mac address are the same.  Returns 0 if there
++ *    is not a complete match up to len, 1 if a complete match up to len is
++ *    found.
++ */
++static __inline__ int llc_mac_match(u8 *mac1, u8 *mac2)
++{
++      return !memcmp(mac1, mac2, IFHWADDRLEN);
++}
+ extern int llc_establish_connection(struct sock *sk, u8 *lmac,
+                                   u8 *dmac, u8 dsap);
+ extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
+-extern void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
+-                                    u8 *dmac, u8 dsap);
+-extern void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
+-                                     u8 *dmac, u8 dsap);
+-extern void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
+-                                      u8 *dmac, u8 dsap);
+ extern int llc_send_disc(struct sock *sk);
+ #endif /* LLC_IF_H */
+Index: linux-2.6.0-test5/include/net/llc_pdu.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_pdu.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_pdu.h    2003-09-27 11:38:41.169269704 +0800
+@@ -2,7 +2,7 @@
+ #define LLC_PDU_H
+ /*
+  * Copyright (c) 1997 by Procom Technology,Inc.
+- *             2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+  *
+  * This program can be redistributed or modified under the terms of the
+  * GNU General Public License as published by the Free Software Foundation.
+@@ -11,7 +11,10 @@
+  *
+  * See the GNU General Public License for more details.
+  */
+-/* LLC PDU structure */
++
++#include <linux/if_ether.h>
++#include <linux/if_tr.h>
++
+ /* Lengths of frame formats */
+ #define LLC_PDU_LEN_I 4       /* header and 2 control bytes */
+ #define LLC_PDU_LEN_S 4
+@@ -198,7 +201,7 @@
+       u8 ctrl_2;
+ };
+-static __inline__ struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
++static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
+ {
+       return (struct llc_pdu_sn *)skb->nh.raw;
+ }
+@@ -210,16 +213,146 @@
+       u8 ctrl_1;
+ };
+-static __inline__ struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
++static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
+ {
+       return (struct llc_pdu_un *)skb->nh.raw;
+ }
+-static __inline__ void *llc_set_pdu_hdr(struct sk_buff *skb, void *ptr)
++static inline void *llc_set_pdu_hdr(struct sk_buff *skb, void *ptr)
+ {
+       return skb->nh.raw = ptr;
+ }
++/**
++ *    llc_pdu_header_init - initializes pdu header
++ *    @skb: input skb that header must be set into it.
++ *    @type: type of PDU (U, I or S).
++ *    @ssap: source sap.
++ *    @dsap: destination sap.
++ *    @cr: command/response bit (0 or 1).
++ *
++ *    This function sets DSAP, SSAP and command/Response bit in LLC header.
++ */
++static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
++                                     u8 ssap, u8 dsap, u8 cr)
++{
++      const int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
++      struct llc_pdu_un *pdu = llc_set_pdu_hdr(skb, skb_push(skb, hlen));
++      pdu->dsap = dsap;
++      pdu->ssap = ssap;
++      pdu->ssap |= cr;
++}
++
++/**
++ *    llc_pdu_decode_sa - extracs source address (MAC) of input frame
++ *    @skb: input skb that source address must be extracted from it.
++ *    @sa: pointer to source address (6 byte array).
++ *
++ *    This function extracts source address(MAC) of input frame.
++ */
++static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
++{
++      if (skb->protocol == ntohs(ETH_P_802_2))
++              memcpy(sa, ((struct ethhdr *)skb->mac.raw)->h_source, ETH_ALEN);
++      else if (skb->protocol == ntohs(ETH_P_TR_802_2))
++              memcpy(sa, ((struct trh_hdr *)skb->mac.raw)->saddr, ETH_ALEN);
++}
++
++/**
++ *    llc_pdu_decode_da - extracts dest address of input frame
++ *    @skb: input skb that destination address must be extracted from it
++ *    @sa: pointer to destination address (6 byte array).
++ *
++ *    This function extracts destination address(MAC) of input frame.
++ */
++static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
++{
++      if (skb->protocol == ntohs(ETH_P_802_2))
++              memcpy(da, ((struct ethhdr *)skb->mac.raw)->h_dest, ETH_ALEN);
++      else if (skb->protocol == ntohs(ETH_P_TR_802_2))
++              memcpy(da, ((struct trh_hdr *)skb->mac.raw)->daddr, ETH_ALEN);
++}
++
++/**
++ *    llc_pdu_decode_ssap - extracts source SAP of input frame
++ *    @skb: input skb that source SAP must be extracted from it.
++ *    @ssap: source SAP (output argument).
++ *
++ *    This function extracts source SAP of input frame. Right bit of SSAP is
++ *    command/response bit.
++ */
++static inline void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
++{
++      *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
++}
++
++/**
++ *    llc_pdu_decode_dsap - extracts dest SAP of input frame
++ *    @skb: input skb that destination SAP must be extracted from it.
++ *    @dsap: destination SAP (output argument).
++ *
++ *    This function extracts destination SAP of input frame. right bit of
++ *    DSAP designates individual/group SAP.
++ */
++static inline void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
++{
++      *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
++}
++
++/**
++ *    llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
++ *    @skb: input skb that header must be set into it.
++ *
++ *    This function sets third byte of LLC header as a UI PDU.
++ */
++static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
++{
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      pdu->ctrl_1  = LLC_PDU_TYPE_U;
++      pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
++}
++
++/**
++ *    llc_pdu_init_as_test_cmd - sets PDU as TEST
++ *    @skb - Address of the skb to build
++ *
++ *    Sets a PDU as TEST
++ */
++static inline void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
++{
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      pdu->ctrl_1  = LLC_PDU_TYPE_U;
++      pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
++      pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
++}
++
++/**
++ *    llc_pdu_init_as_test_rsp - build TEST response PDU
++ *    @skb: Address of the skb to build
++ *    @ev_skb: The received TEST command PDU frame
++ *
++ *    Builds a pdu frame as a TEST response.
++ */
++static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
++                                          struct sk_buff *ev_skb)
++{
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      pdu->ctrl_1  = LLC_PDU_TYPE_U;
++      pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
++      pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
++      if (ev_skb->protocol == ntohs(ETH_P_802_2)) {
++              struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
++              int dsize;
++
++              dsize = ntohs(((struct ethhdr *)ev_skb->mac.raw)->h_proto) - 3;
++              memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
++              skb_put(skb, dsize);
++      }
++}
++
+ /* LLC Type 1 XID command/response information fields format */
+ struct llc_xid_info {
+       u8 fmt_id;      /* always 0x18 for LLC */
+@@ -227,6 +360,54 @@
+       u8 rw;          /* sender receive window */
+ };
++/**
++ *    llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
++ *    @skb: input skb that header must be set into it.
++ *
++ *    This function sets third,fourth,fifth and sixth bytes of LLC header as
++ *    a XID PDU.
++ */
++static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
++                                         u8 svcs_supported, u8 rx_window)
++{
++      struct llc_xid_info *xid_info;
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      pdu->ctrl_1      = LLC_PDU_TYPE_U;
++      pdu->ctrl_1     |= LLC_1_PDU_CMD_XID;
++      pdu->ctrl_1     |= LLC_U_PF_BIT_MASK;
++      xid_info         = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
++      xid_info->fmt_id = LLC_XID_FMT_ID;      /* 0x81 */
++      xid_info->type   = svcs_supported;
++      xid_info->rw     = rx_window << 1;      /* size of receive window */
++      skb_put(skb, 3);
++}
++
++/**
++ *    llc_pdu_init_as_xid_rsp - builds XID response PDU
++ *    @skb: Address of the skb to build
++ *    @svcs_supported: The class of the LLC (I or II)
++ *    @rx_window: The size of the receive window of the LLC
++ *
++ *    Builds a pdu frame as an XID response.
++ */
++static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
++                                         u8 svcs_supported, u8 rx_window)
++{
++      struct llc_xid_info *xid_info;
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      pdu->ctrl_1      = LLC_PDU_TYPE_U;
++      pdu->ctrl_1     |= LLC_1_PDU_CMD_XID;
++      pdu->ctrl_1     |= LLC_U_PF_BIT_MASK;
++
++      xid_info         = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
++      xid_info->fmt_id = LLC_XID_FMT_ID;
++      xid_info->type   = svcs_supported;
++      xid_info->rw     = rx_window << 1;
++      skb_put(skb, 3);
++}
++
+ /* LLC Type 2 FRMR response information field format */
+ struct llc_frmr_info {
+       u16 rej_pdu_ctrl;       /* bits 1-8 if U-PDU */
+@@ -239,17 +420,6 @@
+ extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
+ extern void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
+ extern void llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit);
+-extern void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa);
+-extern void llc_pdu_decode_da(struct sk_buff *skb, u8 *ds);
+-extern void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap);
+-extern void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap);
+-extern void llc_decode_pdu_type(struct sk_buff *skb, u8 *destination);
+-extern void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap,
+-                              u8 dsap, u8 cr);
+-extern void llc_pdu_init_as_ui_cmd(struct sk_buff *skb);
+-extern void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported,
+-                                 u8 rx_window);
+-extern void llc_pdu_init_as_test_cmd(struct sk_buff *skb);
+ extern void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
+ extern void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
+ extern void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
+@@ -257,10 +427,6 @@
+ extern void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
+ extern void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit);
+ extern void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit);
+-extern void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported,
+-                                  u8 rx_window);
+-extern void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
+-                                   struct sk_buff *ev_skb);
+ extern void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb,
+                                    struct llc_pdu_sn *prev_pdu,
+                                    u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
+Index: linux-2.6.0-test5/include/net/llc_sap.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_sap.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_sap.h    2003-09-27 11:38:41.170269552 +0800
+@@ -2,7 +2,7 @@
+ #define LLC_SAP_H
+ /*
+  * Copyright (c) 1997 by Procom Technology,Inc.
+- *             2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+  *
+  * This program can be redistributed or modified under the terms of the
+  * GNU General Public License as published by the Free Software Foundation.
+@@ -11,37 +11,20 @@
+  *
+  * See the GNU General Public License for more details.
+  */
+-#include <linux/skbuff.h>
+-#include <net/llc_if.h>
+-/**
+- * struct llc_sap - Defines the SAP component
+- *
+- * @station - station this sap belongs to
+- * @state - sap state
+- * @p_bit - only lowest-order bit used
+- * @f_bit - only lowest-order bit used
+- * @laddr - SAP value in this 'lsap'
+- * @node - entry in station sap_list
+- * @sk_list - LLC sockets this one manages
+- */
+-struct llc_sap {
+-      struct llc_station *station;
+-      u8                  state;
+-      u8                  p_bit;
+-      u8                  f_bit;
+-      int                 (*rcv_func)(struct sk_buff *skb,
+-                                      struct net_device *dev,
+-                                      struct packet_type *pt);
+-      struct llc_addr     laddr;
+-      struct list_head    node;
+-      struct {
+-              rwlock_t          lock;
+-              struct hlist_head list;
+-      } sk_list;
+-};
++struct llc_sap;
++struct sk_buff;
+-extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk);
+-extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk);
+ extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb);
+ extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
++extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
++extern struct sk_buff *llc_alloc_frame(void);
++
++extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
++                                      struct sk_buff *skb,
++                                      unsigned char *dmac,
++                                      unsigned char dsap);
++extern void llc_build_and_send_xid_pkt(struct llc_sap *sap,
++                                     struct sk_buff *skb,
++                                     unsigned char *dmac,
++                                     unsigned char dsap);
+ #endif /* LLC_SAP_H */
+Index: linux-2.6.0-test5/include/net/llc_s_st.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/llc_s_st.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/llc_s_st.h   2003-09-27 11:38:41.172269248 +0800
+@@ -11,10 +11,7 @@
+  *
+  * See the GNU General Public License for more details.
+  */
+-/* Defines SAP component states */
+-#define LLC_SAP_STATE_INACTIVE        1
+-#define LLC_SAP_STATE_ACTIVE  2
+ #define LLC_NR_SAP_STATES     2       /* size of state table */
+ /* structures and types */
+Index: linux-2.6.0-test5/include/net/rose.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/rose.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/rose.h       2003-09-27 11:38:41.175268792 +0800
+@@ -140,9 +140,6 @@
+ #define rose_sk(__sk) ((rose_cb *)(__sk)->sk_protinfo)
+-/* Magic value indicating first entry in /proc (ie header) */
+-#define ROSE_PROC_START ((void *) 1)
+-
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int  sysctl_rose_restart_request_timeout;
+Index: linux-2.6.0-test5/include/net/syncppp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/net/syncppp.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/net/syncppp.h    2003-09-27 11:38:41.177268488 +0800
+@@ -57,8 +57,11 @@
+       struct sppp sppp;       /* Synchronous PPP */
+ };
+-#define sppp_of(dev)  \
+-          (&((struct ppp_device *)(*(unsigned long *)((dev)->priv)))->sppp)
++static inline struct sppp *sppp_of(struct net_device *dev) 
++{
++      struct ppp_device *ppp = dev->priv;
++      return &ppp->sppp;
++}
+ #define PP_KEEPALIVE    0x01    /* use keepalive protocol */
+ #define PP_CISCO        0x02    /* use Cisco protocol instead of PPP */
+Index: linux-2.6.0-test5/include/pcmcia/ss.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/pcmcia/ss.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/pcmcia/ss.h      2003-09-27 11:38:41.179268184 +0800
+@@ -78,7 +78,6 @@
+ #define SS_DMA_MODE   0x0080
+ #define SS_SPKR_ENA   0x0100
+ #define SS_OUTPUT_ENA 0x0200
+-#define SS_DEBOUNCED  0x0400  /* Tell driver that the debounce delay has ended */
+ /* Flags for I/O port and memory windows */
+ #define MAP_ACTIVE    0x01
+@@ -176,7 +175,6 @@
+       u_short                         functions;
+       u_short                         lock_count;
+       client_handle_t                 clients;
+-      u_int                           real_clients;
+       pccard_mem_map                  cis_mem;
+       u_char                          *cis_virt;
+       struct config_t                 *config;
+@@ -249,7 +247,7 @@
+ extern struct class pcmcia_socket_class;
+ /* socket drivers are expected to use these callbacks in their .drv struct */
+-extern int pcmcia_socket_dev_suspend(struct device *dev, u32 state, u32 level);
+-extern int pcmcia_socket_dev_resume(struct device *dev, u32 level);
++extern int pcmcia_socket_dev_suspend(struct device *dev, u32 state);
++extern int pcmcia_socket_dev_resume(struct device *dev);
+ #endif /* _LINUX_SS_H */
+Index: linux-2.6.0-test5/include/rxrpc/call.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/call.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/call.h     2003-09-27 11:38:41.182267728 +0800
+@@ -67,8 +67,8 @@
+       wait_queue_head_t       waitq;          /* wait queue for events to happen */
+       struct list_head        link;           /* general internal list link */
+       struct list_head        call_link;      /* master call list link */
+-      u32                     chan_ix;        /* connection channel index (net order) */
+-      u32                     call_id;        /* call ID on connection (net order) */
++      uint32_t                chan_ix;        /* connection channel index (net order) */
++      uint32_t                call_id;        /* call ID on connection (net order) */
+       unsigned long           cjif;           /* jiffies at call creation */
+       unsigned long           flags;          /* control flags */
+ #define RXRPC_CALL_ACKS_TIMO  0x00000001      /* ACKS timeout reached */
+@@ -103,7 +103,7 @@
+       char                    ackr_dfr_perm;  /* request for deferred ACKs permitted */
+       rxrpc_seq_t             ackr_dfr_seq;   /* seqno for deferred ACK */
+       struct rxrpc_ackpacket  ackr;           /* pending normal ACK packet */
+-      u8                      ackr_array[RXRPC_CALL_ACK_WINDOW_SIZE]; /* ACK records */
++      uint8_t                 ackr_array[RXRPC_CALL_ACK_WINDOW_SIZE]; /* ACK records */
+       /* presentation layer */
+       char                    app_last_rcv;   /* T if received last packet from remote end */
+@@ -131,14 +131,14 @@
+       struct list_head        app_attn_link;  /* application attention list linkage */
+       size_t                  app_mark;       /* trigger callback when app_ready_qty>=app_mark */
+       char                    app_async_read; /* T if in async-read mode */
+-      u8                      *app_read_buf;  /* application async read buffer (app_mark size) */
+-      u8                      *app_scr_alloc; /* application scratch allocation pointer */
++      uint8_t                 *app_read_buf;  /* application async read buffer (app_mark size) */
++      uint8_t                 *app_scr_alloc; /* application scratch allocation pointer */
+       void                    *app_scr_ptr;   /* application pointer into scratch buffer */
+ #define RXRPC_APP_MARK_EOF 0xFFFFFFFFU        /* mark at end of input */
+       /* application scratch buffer */
+-      u8              app_scratch[0] __attribute__((aligned(sizeof(long))));
++      uint8_t                 app_scratch[0] __attribute__((aligned(sizeof(long))));
+ };
+ #define RXRPC_CALL_SCRATCH_SIZE (PAGE_SIZE - sizeof(struct rxrpc_call))
+@@ -206,7 +206,7 @@
+ extern int rxrpc_call_write_data(struct rxrpc_call *call,
+                                size_t sioc,
+                                struct iovec siov[],
+-                               u8 rxhdr_flags,
++                               uint8_t rxhdr_flags,
+                                int alloc_flags,
+                                int dup_data,
+                                size_t *size_sent);
+Index: linux-2.6.0-test5/include/rxrpc/connection.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/connection.h  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/connection.h       2003-09-27 11:38:41.184267424 +0800
+@@ -34,6 +34,7 @@
+       struct list_head        link;           /* link in peer's list */
+       struct list_head        proc_link;      /* link in proc list */
+       struct list_head        err_link;       /* link in ICMP error processing list */
++      struct list_head        id_link;        /* link in ID grant list */
+       struct sockaddr_in      addr;           /* remote address */
+       struct rxrpc_call       *channels[4];   /* channels (active calls) */
+       wait_queue_head_t       chanwait;       /* wait for channel to become available */
+@@ -44,19 +45,19 @@
+       rxrpc_serial_t          serial_counter; /* packet serial number counter */
+       /* the following should all be in net order */
+-      u32                     in_epoch;       /* peer's epoch */
+-      u32                     out_epoch;      /* my epoch */
+-      u32                     conn_id;        /* connection ID, appropriately shifted */
+-      u16                     service_id;     /* service ID */
+-      u8                      security_ix;    /* security ID */
+-      u8                      in_clientflag;  /* RXRPC_CLIENT_INITIATED if we are server */
+-      u8                      out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
++      uint32_t                in_epoch;       /* peer's epoch */
++      uint32_t                out_epoch;      /* my epoch */
++      uint32_t                conn_id;        /* connection ID, appropriately shifted */
++      uint16_t                service_id;     /* service ID */
++      uint8_t                 security_ix;    /* security ID */
++      uint8_t                 in_clientflag;  /* RXRPC_CLIENT_INITIATED if we are server */
++      uint8_t                 out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
+ };
+ extern int rxrpc_create_connection(struct rxrpc_transport *trans,
+-                                 u16 port,
+-                                 u32 addr,
+-                                 unsigned short service_id,
++                                 uint16_t port,
++                                 uint32_t addr,
++                                 uint16_t service_id,
+                                  void *security,
+                                  struct rxrpc_connection **_conn);
+Index: linux-2.6.0-test5/include/rxrpc/message.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/message.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/message.h  2003-09-27 11:38:41.185267272 +0800
+@@ -9,8 +9,8 @@
+  * 2 of the License, or (at your option) any later version.
+  */
+-#ifndef _H_3AD3363A_3A9C_11D6_83D8_0002B3163499
+-#define _H_3AD3363A_3A9C_11D6_83D8_0002B3163499
++#ifndef _LINUX_RXRPC_MESSAGE_H
++#define _LINUX_RXRPC_MESSAGE_H
+ #include <rxrpc/packet.h>
+@@ -61,7 +61,7 @@
+ extern int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
+                            struct rxrpc_call *call,
+-                           u8 type,
++                           uint8_t type,
+                            int count,
+                            struct iovec diov[],
+                            int alloc_flags,
+@@ -69,4 +69,4 @@
+ extern int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg);
+-#endif /* _H_3AD3363A_3A9C_11D6_83D8_0002B3163499 */
++#endif /* _LINUX_RXRPC_MESSAGE_H */
+Index: linux-2.6.0-test5/include/rxrpc/packet.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/packet.h      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/packet.h   2003-09-27 11:38:41.188266816 +0800
+@@ -27,21 +27,21 @@
+  */
+ struct rxrpc_header
+ {
+-      u32     epoch;          /* client boot timestamp */
++      uint32_t        epoch;          /* client boot timestamp */
+-      u32     cid;            /* connection and channel ID */
++      uint32_t        cid;            /* connection and channel ID */
+ #define RXRPC_MAXCALLS                4                       /* max active calls per conn */
+ #define RXRPC_CHANNELMASK     (RXRPC_MAXCALLS-1)      /* mask for channel ID */
+ #define RXRPC_CIDMASK         (~RXRPC_CHANNELMASK)    /* mask for connection ID */
+ #define RXRPC_CIDSHIFT                2                       /* shift for connection ID */
+-      u32     callNumber;     /* call ID (0 for connection-level packets) */
++      uint32_t        callNumber;     /* call ID (0 for connection-level packets) */
+ #define RXRPC_PROCESS_MAXCALLS        (1<<2)  /* maximum number of active calls per conn (power of 2) */
+-      u32     seq;            /* sequence number of pkt in call stream */
+-      u32     serial;         /* serial number of pkt sent to network */
++      uint32_t        seq;            /* sequence number of pkt in call stream */
++      uint32_t        serial;         /* serial number of pkt sent to network */
+-      u8      type;           /* packet type */
++      uint8_t         type;           /* packet type */
+ #define RXRPC_PACKET_TYPE_DATA                1       /* data */
+ #define RXRPC_PACKET_TYPE_ACK         2       /* ACK */
+ #define RXRPC_PACKET_TYPE_BUSY                3       /* call reject */
+@@ -52,7 +52,7 @@
+ #define RXRPC_PACKET_TYPE_DEBUG               8       /* debug info request */
+ #define RXRPC_N_PACKET_TYPES          9       /* number of packet types (incl type 0) */
+-      u8      flags;          /* packet flags */
++      uint8_t         flags;          /* packet flags */
+ #define RXRPC_CLIENT_INITIATED        0x01            /* signifies a packet generated by a client */
+ #define RXRPC_REQUEST_ACK     0x02            /* request an unconditional ACK of this packet */
+ #define RXRPC_LAST_PACKET     0x04            /* the last packet from this side for this call */
+@@ -60,10 +60,10 @@
+ #define RXRPC_JUMBO_PACKET    0x20            /* [DATA] this is a jumbo packet */
+ #define RXRPC_SLOW_START_OK   0x20            /* [ACK] slow start supported */
+-      u8      userStatus;     /* app-layer defined status */
+-      u8      securityIndex;  /* security protocol ID */
+-      u16     _rsvd;          /* reserved (used by kerberos security as cksum) */
+-      u16     serviceId;      /* service ID */
++      uint8_t         userStatus;     /* app-layer defined status */
++      uint8_t         securityIndex;  /* security protocol ID */
++      uint16_t        _rsvd;          /* reserved (used by kerberos security as cksum) */
++      uint16_t        serviceId;      /* service ID */
+ } __attribute__((packed));
+@@ -83,9 +83,9 @@
+  */
+ struct rxrpc_jumbo_header
+ {
+-      u8      flags;          /* packet flags (as per rxrpc_header) */
+-      u8      pad;
+-      u16     _rsvd;          /* reserved (used by kerberos security as cksum) */
++      uint8_t         flags;          /* packet flags (as per rxrpc_header) */
++      uint8_t         pad;
++      uint16_t        _rsvd;          /* reserved (used by kerberos security as cksum) */
+ };
+ #define RXRPC_JUMBO_DATALEN   1412    /* non-terminal jumbo packet data length */
+@@ -97,13 +97,14 @@
+  */
+ struct rxrpc_ackpacket
+ {
+-      u16     bufferSpace;    /* number of packet buffers available */
+-      u16     maxSkew;        /* diff between serno being ACK'd and highest serial no received */
+-      u32     firstPacket;    /* sequence no of first ACK'd packet in attached list */
+-      u32     previousPacket; /* sequence no of previous packet received */
+-      u32     serial;         /* serial no of packet that prompted this ACK */
++      uint16_t        bufferSpace;    /* number of packet buffers available */
++      uint16_t        maxSkew;        /* diff between serno being ACK'd and highest serial no
++                                       * received */
++      uint32_t        firstPacket;    /* sequence no of first ACK'd packet in attached list */
++      uint32_t        previousPacket; /* sequence no of previous packet received */
++      uint32_t        serial;         /* serial no of packet that prompted this ACK */
+-      u8      reason;         /* reason for ACK */
++      uint8_t         reason;         /* reason for ACK */
+ #define RXRPC_ACK_REQUESTED           1       /* ACK was requested on packet */
+ #define RXRPC_ACK_DUPLICATE           2       /* duplicate packet received */
+ #define RXRPC_ACK_OUT_OF_SEQUENCE     3       /* out of sequence packet received */
+@@ -114,10 +115,10 @@
+ #define RXRPC_ACK_DELAY                       8       /* nothing happened since received packet */
+ #define RXRPC_ACK_IDLE                        9       /* ACK due to fully received ACK window */
+-      u8      nAcks;          /* number of ACKs */
++      uint8_t         nAcks;          /* number of ACKs */
+ #define RXRPC_MAXACKS 255
+-      u8      acks[0];        /* list of ACK/NAKs */
++      uint8_t         acks[0];        /* list of ACK/NAKs */
+ #define RXRPC_ACK_TYPE_NACK           0
+ #define RXRPC_ACK_TYPE_ACK            1
+Index: linux-2.6.0-test5/include/rxrpc/peer.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/peer.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/peer.h     2003-09-27 11:38:41.190266512 +0800
+@@ -42,7 +42,10 @@
+       struct rxrpc_timer      timeout;        /* timeout for grave destruction */
+       struct list_head        link;           /* link in transport's peer list */
+       struct list_head        proc_link;      /* link in /proc list */
+-      rwlock_t                conn_lock;      /* lock for connections */
++      rwlock_t                conn_idlock;    /* lock for connection IDs */
++      struct list_head        conn_idlist;    /* list of connections granted IDs */
++      uint32_t                conn_idcounter; /* connection ID counter */
++      rwlock_t                conn_lock;      /* lock for active/dead connections */
+       struct list_head        conn_active;    /* active connections to/from this peer */
+       struct list_head        conn_graveyard; /* graveyard for inactive connections */
+       spinlock_t              conn_gylock;    /* lock for conn_graveyard */
+Index: linux-2.6.0-test5/include/rxrpc/rxrpc.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/rxrpc.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/rxrpc.h    2003-09-27 11:38:41.191266360 +0800
+@@ -14,7 +14,7 @@
+ #ifdef __KERNEL__
+-extern u32 rxrpc_epoch;
++extern uint32_t rxrpc_epoch;
+ extern int rxrpc_ktrace;
+ extern int rxrpc_kdebug;
+Index: linux-2.6.0-test5/include/rxrpc/transport.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/transport.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/transport.h        2003-09-27 11:38:41.192266208 +0800
+@@ -85,10 +85,11 @@
+ static inline void rxrpc_get_transport(struct rxrpc_transport *trans)
+ {
+-      if (atomic_read(&trans->usage)<=0)
++      if (atomic_read(&trans->usage) <= 0)
+               BUG();
+       atomic_inc(&trans->usage);
+-      //printk("rxrpc_get_transport(%p{u=%d})\n",trans,atomic_read(&trans->usage));
++      //printk("rxrpc_get_transport(%p{u=%d})\n",
++      //       trans, atomic_read(&trans->usage));
+ }
+ extern void rxrpc_put_transport(struct rxrpc_transport *trans);
+@@ -99,11 +100,6 @@
+ extern void rxrpc_del_service(struct rxrpc_transport *trans,
+                             struct rxrpc_service *srv);
+-#if 0
+-extern int rxrpc_trans_add_connection(struct rxrpc_transport *trans,
+-                                    struct rxrpc_connection *conn);
+-#endif
+-
+ extern void rxrpc_trans_receive_packet(struct rxrpc_transport *trans);
+ extern int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
+Index: linux-2.6.0-test5/include/rxrpc/types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/rxrpc/types.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/rxrpc/types.h    2003-09-27 11:38:41.194265904 +0800
+@@ -19,8 +19,8 @@
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
+-typedef unsigned      rxrpc_seq_t;    /* Rx message sequence number */
+-typedef unsigned      rxrpc_serial_t; /* Rx message serial number */
++typedef uint32_t      rxrpc_seq_t;    /* Rx message sequence number */
++typedef uint32_t      rxrpc_serial_t; /* Rx message serial number */
+ struct rxrpc_call;
+ struct rxrpc_connection;
+Index: linux-2.6.0-test5/include/scsi/scsi_tcq.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/scsi/scsi_tcq.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/scsi/scsi_tcq.h  2003-09-27 11:38:41.195265752 +0800
+@@ -27,7 +27,7 @@
+ {
+         if (sdev->tagged_supported) {
+               if (!blk_queue_tagged(sdev->request_queue))
+-                      blk_queue_init_tags(sdev->request_queue, depth);
++                      blk_queue_init_tags(sdev->request_queue, depth, NULL);
+               scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
+         }
+ }
+Index: linux-2.6.0-test5/include/video/epson1355.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/video/epson1355.h   2003-09-27 11:38:18.488717672 +0800
++++ linux-2.6.0-test5/include/video/epson1355.h        2003-09-27 11:38:41.196265600 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/video/neomagic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/video/neomagic.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/video/neomagic.h 2003-09-27 11:38:41.199265144 +0800
+@@ -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 @@
+ #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
+-
+Index: linux-2.6.0-test5/include/video/sisfb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/video/sisfb.h       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/include/video/sisfb.h    2003-09-27 11:38:41.201264840 +0800
+@@ -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 @@
+       SIS_650,
+       SIS_740,
+       SIS_330,
++      SIS_660,
++      SIS_760,
+       MAX_SIS_CHIP
+ } SIS_CHIP_TYPE;
+@@ -83,13 +133,15 @@
+       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 @@
+       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 @@
+       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 @@
+       
+       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__
+Index: linux-2.6.0-test5/init/do_mounts.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts.c 2003-09-27 11:38:41.205264232 +0800
+@@ -76,11 +76,13 @@
+                * Try the %u:%u format -- see print_dev_t()
+                */
+               res = MKDEV(maj, min);
++              if (maj != MAJOR(res) || min != MINOR(res))
++                      goto fail;
+       } else {
+               /*
+                * Nope.  Try old-style "0321"
+                */
+-              res = (dev_t)simple_strtoul(buf, &s, 16);
++              res = new_decode_dev(simple_strtoul(buf, &s, 16));
+               if (*s)
+                       goto fail;
+       }
+@@ -107,7 +109,7 @@
+       if (part < range)
+               return res + part;
+ fail:
+-      return (dev_t) 0;
++      return 0;
+ }
+ /*
+@@ -145,8 +147,10 @@
+               if (sscanf(name, "%u:%u", &maj, &min) == 2) {
+                       res = MKDEV(maj, min);
++                      if (maj != MAJOR(res) || min != MINOR(res))
++                              goto fail;
+               } else {
+-                      res = (dev_t)simple_strtoul(name, &p, 16);
++                      res = new_decode_dev(simple_strtoul(name, &p, 16));
+                       if (*p)
+                               goto fail;
+               }
+@@ -187,7 +191,7 @@
+       sys_rmdir("/sys");
+       return res;
+ fail:
+-      res = (dev_t) 0;
++      res = 0;
+       goto done;
+ }
+Index: linux-2.6.0-test5/init/do_mounts_devfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_devfs.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_devfs.c   2003-09-27 11:38:41.206264080 +0800
+@@ -78,9 +78,8 @@
+ /*
+  * recursively scan <path>, looking for a device node of type <dev>
+  */
+-static int __init find_in_devfs(char *path, dev_t dev)
++static int __init find_in_devfs(char *path, unsigned dev)
+ {
+-      struct stat buf;
+       char *end = path + strlen(path);
+       int rest = path + 64 - end;
+       int size;
+@@ -96,11 +95,7 @@
+               switch (d->d_type) {
+                       case DT_BLK:
+                               sprintf(end, "/%s", d->d_name);
+-                              if (sys_newstat(path, &buf) < 0)
+-                                      break;
+-                              if (!S_ISBLK(buf.st_mode))
+-                                      break;
+-                              if (buf.st_rdev != dev)
++                              if (bstat(path) != dev)
+                                       break;
+                               kfree(p);
+                               return 0;
+@@ -140,7 +135,7 @@
+       if (!dev)
+               return -1;
+       strcpy(path, "/dev");
+-      if (find_in_devfs(path, dev) < 0)
++      if (find_in_devfs(path, new_encode_dev(dev)) < 0)
+               return -1;
+       return sys_symlink(path + 5, name);
+ }
+Index: linux-2.6.0-test5/init/do_mounts.h
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts.h    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts.h 2003-09-27 11:38:41.208263776 +0800
+@@ -10,7 +10,7 @@
+ #include <linux/root_dev.h>
+ asmlinkage long sys_unlink(const char *name);
+-asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
++asmlinkage long sys_mknod(const char *name, int mode, unsigned dev);
+ asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+ asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
+ asmlinkage long sys_mkdir(const char *name, int mode);
+@@ -43,11 +43,36 @@
+ static inline int create_dev(char *name, dev_t dev, char *devfs_name)
+ {
+       sys_unlink(name);
+-      return sys_mknod(name, S_IFBLK|0600, dev);
++      return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
+ }
+ #endif
++#if BITS_PER_LONG == 32
++asmlinkage long sys_stat64(char *name, struct stat64 *stat);
++static inline u32 bstat(char *name)
++{
++      struct stat64 stat;
++      if (!sys_stat64(name, &stat) != 0)
++              return 0;
++      if (!S_ISBLK(stat.st_mode))
++              return 0;
++      if (stat.st_rdev != (u32)stat.st_rdev)
++              return 0;
++      return stat.st_rdev;
++}
++#else
++static inline u32 bstat(char *name)
++{
++      struct stat stat;
++      if (!sys_newstat(name, &stat) != 0)
++              return 0;
++      if (!S_ISBLK(stat.st_mode))
++              return 0;
++      return stat.st_rdev;
++}
++#endif
++
+ #ifdef CONFIG_BLK_DEV_RAM
+ int __init rd_load_disk(int n);
+@@ -79,4 +104,3 @@
+ static inline void md_run_setup(void) {}
+ #endif
+-
+Index: linux-2.6.0-test5/init/do_mounts_initrd.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_initrd.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_initrd.c  2003-09-27 11:38:41.209263624 +0800
+@@ -40,7 +40,7 @@
+       int error;
+       int i, pid;
+-      real_root_dev = ROOT_DEV;
++      real_root_dev = new_encode_dev(ROOT_DEV);
+       create_dev("/dev/root.old", Root_RAM0, NULL);
+       /* mount initrd on rootfs' /root */
+       mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
+@@ -69,12 +69,12 @@
+       close(root_fd);
+       umount_devfs("/old/dev");
+-      if (real_root_dev == Root_RAM0) {
++      if (new_decode_dev(real_root_dev) == Root_RAM0) {
+               sys_chdir("/old");
+               return;
+       }
+-      ROOT_DEV = real_root_dev;
++      ROOT_DEV = new_decode_dev(real_root_dev);
+       mount_root();
+       printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
+Index: linux-2.6.0-test5/init/do_mounts_md.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_md.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_md.c      2003-09-27 11:38:41.212263168 +0800
+@@ -124,7 +124,7 @@
+               for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
+                       char *p;
+                       char comp_name[64];
+-                      struct stat buf;
++                      u32 rdev;
+                       p = strchr(devname, ',');
+                       if (p)
+@@ -134,9 +134,9 @@
+                       if (strncmp(devname, "/dev/", 5) == 0)
+                               devname += 5;
+                       snprintf(comp_name, 63, "/dev/%s", devname);
+-                      if (sys_newstat(comp_name, &buf) == 0 &&
+-                                                      S_ISBLK(buf.st_mode))
+-                              dev = buf.st_rdev;
++                      rdev = bstat(comp_name);
++                      if (rdev)
++                              dev = new_decode_dev(rdev);
+                       if (!dev) {
+                               printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
+                               break;
+Index: linux-2.6.0-test5/init/do_mounts_rd.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/do_mounts_rd.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/do_mounts_rd.c      2003-09-27 11:38:41.215262712 +0800
+@@ -332,7 +332,7 @@
+       
+       insize = read(crd_infd, inbuf, INBUFSIZ);
+       if (insize == 0) {
+-              error("RAMDISK: ran out of compressed data\n");
++              error("RAMDISK: ran out of compressed data");
+               return -1;
+       }
+@@ -369,7 +369,7 @@
+ static void __init error(char *x)
+ {
+-      printk(KERN_ERR "%s", x);
++      printk(KERN_ERR "%s\n", x);
+       exit_code = 1;
+       unzip_error = 1;
+ }
+Index: linux-2.6.0-test5/init/initramfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/initramfs.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/initramfs.c 2003-09-27 11:38:41.219262104 +0800
+@@ -24,7 +24,7 @@
+ }
+ asmlinkage long sys_mkdir(char *name, int mode);
+-asmlinkage long sys_mknod(char *name, int mode, dev_t dev);
++asmlinkage long sys_mknod(char *name, int mode, unsigned dev);
+ asmlinkage long sys_symlink(char *old, char *new);
+ asmlinkage long sys_link(char *old, char *new);
+ asmlinkage long sys_write(int fd, const char *buf, size_t size);
+@@ -92,7 +92,7 @@
+ static __initdata unsigned long body_len, name_len;
+ static __initdata uid_t uid;
+ static __initdata gid_t gid;
+-static __initdata dev_t rdev;
++static __initdata unsigned rdev;
+ static void __init parse_header(char *s)
+ {
+@@ -113,7 +113,7 @@
+       body_len = parsed[6];
+       major = parsed[7];
+       minor = parsed[8];
+-      rdev = MKDEV(parsed[9], parsed[10]);
++      rdev = new_encode_dev(MKDEV(parsed[9], parsed[10]));
+       name_len = parsed[11];
+ }
+@@ -248,7 +248,6 @@
+               next_state = Reset;
+               return 0;
+       }
+-      printk(KERN_INFO "-> %s\n", collected);
+       if (S_ISREG(mode)) {
+               if (maybe_link() >= 0) {
+                       wfd = sys_open(collected, O_WRONLY|O_CREAT, mode);
+@@ -261,11 +260,13 @@
+       } else if (S_ISDIR(mode)) {
+               sys_mkdir(collected, mode);
+               sys_chown(collected, uid, gid);
++              sys_chmod(collected, mode);
+       } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
+                  S_ISFIFO(mode) || S_ISSOCK(mode)) {
+               if (maybe_link() == 0) {
+                       sys_mknod(collected, mode, rdev);
+                       sys_chown(collected, uid, gid);
++                      sys_chmod(collected, mode);
+               }
+       } else
+               panic("populate_root: bogus mode: %o\n", mode);
+Index: linux-2.6.0-test5/init/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/init/Kconfig        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/Kconfig     2003-09-27 11:38:41.222261648 +0800
+@@ -143,24 +143,24 @@
+         This option enables the complete Linux kernel ".config" file
+         contents, information on compiler used to build the kernel,
+         kernel running when this kernel was built and kernel version
+-        from Makefile to be saved in kernel. It provides documentation
++        from Makefile to be saved in the kernel. It provides documentation
+         of which kernel options are used in a running kernel or in an
+         on-disk kernel.  This information can be extracted from the kernel
+         image file with the script scripts/extract-ikconfig and used as
+         input to rebuild the current kernel or to build another kernel.
+         It can also be extracted from a running kernel by reading
+-        /proc/ikconfig/config and /proc/ikconfig/built_with, if enabled.
+-        /proc/ikconfig/config will list the configuration that was used
+-        to build the kernel and /proc/ikconfig/built_with will list
++        /proc/config.gz and /proc/config_built_with, if enabled (below).
++        /proc/config.gz will list the configuration that was used
++        to build the kernel and /proc/config_built_with will list
+         information on the compiler and host machine that was used to
+         build the kernel.
+ config IKCONFIG_PROC
+-      bool "Enable access to .config through /proc/ikconfig"
++      bool "Enable access to .config through /proc/config.gz"
+       depends on IKCONFIG && PROC_FS
+       ---help---
+         This option enables access to kernel configuration file and build
+-        information through /proc/ikconfig.
++        information through /proc/config.gz.
+ menuconfig EMBEDDED
+@@ -204,15 +204,22 @@
+ config MODULES
+       bool "Enable loadable module support"
+       help
+-        Kernel modules are small pieces of compiled code which can be
+-        inserted in or removed from the running kernel, using the programs
+-        insmod and rmmod. This is described in the file
+-        <file:Documentation/modules.txt>, including the fact that you have
+-        to say "make modules" in order to compile the modules that you chose
+-        during kernel configuration.  Modules can be device drivers, file
+-        systems, binary executable formats, and so on. If you think that you
+-        may want to make use of modules with this kernel in the future, then
+-        say Y here.  If unsure, say Y.
++        Kernel modules are small pieces of compiled code which can
++        be inserted in the running kernel, rather than being
++        permanently built into the kernel.  You use the "modprobe"
++        tool to add (and sometimes remove) them.  If you say Y here,
++        many parts of the kernel can be built as modules (by
++        answering M instead of Y where indicated): this is most
++        useful for infrequently used options which are not required
++        for booting.  For more information, see the man pages for
++        modprobe, lsmod, modinfo, insmod and rmmod.
++
++        If you say Y here, you will need to run "make
++        modules_install" to put the modules under /lib/modules/
++        where modprobe can find them (you may need to be root to do
++        this).
++
++        If unsure, say Y.
+ config MODULE_UNLOAD
+       bool "Module unloading"
+@@ -251,21 +258,18 @@
+         compiled for different kernels, by adding enough information
+         to the modules to (hopefully) spot any changes which would
+         make them incompatible with the kernel you are running.  If
+-        you say Y here, you will need a copy of genksyms.  If
+         unsure, say N.
+ config KMOD
+-      bool "Kernel module loader"
++      bool "Automatic kernel module loading"
+       depends on MODULES
+       help
+-        Normally when you have selected some drivers and/or file systems to
+-        be created as loadable modules, you also have the responsibility to
+-        load the corresponding modules (using the programs insmod or
+-        modprobe) before you can use them. If you say Y here however, the
+-        kernel will be able to load modules for itself: when a part of the
+-        kernel needs a module, it runs modprobe with the appropriate
+-        arguments, thereby loading the module if it is available. (This is a
+-        replacement for kerneld.) Say Y here and read about configuring it
+-        in <file:Documentation/kmod.txt>.
++        Normally when you have selected some parts of the kernel to
++        be created as kernel modules, you must load them (using the
++        "modprobe" command) before you can use them. If you say Y
++        here, some parts of the kernel will be able to load modules
++        automatically: when a part of the kernel needs a module, it
++        runs modprobe with the appropriate arguments, thereby
++        loading the module if it is available.  If unsure, say Y.
+ endmenu
+Index: linux-2.6.0-test5/init/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/main.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/init/main.c      2003-09-27 11:38:41.227260888 +0800
+@@ -542,12 +542,16 @@
+       spawn_ksoftirqd();
+ }
++static void run_init_process(char *init_filename)
++{
++      argv_init[0] = init_filename;
++      execve(init_filename, argv_init, envp_init);
++}
++
+ extern void prepare_namespace(void);
+ static int init(void * unused)
+ {
+-      static char * argv_sh[] = { "sh", NULL, };
+-
+       lock_kernel();
+       /*
+        * Tell the world that we're going to be the grim
+@@ -592,10 +596,12 @@
+        */
+       if (execute_command)
+-              execve(execute_command,argv_init,envp_init);
+-      execve("/sbin/init",argv_init,envp_init);
+-      execve("/etc/init",argv_init,envp_init);
+-      execve("/bin/init",argv_init,envp_init);
+-      execve("/bin/sh",argv_sh,envp_init);
++              run_init_process(execute_command);
++
++      run_init_process("/sbin/init");
++      run_init_process("/etc/init");
++      run_init_process("/bin/init");
++      run_init_process("/bin/sh");
++
+       panic("No init found.  Try passing init= option to kernel.");
+ }
+Index: linux-2.6.0-test5/ipc/sem.c
+===================================================================
+--- linux-2.6.0-test5.orig/ipc/sem.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/ipc/sem.c        2003-09-27 11:38:41.235259672 +0800
+@@ -1038,8 +1038,10 @@
+        * allocated an undo structure, it was invalidated by an RMID
+        * and now a new array with received the same id. Check and retry.
+        */
+-      if (un && un->semid == -1)
++      if (un && un->semid == -1) {
++              sem_unlock(sma);
+               goto retry_undos;
++      }
+       error = -EFBIG;
+       if (max >= sma->sem_nsems)
+               goto out_unlock_free;
+Index: linux-2.6.0-test5/kernel/acct.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/acct.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/acct.c    2003-09-27 11:38:41.238259216 +0800
+@@ -342,7 +342,7 @@
+       ac.ac_stime = encode_comp_t(current->stime);
+       ac.ac_uid = current->uid;
+       ac.ac_gid = current->gid;
+-      ac.ac_tty = current->tty ? current->tty->device : 0;
++      ac.ac_tty = current->tty ? tty_devnum(current->tty) : 0;
+       ac.ac_flag = 0;
+       if (current->flags & PF_FORKNOEXEC)
+Index: linux-2.6.0-test5/kernel/configs.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/configs.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/configs.c 2003-09-27 11:38:41.241258760 +0800
+@@ -23,6 +23,7 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
++#include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/proc_fs.h>
+@@ -35,129 +36,74 @@
+ /**************************************************/
+ /* the actual current config file                 */
++/* This one is for extraction from the kernel binary file image. */
+ #include "ikconfig.h"
+ #ifdef CONFIG_IKCONFIG_PROC
++/* This is the data that can be read from /proc/config.gz. */
++#include "config_data.h"
++
+ /**************************************************/
+ /* globals and useful constants                   */
+-static const char IKCONFIG_NAME[] = "ikconfig";
+-static const char IKCONFIG_VERSION[] = "0.6";
+-
+-static int ikconfig_size;
+-static struct proc_dir_entry *ikconfig_dir;
++static const char IKCONFIG_VERSION[] __initdata = "0.7";
+ static ssize_t
+-ikconfig_read(struct file *file, char __user *buf, 
+-                 size_t len, loff_t *offset)
++ikconfig_read_current(struct file *file, char __user *buf,
++                    size_t len, loff_t * offset)
+ {
+       loff_t pos = *offset;
+       ssize_t count;
+-      
+-      if (pos >= ikconfig_size)
++
++      if (pos >= kernel_config_data_size)
+               return 0;
+-      count = min(len, (size_t)(ikconfig_size - pos));
+-      if(copy_to_user(buf, ikconfig_config + pos, count))
++      count = min(len, (size_t)(kernel_config_data_size - pos));
++      if(copy_to_user(buf, kernel_config_data + pos, count))
+               return -EFAULT;
+       *offset += count;
+       return count;
+ }
+-static struct file_operations config_fops = {
++static struct file_operations ikconfig_file_ops = {
+       .owner = THIS_MODULE,
+-      .read  = ikconfig_read,
++      .read = ikconfig_read_current,
+ };
+ /***************************************************/
+-/* built_with_show: let people read the info  */
+-/* we have on the tools used to build this kernel  */
+-
+-static int builtwith_show(struct seq_file *seq, void *v)
+-{
+-      seq_printf(seq, 
+-                 "Kernel:    %s\nCompiler:  %s\nVersion_in_Makefile: %s\n",
+-                 ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE);
+-      return 0;
+-}
+-
+-static int built_with_open(struct inode *inode, struct file *file)
+-{
+-      return single_open(file, builtwith_show, PDE(inode)->data);
+-}
+-      
+-static struct file_operations builtwith_fops = {
+-      .owner = THIS_MODULE,
+-      .open  = built_with_open,
+-      .read  = seq_read,
+-      .llseek = seq_lseek,
+-      .release = single_release,
+-};    
+-
+-/***************************************************/
+ /* ikconfig_init: start up everything we need to */
+-int __init
+-ikconfig_init(void)
++static int __init ikconfig_init(void)
+ {
+       struct proc_dir_entry *entry;
+-      printk(KERN_INFO "ikconfig %s with /proc/ikconfig\n",
++      printk(KERN_INFO "ikconfig %s with /proc/config*\n",
+              IKCONFIG_VERSION);
+-      /* create the ikconfig directory */
+-      ikconfig_dir = proc_mkdir(IKCONFIG_NAME, NULL);
+-      if (ikconfig_dir == NULL) 
+-              goto leave;
+-      ikconfig_dir->owner = THIS_MODULE;
+-
+       /* create the current config file */
+-      entry = create_proc_entry("config", S_IFREG | S_IRUGO, ikconfig_dir);
++      entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
++                                &proc_root);
+       if (!entry)
+-              goto leave2;
++              return -ENOMEM;
+-      entry->proc_fops = &config_fops;
+-      entry->size = ikconfig_size = strlen(ikconfig_config);
+-
+-      /* create the "built with" file */
+-      entry = create_proc_entry("built_with", S_IFREG | S_IRUGO,
+-                                ikconfig_dir);
+-      if (!entry)
+-              goto leave3;
+-      entry->proc_fops = &builtwith_fops;
++      entry->proc_fops = &ikconfig_file_ops;
++      entry->size = kernel_config_data_size;
+       return 0;
+-
+-leave3:
+-      /* remove the file from proc */
+-      remove_proc_entry("config", ikconfig_dir);
+-
+-leave2:
+-      /* remove the ikconfig directory */
+-      remove_proc_entry(IKCONFIG_NAME, NULL);
+-
+-leave:
+-      return -ENOMEM;
+ }
+ /***************************************************/
+-/* cleanup_ikconfig: clean up our mess           */
++/* ikconfig_cleanup: clean up our mess           */
+-static void
+-cleanup_ikconfig(void)
++static void __exit ikconfig_cleanup(void)
+ {
+-      /* remove the files */
+-      remove_proc_entry("config", ikconfig_dir);
+-      remove_proc_entry("built_with", ikconfig_dir);
+-
+-      /* remove the ikconfig directory */
+-      remove_proc_entry(IKCONFIG_NAME, NULL);
++      remove_proc_entry("config.gz", &proc_root);
+ }
+ module_init(ikconfig_init);
+-module_exit(cleanup_ikconfig);
++module_exit(ikconfig_cleanup);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Randy Dunlap");
+Index: linux-2.6.0-test5/kernel/exit.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/exit.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/exit.c    2003-09-27 11:38:41.248257696 +0800
+@@ -152,7 +152,7 @@
+                               || p->state >= TASK_ZOMBIE 
+                               || p->real_parent->pid == 1)
+                       continue;
+-              if (p->real_parent->pgrp != pgrp
++              if (process_group(p->real_parent) != pgrp
+                           && p->real_parent->session == p->session) {
+                       ret = 0;
+                       break;
+@@ -247,9 +247,9 @@
+               curr->session = session;
+               attach_pid(curr, PIDTYPE_SID, session);
+       }
+-      if (curr->pgrp != pgrp) {
++      if (process_group(curr) != pgrp) {
+               detach_pid(curr, PIDTYPE_PGID);
+-              curr->pgrp = pgrp;
++              curr->group_leader->__pgrp = pgrp;
+               attach_pid(curr, PIDTYPE_PGID, pgrp);
+       }
+ }
+@@ -508,9 +508,9 @@
+        * than we are, and it was the only connection
+        * outside, so the child pgrp is now orphaned.
+        */
+-      if ((p->pgrp != father->pgrp) &&
++      if ((process_group(p) != process_group(father)) &&
+           (p->session == father->session)) {
+-              int pgrp = p->pgrp;
++              int pgrp = process_group(p);
+               if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
+                       __kill_pg_info(SIGHUP, (void *)1, pgrp);
+@@ -618,12 +618,12 @@
+        
+       t = tsk->real_parent;
+       
+-      if ((t->pgrp != tsk->pgrp) &&
++      if ((process_group(t) != process_group(tsk)) &&
+           (t->session == tsk->session) &&
+-          will_become_orphaned_pgrp(tsk->pgrp, tsk) &&
+-          has_stopped_jobs(tsk->pgrp)) {
+-              __kill_pg_info(SIGHUP, (void *)1, tsk->pgrp);
+-              __kill_pg_info(SIGCONT, (void *)1, tsk->pgrp);
++          will_become_orphaned_pgrp(process_group(tsk), tsk) &&
++          has_stopped_jobs(process_group(tsk))) {
++              __kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
++              __kill_pg_info(SIGCONT, (void *)1, process_group(tsk));
+       }
+       /* Let father know we died 
+@@ -813,10 +813,10 @@
+               if (p->pid != pid)
+                       return 0;
+       } else if (!pid) {
+-              if (p->pgrp != current->pgrp)
++              if (process_group(p) != process_group(current))
+                       return 0;
+       } else if (pid != -1) {
+-              if (p->pgrp != -pid)
++              if (process_group(p) != -pid)
+                       return 0;
+       }
+Index: linux-2.6.0-test5/kernel/fork.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/fork.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/fork.c    2003-09-27 11:38:41.256256480 +0800
+@@ -121,7 +121,12 @@
+ {
+       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 @@
+ {
+       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))
+@@ -305,7 +315,7 @@
+       return retval;
+ fail_nomem:
+       retval = -ENOMEM;
+-  fail:
++fail:
+       vm_unacct_memory(charge);
+       goto out;
+ }
+@@ -499,7 +509,7 @@
+               goto fail_nomem;
+       if (init_new_context(tsk,mm))
+-              goto free_pt;
++              goto fail_nocontext;
+       retval = dup_mmap(mm, oldmm);
+       if (retval)
+@@ -514,6 +524,15 @@
+       mmput(mm);
+ fail_nomem:
+       return retval;
++
++fail_nocontext:
++      /*
++       * If init_new_context() failed, we cannot use mmput() to free the mm
++       * because it calls destroy_context()
++       */
++      mm_free_pgd(mm);
++      free_mm(mm);
++      return retval;
+ }
+ static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
+@@ -868,6 +887,7 @@
+       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)))
+@@ -925,7 +945,7 @@
+        */
+       p->first_time_slice = 1;
+       current->time_slice >>= 1;
+-      p->last_run = jiffies;
++      p->timestamp = sched_clock();
+       if (!current->time_slice) {
+               /*
+                * This case is rare, it happens when the parent has only
+@@ -1004,7 +1024,7 @@
+       attach_pid(p, PIDTYPE_PID, p->pid);
+       if (thread_group_leader(p)) {
+               attach_pid(p, PIDTYPE_TGID, p->tgid);
+-              attach_pid(p, PIDTYPE_PGID, p->pgrp);
++              attach_pid(p, PIDTYPE_PGID, process_group(p));
+               attach_pid(p, PIDTYPE_SID, p->session);
+               if (p->pid)
+                       __get_cpu_var(process_counts)++;
+Index: linux-2.6.0-test5/kernel/futex.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/futex.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/futex.c   2003-09-27 11:38:41.261255720 +0800
+@@ -33,7 +33,7 @@
+ #include <linux/poll.h>
+ #include <linux/fs.h>
+ #include <linux/file.h>
+-#include <linux/hash.h>
++#include <linux/jhash.h>
+ #include <linux/init.h>
+ #include <linux/futex.h>
+ #include <linux/mount.h>
+@@ -44,6 +44,7 @@
+ /*
+  * 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().
+  */
+ union futex_key {
+       struct {
+@@ -79,9 +80,15 @@
+       struct file *filp;
+ };
+-/* The key for the hash is the address + index + offset within page */
+-static struct list_head futex_queues[1<<FUTEX_HASHBITS];
+-static spinlock_t futex_lock = SPIN_LOCK_UNLOCKED;
++/*
++ * Split the global futex_lock into every hash list lock.
++ */
++struct futex_hash_bucket {
++       spinlock_t              lock;
++       struct list_head       chain;
++};
++
++static struct futex_hash_bucket futex_queues[1<<FUTEX_HASHBITS];
+ /* Futex-fs vfsmount entry: */
+ static struct vfsmount *futex_mnt;
+@@ -89,11 +96,12 @@
+ /*
+  * We hash on the keys returned from get_futex_key (see below).
+  */
+-static inline struct list_head *hash_futex(union futex_key *key)
++static struct futex_hash_bucket *hash_futex(union futex_key *key)
+ {
+-      return &futex_queues[hash_long(key->both.word
+-                                     + (unsigned long) key->both.ptr
+-                                     + key->both.offset, FUTEX_HASHBITS)];
++      u32 hash = jhash2((u32*)&key->both.word,
++                        (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
++                        key->both.offset);
++      return &futex_queues[hash & ((1 << FUTEX_HASHBITS)-1)];
+ }
+ /*
+@@ -214,6 +222,7 @@
+ static int futex_wake(unsigned long uaddr, int num)
+ {
+       struct list_head *i, *next, *head;
++      struct futex_hash_bucket *bh;
+       union futex_key key;
+       int ret;
+@@ -223,9 +232,10 @@
+       if (unlikely(ret != 0))
+               goto out;
+-      head = hash_futex(&key);
++      bh = hash_futex(&key);
++      spin_lock(&bh->lock);
++      head = &bh->chain;
+-      spin_lock(&futex_lock);
+       list_for_each_safe(i, next, head) {
+               struct futex_q *this = list_entry(i, struct futex_q, list);
+@@ -239,7 +249,7 @@
+                               break;
+               }
+       }
+-      spin_unlock(&futex_lock);
++      spin_unlock(&bh->lock);
+ out:
+       up_read(&current->mm->mmap_sem);
+@@ -254,6 +264,7 @@
+                               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;
+@@ -266,10 +277,19 @@
+       if (unlikely(ret != 0))
+               goto out;
+-      head1 = hash_futex(&key1);
+-      head2 = hash_futex(&key2);
++      bh1 = hash_futex(&key1);
++      bh2 = hash_futex(&key2);
++      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;
+-      spin_lock(&futex_lock);
+       list_for_each_safe(i, next, head1) {
+               struct futex_q *this = list_entry(i, struct futex_q, list);
+@@ -291,38 +311,46 @@
+                       }
+               }
+       }
+-      spin_unlock(&futex_lock);
+-
++      if (bh1 < bh2) {
++              spin_unlock(&bh2->lock);
++              spin_unlock(&bh1->lock);
++      } else {
++              if (bh1 > bh2)
++                      spin_unlock(&bh1->lock);
++              spin_unlock(&bh2->lock);
++      }
+ out:
+       up_read(&current->mm->mmap_sem);
+       return ret;
+ }
+-static inline void queue_me(struct futex_q *q, union futex_key *key,
++static void queue_me(struct futex_q *q, union futex_key *key,
+                           int fd, struct file *filp)
+ {
+-      struct list_head *head = hash_futex(key);
++      struct futex_hash_bucket *bh = hash_futex(key);
++      struct list_head *head = &bh->chain;
+       q->key = *key;
+       q->fd = fd;
+       q->filp = filp;
+-      spin_lock(&futex_lock);
++      spin_lock(&bh->lock);
+       list_add_tail(&q->list, head);
+-      spin_unlock(&futex_lock);
++      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;
+-      spin_lock(&futex_lock);
++      spin_lock(&bh->lock);
+       if (!list_empty(&q->list)) {
+               list_del(&q->list);
+               ret = 1;
+       }
+-      spin_unlock(&futex_lock);
++      spin_unlock(&bh->lock);
+       return ret;
+ }
+@@ -332,8 +360,8 @@
+       int ret, curval;
+       union futex_key key;
+       struct futex_q q;
++      struct futex_hash_bucket *bh = NULL;
+- try_again:
+       init_waitqueue_head(&q.waiters);
+       down_read(&current->mm->mmap_sem);
+@@ -367,25 +395,26 @@
+       /*
+        * There might have been scheduling since the queue_me(), as we
+        * cannot hold a spinlock across the get_user() in case it
+-       * faults.  So we cannot just set TASK_INTERRUPTIBLE state when
++       * faults, and we cannot just set TASK_INTERRUPTIBLE state when
+        * queueing ourselves into the futex hash.  This code thus has to
+-       * rely on the futex_wake() code doing a wakeup after removing
+-       * the waiter from the list.
++       * rely on the futex_wake() code removing us from hash when it
++       * wakes us up.
+        */
+       add_wait_queue(&q.waiters, &wait);
+-      spin_lock(&futex_lock);
++      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(&futex_lock);
++              spin_unlock(&bh->lock);
+               set_current_state(TASK_RUNNING);
+               return 0;
+       }
+-      spin_unlock(&futex_lock);
++      spin_unlock(&bh->lock);
+       time = schedule_timeout(time);
+       set_current_state(TASK_RUNNING);
+@@ -394,26 +423,17 @@
+        * we are the only user of it.
+        */
+-      /*
+-       * Were we woken or interrupted for a valid reason?
+-       */
+-      ret = unqueue_me(&q);
+-      if (ret == 0)
++      /* If we were woken (and unqueued), we succeeded, whatever. */
++      if (!unqueue_me(&q))
+               return 0;
+       if (time == 0)
+               return -ETIMEDOUT;
+-      if (signal_pending(current))
+-              return -EINTR;
+-
+-      /*
+-       * No, it was a spurious wakeup.  Try again.  Should never happen. :)
+-       */
+-      goto try_again;
++      /* A spurious wakeup should never happen. */
++      WARN_ON(!signal_pending(current));
++      return -EINTR;
+  out_unqueue:
+-      /*
+-       * Were we unqueued anyway?
+-       */
++      /* If we were woken (and unqueued), we succeeded, whatever. */
+       if (!unqueue_me(&q))
+               ret = 0;
+  out_release_sem:
+@@ -435,13 +455,14 @@
+                              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(&futex_lock);
++      spin_lock(&bh->lock);
+       if (list_empty(&q->list))
+               ret = POLLIN | POLLRDNORM;
+-      spin_unlock(&futex_lock);
++      spin_unlock(&bh->lock);
+       return ret;
+ }
+@@ -587,8 +608,10 @@
+       register_filesystem(&futex_fs_type);
+       futex_mnt = kern_mount(&futex_fs_type);
+-      for (i = 0; i < ARRAY_SIZE(futex_queues); i++)
+-              INIT_LIST_HEAD(&futex_queues[i]);
++      for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
++              INIT_LIST_HEAD(&futex_queues[i].chain);
++              futex_queues[i].lock = SPIN_LOCK_UNLOCKED;
++      }
+       return 0;
+ }
+ __initcall(init);
+Index: linux-2.6.0-test5/kernel/ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/ksyms.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/ksyms.c   2003-09-27 11:38:41.267254808 +0800
+@@ -126,11 +126,11 @@
+ 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
+@@ -221,6 +221,7 @@
+ 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);
+@@ -348,8 +349,6 @@
+ EXPORT_SYMBOL(unlock_page);
+ /* device registration */
+-EXPORT_SYMBOL(register_chrdev);
+-EXPORT_SYMBOL(unregister_chrdev);
+ EXPORT_SYMBOL(register_blkdev);
+ EXPORT_SYMBOL(unregister_blkdev);
+ EXPORT_SYMBOL(tty_register_driver);
+@@ -609,6 +608,16 @@
+ 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);
+Index: linux-2.6.0-test5/kernel/lockmeter.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/lockmeter.c  2003-09-27 11:38:18.488717672 +0800
++++ linux-2.6.0-test5/kernel/lockmeter.c       2003-09-27 11:38:41.269254504 +0800
+@@ -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
+Index: linux-2.6.0-test5/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/Makefile     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/Makefile  2003-09-27 11:38:41.271254200 +0800
+@@ -11,6 +11,7 @@
+ 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
+@@ -18,6 +19,7 @@
+ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
+ obj-$(CONFIG_COMPAT) += compat.o
+ obj-$(CONFIG_IKCONFIG) += configs.o
++obj-$(CONFIG_IKCONFIG_PROC) += configs.o
+ ifneq ($(CONFIG_IA64),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+@@ -28,12 +30,32 @@
+ CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer
+ endif
++# configs.o uses generated files - dependecies must be listed explicitly
++$(obj)/configs.o: $(obj)/ikconfig.h
++
++ifdef CONFIG_IKCONFIG_PROC
++$(obj)/configs.o: $(obj)/config_data.h
++endif
++
++# ikconfig.h contains all the selected config entries - generated
++# from top-level Makefile and .config. Info from ikconfig.h can
++# be extracted from the kernel binary.
++
+ quiet_cmd_ikconfig = IKCFG   $@
+       cmd_ikconfig = $(CONFIG_SHELL) $< .config $(srctree)/Makefile > $@
+ targets += ikconfig.h
+-
+ $(obj)/ikconfig.h: scripts/mkconfigs .config Makefile FORCE
+       $(call if_changed,ikconfig)
+-$(obj)/configs.o: $(obj)/ikconfig.h
++# config_data.h contains the same information as ikconfig.h but gzipped.
++# Info from config_data can be extracted from /proc/config*
++targets += config_data.gz
++$(obj)/config_data.gz: .config FORCE
++      $(call if_changed,gzip)
++
++quiet_cmd_ikconfiggz = IKCFG   $@
++      cmd_ikconfiggz = cat $< | scripts/bin2c kernel_config_data > $@
++targets += config_data.h
++$(obj)/config_data.h: $(obj)/config_data.gz FORCE
++      $(call if_changed,ikconfiggz)
+Index: linux-2.6.0-test5/kernel/pid.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/pid.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/pid.c     2003-09-27 11:38:41.274253744 +0800
+@@ -250,13 +250,13 @@
+       attach_pid(thread, PIDTYPE_PID, thread->pid);
+       attach_pid(thread, PIDTYPE_TGID, thread->tgid);
+-      attach_pid(thread, PIDTYPE_PGID, thread->pgrp);
++      attach_pid(thread, PIDTYPE_PGID, leader->__pgrp);
+       attach_pid(thread, PIDTYPE_SID, thread->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_PGID, leader->__pgrp);
+       attach_pid(leader, PIDTYPE_SID, leader->session);
+ }
+@@ -265,6 +265,9 @@
+  * 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 @@
+               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)
+Index: linux-2.6.0-test5/kernel/posix-timers.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/posix-timers.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/posix-timers.c    2003-09-27 11:38:41.283252376 +0800
+@@ -344,6 +344,7 @@
+               return NULL;
+       if ((event->sigev_notify & ~SIGEV_NONE & MIPS_SIGEV) &&
++                      event->sigev_signo &&
+                       ((unsigned) (event->sigev_signo > SIGRTMAX)))
+               return NULL;
+Index: linux-2.6.0-test5/kernel/power/console.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/console.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/console.c   2003-09-27 11:38:41.284252224 +0800
+@@ -8,7 +8,7 @@
+ #include <linux/kbd_kern.h>
+ #include "power.h"
+-static int new_loglevel = 7;
++static int new_loglevel = 10;
+ static int orig_loglevel;
+ static int orig_fgconsole, orig_kmsg;
+Index: linux-2.6.0-test5/kernel/power/disk.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/disk.c 2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/kernel/power/disk.c      2003-09-27 11:38:41.285252072 +0800
+@@ -0,0 +1,335 @@
++/*
++ * kernel/power/disk.c - Suspend-to-disk support.
++ *
++ * Copyright (c) 2003 Patrick Mochel
++ * Copyright (c) 2003 Open Source Development Lab
++ *
++ * This file is release under the GPLv2
++ *
++ */
++
++#define DEBUG
++
++
++#include <linux/suspend.h>
++#include <linux/reboot.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/fs.h>
++#include "power.h"
++
++
++extern u32 pm_disk_mode;
++extern struct pm_ops * pm_ops;
++
++extern int pmdisk_save(void);
++extern int pmdisk_write(void);
++extern int pmdisk_read(void);
++extern int pmdisk_restore(void);
++extern int pmdisk_free(void);
++
++extern long sys_sync(void);
++
++
++/**
++ *    power_down - Shut machine down for hibernate.
++ *    @mode:          Suspend-to-disk mode
++ *
++ *    Use the platform driver, if configured so, and return gracefully if it
++ *    fails.
++ *    Otherwise, try to power off and reboot. If they fail, halt the machine,
++ *    there ain't no turning back.
++ */
++
++static int power_down(u32 mode)
++{
++      unsigned long flags;
++      int error = 0;
++
++      local_irq_save(flags);
++      device_power_down(PM_SUSPEND_DISK);
++      switch(mode) {
++      case PM_DISK_PLATFORM:
++              error = pm_ops->enter(PM_SUSPEND_DISK);
++              break;
++      case PM_DISK_SHUTDOWN:
++              printk("Powering off system\n");
++              machine_power_off();
++              break;
++      case PM_DISK_REBOOT:
++              machine_restart(NULL);
++              break;
++      }
++      machine_halt();
++      device_power_up();
++      local_irq_restore(flags);
++      return 0;
++}
++
++
++static int in_suspend __nosavedata = 0;
++
++
++/**
++ *    free_some_memory -  Try to free as much memory as possible
++ *
++ *    ... but do not OOM-kill anyone
++ *
++ *    Notice: all userland should be stopped at this point, or
++ *    livelock is possible.
++ */
++
++static void free_some_memory(void)
++{
++      printk("Freeing memory: ");
++      while (shrink_all_memory(10000))
++              printk(".");
++      printk("|\n");
++      blk_run_queues();
++}
++
++
++static inline void platform_finish(void)
++{
++      if (pm_disk_mode == PM_DISK_PLATFORM) {
++              if (pm_ops && pm_ops->finish)
++                      pm_ops->finish(PM_SUSPEND_DISK);
++      }
++}
++
++static void finish(void)
++{
++      device_resume();
++      platform_finish();
++      thaw_processes();
++      pm_restore_console();
++}
++
++
++static int prepare(void)
++{
++      int error;
++
++      pm_prepare_console();
++
++      sys_sync();
++      if (freeze_processes()) {
++              error = -EBUSY;
++              goto Thaw;
++      }
++
++      if (pm_disk_mode == PM_DISK_PLATFORM) {
++              if (pm_ops && pm_ops->prepare) {
++                      if ((error = pm_ops->prepare(PM_SUSPEND_DISK)))
++                              goto Thaw;
++              }
++      }
++
++      /* Free memory before shutting down devices. */
++      free_some_memory();
++
++      if ((error = device_suspend(PM_SUSPEND_DISK)))
++              goto Finish;
++
++      return 0;
++ Finish:
++      platform_finish();
++ Thaw:
++      thaw_processes();
++      pm_restore_console();
++      return error;
++}
++
++
++/**
++ *    pm_suspend_disk - The granpappy of power management.
++ *
++ *    If we're going through the firmware, then get it over with quickly.
++ *
++ *    If not, then call pmdis to do it's thing, then figure out how
++ *    to power down the system.
++ */
++
++int pm_suspend_disk(void)
++{
++      int error;
++
++      if ((error = prepare()))
++              return error;
++
++      pr_debug("PM: Attempting to suspend to disk.\n");
++      if (pm_disk_mode == PM_DISK_FIRMWARE)
++              return pm_ops->enter(PM_SUSPEND_DISK);
++
++      pr_debug("PM: snapshotting memory.\n");
++      in_suspend = 1;
++      if ((error = pmdisk_save()))
++              goto Done;
++
++      if (in_suspend) {
++              pr_debug("PM: writing image.\n");
++
++              /*
++               * FIXME: Leftover from swsusp. Are they necessary?
++               */
++              mb();
++              barrier();
++
++              error = pmdisk_write();
++              if (!error) {
++                      error = power_down(pm_disk_mode);
++                      pr_debug("PM: Power down failed.\n");
++              }
++      } else
++              pr_debug("PM: Image restored successfully.\n");
++      pmdisk_free();
++ Done:
++      finish();
++      return error;
++}
++
++
++/**
++ *    pm_resume - Resume from a saved image.
++ *
++ *    Called as a late_initcall (so all devices are discovered and
++ *    initialized), we call pmdisk to see if we have a saved image or not.
++ *    If so, we quiesce devices, the restore the saved image. We will
++ *    return above (in pm_suspend_disk() ) if everything goes well.
++ *    Otherwise, we fail gracefully and return to the normally
++ *    scheduled program.
++ *
++ */
++
++static int pm_resume(void)
++{
++      int error;
++
++      pr_debug("PM: Reading pmdisk image.\n");
++
++      if ((error = pmdisk_read()))
++              goto Done;
++
++      pr_debug("PM: Preparing system for restore.\n");
++
++      if ((error = prepare()))
++              goto Free;
++
++      barrier();
++      mb();
++
++      /* FIXME: The following (comment and mdelay()) are from swsusp.
++       * Are they really necessary?
++       *
++       * We do not want some readahead with DMA to corrupt our memory, right?
++       * Do it with disabled interrupts for best effect. That way, if some
++       * driver scheduled DMA, we have good chance for DMA to finish ;-).
++       */
++      pr_debug("PM: Waiting for DMAs to settle down.\n");
++      mdelay(1000);
++
++      pr_debug("PM: Restoring saved image.\n");
++      pmdisk_restore();
++      pr_debug("PM: Restore failed, recovering.n");
++      finish();
++ Free:
++      pmdisk_free();
++ Done:
++      pr_debug("PM: Resume from disk failed.\n");
++      return 0;
++}
++
++late_initcall(pm_resume);
++
++
++static char * pm_disk_modes[] = {
++      [PM_DISK_FIRMWARE]      = "firmware",
++      [PM_DISK_PLATFORM]      = "platform",
++      [PM_DISK_SHUTDOWN]      = "shutdown",
++      [PM_DISK_REBOOT]        = "reboot",
++};
++
++/**
++ *    disk - Control suspend-to-disk mode
++ *
++ *    Suspend-to-disk can be handled in several ways. The greatest
++ *    distinction is who writes memory to disk - the firmware or the OS.
++ *    If the firmware does it, we assume that it also handles suspending
++ *    the system.
++ *    If the OS does it, then we have three options for putting the system
++ *    to sleep - using the platform driver (e.g. ACPI or other PM registers),
++ *    powering off the system or rebooting the system (for testing).
++ *
++ *    The system will support either 'firmware' or 'platform', and that is
++ *    known a priori (and encoded in pm_ops). But, the user may choose
++ *    'shutdown' or 'reboot' as alternatives.
++ *
++ *    show() will display what the mode is currently set to.
++ *    store() will accept one of
++ *
++ *    'firmware'
++ *    'platform'
++ *    'shutdown'
++ *    'reboot'
++ *
++ *    It will only change to 'firmware' or 'platform' if the system
++ *    supports it (as determined from pm_ops->pm_disk_mode).
++ */
++
++static ssize_t disk_show(struct subsystem * subsys, char * buf)
++{
++      return sprintf(buf,"%s\n",pm_disk_modes[pm_disk_mode]);
++}
++
++
++static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n)
++{
++      int error = 0;
++      int i;
++      u32 mode = 0;
++
++      down(&pm_sem);
++      for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) {
++              if (!strcmp(buf,pm_disk_modes[i])) {
++                      mode = i;
++                      break;
++              }
++      }
++      if (mode) {
++              if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT)
++                      pm_disk_mode = mode;
++              else {
++                      if (pm_ops && pm_ops->enter &&
++                          (mode == pm_ops->pm_disk_mode))
++                              pm_disk_mode = mode;
++                      else
++                              error = -EINVAL;
++              }
++      } else
++              error = -EINVAL;
++
++      pr_debug("PM: suspend-to-disk mode set to '%s'\n",
++               pm_disk_modes[mode]);
++      up(&pm_sem);
++      return error ? error : n;
++}
++
++power_attr(disk);
++
++static struct attribute * g[] = {
++      &disk_attr.attr,
++      NULL,
++};
++
++
++static struct attribute_group attr_group = {
++      .attrs = g,
++};
++
++
++static int __init pm_disk_init(void)
++{
++      return sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
++}
++
++core_initcall(pm_disk_init);
+Index: linux-2.6.0-test5/kernel/power/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/Kconfig        2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/kernel/power/Kconfig     2003-09-27 11:38:41.286251920 +0800
+@@ -0,0 +1,92 @@
++config PM
++      bool "Power Management support"
++      ---help---
++        "Power Management" means that parts of your computer are shut
++        off or put into a power conserving "sleep" mode if they are not
++        being used.  There are two competing standards for doing this: APM
++        and ACPI.  If you want to use either one, say Y here and then also
++        to the requisite support below.
++
++        Power Management is most important for battery powered laptop
++        computers; if you have a laptop, check out the Linux Laptop home
++        page on the WWW at
++        <http://www.cs.utexas.edu/users/kharker/linux-laptop/> and the
++        Battery Powered Linux mini-HOWTO, available from
++        <http://www.tldp.org/docs.html#howto>.
++
++        Note that, even if you say N here, Linux on the x86 architecture
++        will issue the hlt instruction if nothing is to be done, thereby
++        sending the processor to sleep and saving power.
++
++config SOFTWARE_SUSPEND
++      bool "Software Suspend (EXPERIMENTAL)"
++      depends on EXPERIMENTAL && PM && SWAP
++      ---help---
++        Enable the possibilty of suspendig machine. It doesn't need APM.
++        You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 
++        (patch for sysvinit needed). 
++
++        It creates an image which is saved in your active swaps. By the next
++        booting the, pass 'resume=/dev/swappartition' and kernel will 
++        detect the saved image, restore the memory from
++        it and then it continues to run as before you've suspended.
++        If you don't want the previous state to continue use the 'noresume'
++        kernel option. However note that your partitions will be fsck'd and
++        you must re-mkswap your swap partitions. It does not work with swap
++        files.
++
++        Right now you may boot without resuming and then later resume but
++        in meantime you cannot use those swap partitions/files which were
++        involved in suspending. Also in this case there is a risk that buffers
++        on disk won't match with saved ones.
++
++        For more information take a look at Documentation/swsusp.txt.
++
++config PM_DISK
++      bool "Suspend-to-Disk Support"
++      depends on PM && SWAP
++      ---help---
++        Suspend-to-disk is a power management state in which the contents
++        of memory are stored on disk and the entire system is shut down or
++        put into a low-power state (e.g. ACPI S4). When the computer is 
++        turned back on, the stored image is loaded from disk and execution
++        resumes from where it left off before suspending. 
++
++        This config option enables the core infrastructure necessary to 
++        perform the suspend and resume transition. 
++
++        Currently, this suspend-to-disk implementation is based on a forked
++        version of the swsusp code base. As such, it's still experimental,
++        and still relies on CONFIG_SWAP. 
++
++        More information can be found in Documentation/power/.
++
++        If unsure, Say N.
++
++config PM_DISK_PARTITION
++      string "Default resume partition"
++      default ""
++      ---help---
++        The default resume partition is the partition that the pmdisk suspend-
++        to-disk implementation will look for a suspended disk image. 
++
++        The partition specified here will be different for almost every user. 
++        It should be a valid swap partition (at least for now) that is turned
++        on before suspending. 
++
++        The partition specified can be overridden by specifying:
++
++              pmdisk=/dev/<other device> 
++
++        which will set the resume partition to the device specified. 
++
++        One may also do: 
++
++              pmdisk=off
++
++        to inform the kernel not to perform a resume transition. 
++
++        Note there is currently not a way to specify which device to save the
++        suspended image to. It will simply pick the first available swap 
++        device.
++
+Index: linux-2.6.0-test5/kernel/power/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/main.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/main.c      2003-09-27 11:38:41.290251312 +0800
+@@ -8,32 +8,23 @@
+  *
+  */
++#define DEBUG
++
+ #include <linux/suspend.h>
+ #include <linux/kobject.h>
+-#include <linux/reboot.h>
+ #include <linux/string.h>
++#include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/pm.h>
+-#include <linux/fs.h>
+ #include "power.h"
+-static DECLARE_MUTEX(pm_sem);
+-
+-static struct pm_ops * pm_ops = NULL;
+-
+-static u32 pm_disk_mode = PM_DISK_SHUTDOWN;
+-
+-#ifdef CONFIG_SOFTWARE_SUSPEND
+-static int have_swsusp = 1;
+-#else
+-static int have_swsusp = 0;
+-#endif
+-
+-extern long sys_sync(void);
++DECLARE_MUTEX(pm_sem);
++struct pm_ops * pm_ops = NULL;
++u32 pm_disk_mode = PM_DISK_SHUTDOWN;
+ /**
+  *    pm_set_ops - Set the global power method table. 
+@@ -51,171 +42,6 @@
+ /**
+- *    pm_suspend_standby - Enter 'standby' state.
+- *    
+- *    'standby' is also known as 'Power-On Suspend'. Here, we power down
+- *    devices, disable interrupts, and enter the state.
+- */
+-
+-static int pm_suspend_standby(void)
+-{
+-      int error = 0;
+-      unsigned long flags;
+-
+-      if (!pm_ops || !pm_ops->enter)
+-              return -EPERM;
+-
+-      local_irq_save(flags);
+-      if ((error = device_power_down(PM_SUSPEND_STANDBY)))
+-              goto Done;
+-      error = pm_ops->enter(PM_SUSPEND_STANDBY);
+-      local_irq_restore(flags);
+-      device_power_up();
+- Done:
+-      return error;
+-}
+-
+-
+-/**
+- *    pm_suspend_mem - Enter suspend-to-RAM state.
+- *
+- *    Identical to pm_suspend_standby() - we power down devices, disable 
+- *    interrupts, and enter the low-power state.
+- */
+-
+-static int pm_suspend_mem(void)
+-{
+-      int error = 0;
+-      unsigned long flags;
+-
+-      if (!pm_ops || !pm_ops->enter)
+-              return -EPERM;
+-
+-      local_irq_save(flags);
+-      if ((error = device_power_down(PM_SUSPEND_STANDBY)))
+-              goto Done;
+-      error = pm_ops->enter(PM_SUSPEND_STANDBY);
+-      local_irq_restore(flags);
+-      device_power_up();
+- Done:
+-      return error;
+-}
+-
+-
+-/**
+- *    power_down - Shut machine down for hibernate.
+- *    @mode:          Suspend-to-disk mode
+- *
+- *    Use the platform driver, if configured so, and return gracefully if it
+- *    fails. 
+- *    Otherwise, try to power off and reboot. If they fail, halt the machine,
+- *    there ain't no turning back.
+- */
+-
+-static int power_down(u32 mode)
+-{
+-      unsigned long flags;
+-      int error = 0;
+-
+-      local_irq_save(flags);
+-      device_power_down(PM_SUSPEND_DISK);
+-      switch(mode) {
+-      case PM_DISK_PLATFORM:
+-              error = pm_ops->enter(PM_SUSPEND_DISK);
+-              if (error) {
+-                      device_power_up();
+-                      local_irq_restore(flags);
+-                      return error;
+-              }
+-      case PM_DISK_SHUTDOWN:
+-              machine_power_off();
+-              break;
+-      case PM_DISK_REBOOT:
+-              machine_restart(NULL);
+-              break;
+-      }
+-      machine_halt();
+-      return 0;
+-}
+-
+-
+-static int in_suspend __nosavedata = 0;
+-
+-
+-/**
+- *    free_some_memory -  Try to free as much memory as possible
+- *
+- *    ... but do not OOM-kill anyone
+- *
+- *    Notice: all userland should be stopped at this point, or 
+- *    livelock is possible.
+- */
+-
+-static void free_some_memory(void)
+-{
+-      printk("Freeing memory: ");
+-      while (shrink_all_memory(10000))
+-              printk(".");
+-      printk("|\n");
+-      blk_run_queues();
+-}
+-
+-
+-/**
+- *    pm_suspend_disk - The granpappy of power management.
+- *    
+- *    If we're going through the firmware, then get it over with quickly.
+- *
+- *    If not, then call swsusp to do it's thing, then figure out how
+- *    to power down the system.
+- */
+-
+-static int pm_suspend_disk(void)
+-{
+-      int error;
+-
+-      pr_debug("PM: Attempting to suspend to disk.\n");
+-      if (pm_disk_mode == PM_DISK_FIRMWARE)
+-              return pm_ops->enter(PM_SUSPEND_DISK);
+-
+-      if (!have_swsusp)
+-              return -EPERM;
+-
+-      pr_debug("PM: snapshotting memory.\n");
+-      in_suspend = 1;
+-      if ((error = swsusp_save()))
+-              goto Done;
+-
+-      if (in_suspend) {
+-              pr_debug("PM: writing image.\n");
+-              error = swsusp_write();
+-              if (!error)
+-                      error = power_down(pm_disk_mode);
+-              pr_debug("PM: Power down failed.\n");
+-      } else
+-              pr_debug("PM: Image restored successfully.\n");
+-      swsusp_free();
+- Done:
+-      return error;
+-}
+-
+-
+-
+-#define decl_state(_name) \
+-      { .name = __stringify(_name), .fn = pm_suspend_##_name }
+-
+-struct pm_state {
+-      char * name;
+-      int (*fn)(void);
+-} pm_states[] = {
+-      [PM_SUSPEND_STANDBY]    = decl_state(standby),
+-      [PM_SUSPEND_MEM]        = decl_state(mem),
+-      [PM_SUSPEND_DISK]       = decl_state(disk),
+-      { NULL },
+-};
+-
+-
+-/**
+  *    suspend_prepare - Do prep work before entering low-power state.
+  *    @state:         State we're entering.
+  *
+@@ -228,36 +54,47 @@
+ {
+       int error = 0;
++      if (!pm_ops || !pm_ops->enter)
++              return -EPERM;
++
+       pm_prepare_console();
+-      sys_sync();
+       if (freeze_processes()) {
+               error = -EAGAIN;
+               goto Thaw;
+       }
+-      if (pm_ops && pm_ops->prepare) {
++      if (pm_ops->prepare) {
+               if ((error = pm_ops->prepare(state)))
+                       goto Thaw;
+       }
+-      /* Free memory before shutting down devices. */
+-      if (state == PM_SUSPEND_DISK)
+-              free_some_memory();
+-
+       if ((error = device_suspend(state)))
+               goto Finish;
+-
+       return 0;
+- Done:
+-      pm_restore_console();
+-      return error;
+  Finish:
+-      if (pm_ops && pm_ops->finish)
++      if (pm_ops->finish)
+               pm_ops->finish(state);
+  Thaw:
+       thaw_processes();
+-      goto Done;
++      pm_restore_console();
++      return error;
++}
++
++
++static int suspend_enter(u32 state)
++{
++      int error = 0;
++      unsigned long flags;
++
++      local_irq_save(flags);
++      if ((error = device_power_down(state)))
++              goto Done;
++      error = pm_ops->enter(state);
++      device_power_up();
++ Done:
++      local_irq_restore(flags);
++      return error;
+ }
+@@ -279,6 +116,16 @@
+ }
++
++
++char * pm_states[] = {
++      [PM_SUSPEND_STANDBY]    = "standby",
++      [PM_SUSPEND_MEM]        = "mem",
++      [PM_SUSPEND_DISK]       = "disk",
++      NULL,
++};
++
++
+ /**
+  *    enter_state - Do common work of entering low-power state.
+  *    @state:         pm_state structure for state we're entering.
+@@ -293,7 +140,6 @@
+ static int enter_state(u32 state)
+ {
+       int error;
+-      struct pm_state * s = &pm_states[state];
+       if (down_trylock(&pm_sem))
+               return -EBUSY;
+@@ -304,12 +150,17 @@
+               goto Unlock;
+       }
+-      pr_debug("PM: Preparing system for suspend.\n");
++      if (state == PM_SUSPEND_DISK) {
++              error = pm_suspend_disk();
++              goto Unlock;
++      }
++
++      pr_debug("PM: Preparing system for suspend\n");
+       if ((error = suspend_prepare(state)))
+               goto Unlock;
+       pr_debug("PM: Entering state.\n");
+-      error = s->fn();
++      error = suspend_enter(state);
+       pr_debug("PM: Finishing up.\n");
+       suspend_finish(state);
+@@ -335,138 +186,10 @@
+ }
+-/**
+- *    pm_resume - Resume from a saved image.
+- *
+- *    Called as a late_initcall (so all devices are discovered and 
+- *    initialized), we call swsusp to see if we have a saved image or not.
+- *    If so, we quiesce devices, the restore the saved image. We will 
+- *    return above (in pm_suspend_disk() ) if everything goes well. 
+- *    Otherwise, we fail gracefully and return to the normally 
+- *    scheduled program.
+- *
+- */
+-
+-static int pm_resume(void)
+-{
+-      int error;
+-
+-      if (!have_swsusp)
+-              return 0;
+-
+-      pr_debug("PM: Reading swsusp image.\n");
+-
+-      if ((error = swsusp_read()))
+-              goto Done;
+-
+-      pr_debug("PM: Preparing system for restore.\n");
+-
+-      if ((error = suspend_prepare(PM_SUSPEND_DISK)))
+-              goto Free;
+-
+-      pr_debug("PM: Restoring saved image.\n");
+-      swsusp_restore();
+-
+-      pr_debug("PM: Restore failed, recovering.n");
+-      suspend_finish(PM_SUSPEND_DISK);
+- Free:
+-      swsusp_free();
+- Done:
+-      pr_debug("PM: Resume from disk failed.\n");
+-      return 0;
+-}
+-
+-late_initcall(pm_resume);
+-
+ decl_subsys(power,NULL,NULL);
+-#define power_attr(_name) \
+-static struct subsys_attribute _name##_attr = {       \
+-      .attr   = {                             \
+-              .name = __stringify(_name),     \
+-              .mode = 0644,                   \
+-      },                                      \
+-      .show   = _name##_show,                 \
+-      .store  = _name##_store,                \
+-}
+-
+-
+-static char * pm_disk_modes[] = {
+-      [PM_DISK_FIRMWARE]      = "firmware",
+-      [PM_DISK_PLATFORM]      = "platform",
+-      [PM_DISK_SHUTDOWN]      = "shutdown",
+-      [PM_DISK_REBOOT]        = "reboot",
+-};
+-
+-/**
+- *    disk - Control suspend-to-disk mode
+- *
+- *    Suspend-to-disk can be handled in several ways. The greatest 
+- *    distinction is who writes memory to disk - the firmware or the OS.
+- *    If the firmware does it, we assume that it also handles suspending 
+- *    the system.
+- *    If the OS does it, then we have three options for putting the system
+- *    to sleep - using the platform driver (e.g. ACPI or other PM registers),
+- *    powering off the system or rebooting the system (for testing). 
+- *
+- *    The system will support either 'firmware' or 'platform', and that is
+- *    known a priori (and encoded in pm_ops). But, the user may choose
+- *    'shutdown' or 'reboot' as alternatives.
+- *
+- *    show() will display what the mode is currently set to. 
+- *    store() will accept one of
+- *
+- *    'firmware'
+- *    'platform'
+- *    'shutdown'
+- *    'reboot'
+- *
+- *    It will only change to 'firmware' or 'platform' if the system
+- *    supports it (as determined from pm_ops->pm_disk_mode).
+- */
+-
+-static ssize_t disk_show(struct subsystem * subsys, char * buf)
+-{
+-      return sprintf(buf,"%s\n",pm_disk_modes[pm_disk_mode]);
+-}
+-
+-
+-static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n)
+-{
+-      int error = 0;
+-      int i;
+-      u32 mode = 0;
+-
+-      down(&pm_sem);
+-      for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) {
+-              if (!strcmp(buf,pm_disk_modes[i])) {
+-                      mode = i;
+-                      break;
+-              }
+-      }
+-      if (mode) {
+-              if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT)
+-                      pm_disk_mode = mode;
+-              else {
+-                      if (pm_ops && pm_ops->enter && 
+-                          (mode == pm_ops->pm_disk_mode))
+-                              pm_disk_mode = mode;
+-                      else
+-                              error = -EINVAL;
+-              }
+-      } else
+-              error = -EINVAL;
+-
+-      pr_debug("PM: suspend-to-disk mode set to '%s'\n",
+-               pm_disk_modes[mode]);
+-      up(&pm_sem);
+-      return error ? error : n;
+-}
+-
+-power_attr(disk);
+-
+ /**
+  *    state - control system power state.
+  *
+@@ -480,27 +203,28 @@
+ static ssize_t state_show(struct subsystem * subsys, char * buf)
+ {
+-      struct pm_state * state;
++      int i;
+       char * s = buf;
+-      for (state = &pm_states[0]; state->name; state++)
+-              s += sprintf(s,"%s ",state->name);
++      for (i = 0; i < PM_SUSPEND_MAX; i++) {
++              if (pm_states[i])
++                      s += sprintf(s,"%s ",pm_states[i]);
++      }
+       s += sprintf(s,"\n");
+       return (s - buf);
+ }
+ static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n)
+ {
+-      u32 state;
+-      struct pm_state * s;
++      u32 state = PM_SUSPEND_STANDBY;
++      char ** s;
+       int error;
+-      for (state = 0; state < PM_SUSPEND_MAX; state++) {
+-              s = &pm_states[state];
+-              if (s->name && !strcmp(buf,s->name))
++      for (s = &pm_states[state]; *s; s++, state++) {
++              if (!strcmp(buf,*s))
+                       break;
+       }
+-      if (s)
++      if (*s)
+               error = enter_state(state);
+       else
+               error = -EINVAL;
+@@ -511,7 +235,6 @@
+ static struct attribute * g[] = {
+       &state_attr.attr,
+-      &disk_attr.attr,
+       NULL,
+ };
+@@ -520,7 +243,7 @@
+ };
+-static int pm_init(void)
++static int __init pm_init(void)
+ {
+       int error = subsystem_register(&power_subsys);
+       if (!error)
+Index: linux-2.6.0-test5/kernel/power/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/Makefile       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/Makefile    2003-09-27 11:38:41.291251160 +0800
+@@ -1,4 +1,5 @@
+ obj-y                         := main.o process.o console.o pm.o
+ obj-$(CONFIG_SOFTWARE_SUSPEND)        += swsusp.o
++obj-$(CONFIG_PM_DISK)         += disk.o pmdisk.o
+ obj-$(CONFIG_MAGIC_SYSRQ)     += poweroff.o
+Index: linux-2.6.0-test5/kernel/power/pmdisk.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/pmdisk.c       2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/kernel/power/pmdisk.c    2003-09-27 11:38:41.293250856 +0800
+@@ -0,0 +1,942 @@
++/*
++ * kernel/power/pmdisk.c - Suspend-to-disk implmentation
++ *
++ * This STD implementation is initially derived from swsusp (suspend-to-swap).
++ * The original copyright on that was: 
++ *
++ * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
++ * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz>
++ *
++ * The additional parts are: 
++ * 
++ * Copyright (C) 2003 Patrick Mochel
++ * Copyright (C) 2003 Open Source Development Lab
++ * 
++ * This file is released under the GPLv2. 
++ *
++ * For more information, please see the text files in Documentation/power/
++ *
++ */
++
++#include <linux/mm.h>
++#include <linux/bio.h>
++#include <linux/suspend.h>
++#include <linux/version.h>
++#include <linux/reboot.h>
++#include <linux/device.h>
++#include <linux/swapops.h>
++#include <linux/bootmem.h>
++
++#include <asm/mmu_context.h>
++
++#include "power.h"
++
++
++extern int pmdisk_arch_suspend(int resume);
++
++#define __ADDRESS(x)  ((unsigned long) phys_to_virt(x))
++#define ADDRESS(x) __ADDRESS((x) << PAGE_SHIFT)
++#define ADDRESS2(x) __ADDRESS(__pa(x))                /* Needed for x86-64 where some pages are in memory twice */
++
++/* References to section boundaries */
++extern char __nosave_begin, __nosave_end;
++
++extern int is_head_of_free_region(struct page *);
++
++/* Variables to be preserved over suspend */
++static int pagedir_order_check;
++static int nr_copy_pages_check;
++
++/* For resume= kernel option */
++static char resume_file[256] = CONFIG_PM_DISK_PARTITION;
++
++static dev_t resume_device;
++/* Local variables that should not be affected by save */
++unsigned int pmdisk_pages __nosavedata = 0;
++
++/* Suspend pagedir is allocated before final copy, therefore it
++   must be freed after resume 
++
++   Warning: this is evil. There are actually two pagedirs at time of
++   resume. One is "pagedir_save", which is empty frame allocated at
++   time of suspend, that must be freed. Second is "pagedir_nosave", 
++   allocated at time of resume, that travels through memory not to
++   collide with anything.
++ */
++suspend_pagedir_t *pm_pagedir_nosave __nosavedata = NULL;
++static suspend_pagedir_t *pagedir_save;
++static int pagedir_order __nosavedata = 0;
++
++struct link {
++      char dummy[PAGE_SIZE - sizeof(swp_entry_t)];
++      swp_entry_t next;
++};
++
++union diskpage {
++      union swap_header swh;
++      struct link link;
++      struct suspend_header sh;
++};
++
++/*
++ * XXX: We try to keep some more pages free so that I/O operations succeed
++ * without paging. Might this be more?
++ */
++#define PAGES_FOR_IO  512
++
++static const char name_suspend[] = "Suspend Machine: ";
++static const char name_resume[] = "Resume Machine: ";
++
++/*
++ * Debug
++ */
++#define       DEBUG_DEFAULT
++#undef        DEBUG_PROCESS
++#undef        DEBUG_SLOW
++#define TEST_SWSUSP 0         /* Set to 1 to reboot instead of halt machine after suspension */
++
++#ifdef DEBUG_DEFAULT
++# define PRINTK(f, a...)       printk(f, ## a)
++#else
++# define PRINTK(f, a...)
++#endif
++
++#ifdef DEBUG_SLOW
++#define MDELAY(a) mdelay(a)
++#else
++#define MDELAY(a)
++#endif
++
++/*
++ * Saving part...
++ */
++
++static __inline__ int fill_suspend_header(struct suspend_header *sh)
++{
++      memset((char *)sh, 0, sizeof(*sh));
++
++      sh->version_code = LINUX_VERSION_CODE;
++      sh->num_physpages = num_physpages;
++      strncpy(sh->machine, system_utsname.machine, 8);
++      strncpy(sh->version, system_utsname.version, 20);
++      /* FIXME: Is this bogus? --RR */
++      sh->num_cpus = num_online_cpus();
++      sh->page_size = PAGE_SIZE;
++      sh->suspend_pagedir = pm_pagedir_nosave;
++      BUG_ON (pagedir_save != pm_pagedir_nosave);
++      sh->num_pbes = pmdisk_pages;
++      /* TODO: needed? mounted fs' last mounted date comparison
++       * [so they haven't been mounted since last suspend.
++       * Maybe it isn't.] [we'd need to do this for _all_ fs-es]
++       */
++      return 0;
++}
++
++/* We memorize in swapfile_used what swap devices are used for suspension */
++#define SWAPFILE_UNUSED    0
++#define SWAPFILE_SUSPEND   1  /* This is the suspending device */
++#define SWAPFILE_IGNORED   2  /* Those are other swap devices ignored for suspension */
++
++static unsigned short swapfile_used[MAX_SWAPFILES];
++static unsigned short root_swap;
++#define MARK_SWAP_SUSPEND 0
++#define MARK_SWAP_RESUME 2
++
++static void mark_swapfiles(swp_entry_t prev, int mode)
++{
++      swp_entry_t entry;
++      union diskpage *cur;
++      struct page *page;
++
++      if (root_swap == 0xFFFF)  /* ignored */
++              return;
++
++      page = alloc_page(GFP_ATOMIC);
++      if (!page)
++              panic("Out of memory in mark_swapfiles");
++      cur = page_address(page);
++      /* XXX: this is dirty hack to get first page of swap file */
++      entry = swp_entry(root_swap, 0);
++      rw_swap_page_sync(READ, entry, page);
++
++      if (mode == MARK_SWAP_RESUME) {
++              if (!memcmp("S1",cur->swh.magic.magic,2))
++                      memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
++              else if (!memcmp("S2",cur->swh.magic.magic,2))
++                      memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
++              else printk("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
++                      name_resume, cur->swh.magic.magic);
++      } else {
++              if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)))
++                      memcpy(cur->swh.magic.magic,"S1SUSP....",10);
++              else if ((!memcmp("SWAPSPACE2",cur->swh.magic.magic,10)))
++                      memcpy(cur->swh.magic.magic,"S2SUSP....",10);
++              else panic("\nSwapspace is not swapspace (%.10s)\n", cur->swh.magic.magic);
++              cur->link.next = prev; /* prev is the first/last swap page of the resume area */
++              /* link.next lies *no more* in last 4/8 bytes of magic */
++      }
++      rw_swap_page_sync(WRITE, entry, page);
++      __free_page(page);
++}
++
++static void read_swapfiles(void) /* This is called before saving image */
++{
++      int i, len;
++      
++      len=strlen(resume_file);
++      root_swap = 0xFFFF;
++      
++      swap_list_lock();
++      for(i=0; i<MAX_SWAPFILES; i++) {
++              if (swap_info[i].flags == 0) {
++                      swapfile_used[i]=SWAPFILE_UNUSED;
++              } else {
++                      if(!len) {
++                              printk(KERN_WARNING "resume= option should be used to set suspend device" );
++                              if(root_swap == 0xFFFF) {
++                                      swapfile_used[i] = SWAPFILE_SUSPEND;
++                                      root_swap = i;
++                              } else
++                                      swapfile_used[i] = SWAPFILE_IGNORED;                              
++                      } else {
++                              /* we ignore all swap devices that are not the resume_file */
++                              if (1) {
++// FIXME                              if(resume_device == swap_info[i].swap_device) {
++                                      swapfile_used[i] = SWAPFILE_SUSPEND;
++                                      root_swap = i;
++                              } else {
++#if 0
++                                      printk( "Resume: device %s (%x != %x) ignored\n", swap_info[i].swap_file->d_name.name, swap_info[i].swap_device, resume_device );                                 
++#endif
++                                      swapfile_used[i] = SWAPFILE_IGNORED;
++                              }
++                      }
++              }
++      }
++      swap_list_unlock();
++}
++
++static void lock_swapdevices(void) /* This is called after saving image so modification
++                                    will be lost after resume... and that's what we want. */
++{
++      int i;
++
++      swap_list_lock();
++      for(i = 0; i< MAX_SWAPFILES; i++)
++              if(swapfile_used[i] == SWAPFILE_IGNORED) {
++                      swap_info[i].flags ^= 0xFF; /* we make the device unusable. A new call to
++                                                     lock_swapdevices can unlock the devices. */
++              }
++      swap_list_unlock();
++}
++
++static int write_suspend_image(void)
++{
++      int i;
++      swp_entry_t entry, prev = { 0 };
++      int nr_pgdir_pages = SUSPEND_PD_PAGES(pmdisk_pages);
++      union diskpage *cur,  *buffer = (union diskpage *)get_zeroed_page(GFP_ATOMIC);
++      unsigned long address;
++      struct page *page;
++
++      printk( "Writing data to swap (%d pages): ", pmdisk_pages );
++      for (i=0; i<pmdisk_pages; i++) {
++              if (!(i%100))
++                      printk( "." );
++              if (!(entry = get_swap_page()).val)
++                      panic("\nNot enough swapspace when writing data" );
++              
++              if (swapfile_used[swp_type(entry)] != SWAPFILE_SUSPEND)
++                      panic("\nPage %d: not enough swapspace on suspend device", i );
++          
++              address = (pm_pagedir_nosave+i)->address;
++              page = virt_to_page(address);
++              rw_swap_page_sync(WRITE, entry, page);
++              (pm_pagedir_nosave+i)->swap_address = entry;
++      }
++      printk( "|\n" );
++      printk( "Writing pagedir (%d pages): ", nr_pgdir_pages);
++      for (i=0; i<nr_pgdir_pages; i++) {
++              cur = (union diskpage *)((char *) pm_pagedir_nosave)+i;
++              BUG_ON ((char *) cur != (((char *) pm_pagedir_nosave) + i*PAGE_SIZE));
++              printk( "." );
++              if (!(entry = get_swap_page()).val) {
++                      printk(KERN_CRIT "Not enough swapspace when writing pgdir\n" );
++                      panic("Don't know how to recover");
++                      free_page((unsigned long) buffer);
++                      return -ENOSPC;
++              }
++
++              if(swapfile_used[swp_type(entry)] != SWAPFILE_SUSPEND)
++                      panic("\nNot enough swapspace for pagedir on suspend device" );
++
++              BUG_ON (sizeof(swp_entry_t) != sizeof(long));
++              BUG_ON (PAGE_SIZE % sizeof(struct pbe));
++
++              cur->link.next = prev;                          
++              page = virt_to_page((unsigned long)cur);
++              rw_swap_page_sync(WRITE, entry, page);
++              prev = entry;
++      }
++      printk("H");
++      BUG_ON (sizeof(struct suspend_header) > PAGE_SIZE-sizeof(swp_entry_t));
++      BUG_ON (sizeof(union diskpage) != PAGE_SIZE);
++      if (!(entry = get_swap_page()).val)
++              panic( "\nNot enough swapspace when writing header" );
++      if (swapfile_used[swp_type(entry)] != SWAPFILE_SUSPEND)
++              panic("\nNot enough swapspace for header on suspend device" );
++
++      cur = (void *) buffer;
++      if (fill_suspend_header(&cur->sh))
++              panic("\nOut of memory while writing header");
++              
++      cur->link.next = prev;
++
++      page = virt_to_page((unsigned long)cur);
++      rw_swap_page_sync(WRITE, entry, page);
++      prev = entry;
++
++      printk( "S" );
++      mark_swapfiles(prev, MARK_SWAP_SUSPEND);
++      printk( "|\n" );
++
++      MDELAY(1000);
++      free_page((unsigned long) buffer);
++      return 0;
++}
++
++/* if pagedir_p != NULL it also copies the counted pages */
++static int count_and_copy_data_pages(struct pbe *pagedir_p)
++{
++      int chunk_size;
++      int nr_copy_pages = 0;
++      int pfn;
++      struct page *page;
++      
++      BUG_ON (max_pfn != num_physpages);
++
++      for (pfn = 0; pfn < max_pfn; pfn++) {
++              page = pfn_to_page(pfn);
++
++              if (!PageReserved(page)) {
++                      if (PageNosave(page))
++                              continue;
++
++                      if ((chunk_size=is_head_of_free_region(page))!=0) {
++                              pfn += chunk_size - 1;
++                              continue;
++                      }
++              } else if (PageReserved(page)) {
++                      BUG_ON (PageNosave(page));
++
++                      /*
++                       * Just copy whole code segment. Hopefully it is not that big.
++                       */
++                      if ((ADDRESS(pfn) >= (unsigned long) ADDRESS2(&__nosave_begin)) && 
++                          (ADDRESS(pfn) <  (unsigned long) ADDRESS2(&__nosave_end))) {
++                              PRINTK("[nosave %lx]", ADDRESS(pfn));
++                              continue;
++                      }
++                      /* Hmm, perhaps copying all reserved pages is not too healthy as they may contain 
++                         critical bios data? */
++              } else  BUG();
++
++              nr_copy_pages++;
++              if (pagedir_p) {
++                      pagedir_p->orig_address = ADDRESS(pfn);
++                      copy_page((void *) pagedir_p->address, (void *) pagedir_p->orig_address);
++                      pagedir_p++;
++              }
++      }
++      return nr_copy_pages;
++}
++
++static void free_suspend_pagedir(unsigned long this_pagedir)
++{
++      struct page *page;
++      int pfn;
++      unsigned long this_pagedir_end = this_pagedir +
++              (PAGE_SIZE << pagedir_order);
++
++      for(pfn = 0; pfn < num_physpages; pfn++) {
++              page = pfn_to_page(pfn);
++              if (!TestClearPageNosave(page))
++                      continue;
++
++              if (ADDRESS(pfn) >= this_pagedir && ADDRESS(pfn) < this_pagedir_end)
++                      continue; /* old pagedir gets freed in one */
++              
++              free_page(ADDRESS(pfn));
++      }
++      free_pages(this_pagedir, pagedir_order);
++}
++
++static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages)
++{
++      int i;
++      suspend_pagedir_t *pagedir;
++      struct pbe *p;
++      struct page *page;
++
++      pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));
++
++      p = pagedir = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC | __GFP_COLD, pagedir_order);
++      if(!pagedir)
++              return NULL;
++
++      page = virt_to_page(pagedir);
++      for(i=0; i < 1<<pagedir_order; i++)
++              SetPageNosave(page++);
++              
++      while(nr_copy_pages--) {
++              p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
++              if(!p->address) {
++                      free_suspend_pagedir((unsigned long) pagedir);
++                      return NULL;
++              }
++              SetPageNosave(virt_to_page(p->address));
++              p->orig_address = 0;
++              p++;
++      }
++      return pagedir;
++}
++
++
++int pmdisk_suspend(void)
++{
++      struct sysinfo i;
++      unsigned int nr_needed_pages = 0;
++
++      read_swapfiles();
++      drain_local_pages();
++
++      pm_pagedir_nosave = NULL;
++      printk( "/critical section: Counting pages to copy" );
++      pmdisk_pages = count_and_copy_data_pages(NULL);
++      nr_needed_pages = pmdisk_pages + PAGES_FOR_IO;
++      
++      printk(" (pages needed: %d+%d=%d free: %d)\n",pmdisk_pages,PAGES_FOR_IO,nr_needed_pages,nr_free_pages());
++      if(nr_free_pages() < nr_needed_pages) {
++              printk(KERN_CRIT "%sCouldn't get enough free pages, on %d pages short\n",
++                     name_suspend, nr_needed_pages-nr_free_pages());
++              root_swap = 0xFFFF;
++              return 1;
++      }
++      si_swapinfo(&i);        /* FIXME: si_swapinfo(&i) returns all swap devices information.
++                                 We should only consider resume_device. */
++      if (i.freeswap < nr_needed_pages)  {
++              printk(KERN_CRIT "%sThere's not enough swap space available, on %ld pages short\n",
++                     name_suspend, nr_needed_pages-i.freeswap);
++              return 1;
++      }
++
++      PRINTK( "Alloc pagedir\n" ); 
++      pagedir_save = pm_pagedir_nosave = create_suspend_pagedir(pmdisk_pages);
++      if(!pm_pagedir_nosave) {
++              /* Shouldn't happen */
++              printk(KERN_CRIT "%sCouldn't allocate enough pages\n",name_suspend);
++              panic("Really should not happen");
++              return 1;
++      }
++      nr_copy_pages_check = pmdisk_pages;
++      pagedir_order_check = pagedir_order;
++
++      drain_local_pages();    /* During allocating of suspend pagedir, new cold pages may appear. Kill them */
++      if (pmdisk_pages != count_and_copy_data_pages(pm_pagedir_nosave))       /* copy */
++              BUG();
++
++      /*
++       * End of critical section. From now on, we can write to memory,
++       * but we should not touch disk. This specially means we must _not_
++       * touch swap space! Except we must write out our image of course.
++       */
++
++      printk( "critical section/: done (%d pages copied)\n", pmdisk_pages );
++      return 0;
++}
++
++
++/**
++ *    suspend_save_image - Prepare and write saved image to swap.
++ *
++ *    IRQs are re-enabled here so we can resume devices and safely write
++ *    to the swap devices. We disable them again before we leave.
++ *
++ *    The second lock_swapdevices() will unlock ignored swap devices since
++ *    writing is finished.
++ *    It is important _NOT_ to umount filesystems at this point. We want
++ *    them synced (in case something goes wrong) but we DO not want to mark
++ *    filesystem clean: it is not. (And it does not matter, if we resume
++ *    correctly, we'll mark system clean, anyway.)
++ */
++
++static int suspend_save_image(void)
++{
++      int error;
++      device_resume();
++      lock_swapdevices();
++      error = write_suspend_image();
++      lock_swapdevices();
++      return error;
++}
++
++/*
++ * Magic happens here
++ */
++
++int pmdisk_resume(void)
++{
++      BUG_ON (nr_copy_pages_check != pmdisk_pages);
++      BUG_ON (pagedir_order_check != pagedir_order);
++      
++      /* Even mappings of "global" things (vmalloc) need to be fixed */
++      __flush_tlb_global();
++      return 0;
++}
++
++/* pmdisk_arch_suspend() is implemented in arch/?/power/pmdisk.S,
++   and basically does:
++
++      if (!resume) {
++              save_processor_state();
++              SAVE_REGISTERS
++              return pmdisk_suspend();
++      }
++      GO_TO_SWAPPER_PAGE_TABLES
++      COPY_PAGES_BACK
++      RESTORE_REGISTERS
++      restore_processor_state();
++      return pmdisk_resume();
++
++ */
++
++
++/* More restore stuff */
++
++/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
++static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
++{
++      int i;
++      char *topointer=(char *)to, *frompointer=(char *)from;
++
++      for(i=0; i < 1 << pagedir_order; i++) {
++              copy_page(topointer, frompointer);
++              topointer += PAGE_SIZE;
++              frompointer += PAGE_SIZE;
++      }
++}
++
++#define does_collide(addr) does_collide_order(pm_pagedir_nosave, addr, 0)
++
++/*
++ * Returns true if given address/order collides with any orig_address 
++ */
++static int __init does_collide_order(suspend_pagedir_t *pagedir, 
++                                   unsigned long addr, int order)
++{
++      int i;
++      unsigned long addre = addr + (PAGE_SIZE<<order);
++      
++      for(i=0; i < pmdisk_pages; i++)
++              if((pagedir+i)->orig_address >= addr &&
++                      (pagedir+i)->orig_address < addre)
++                      return 1;
++
++      return 0;
++}
++
++/*
++ * We check here that pagedir & pages it points to won't collide with pages
++ * where we're going to restore from the loaded pages later
++ */
++static int __init check_pagedir(void)
++{
++      int i;
++
++      for(i=0; i < pmdisk_pages; i++) {
++              unsigned long addr;
++
++              do {
++                      addr = get_zeroed_page(GFP_ATOMIC);
++                      if(!addr)
++                              return -ENOMEM;
++              } while (does_collide(addr));
++
++              (pm_pagedir_nosave+i)->address = addr;
++      }
++      return 0;
++}
++
++static int __init relocate_pagedir(void)
++{
++      /*
++       * We have to avoid recursion (not to overflow kernel stack),
++       * and that's why code looks pretty cryptic 
++       */
++      suspend_pagedir_t *new_pagedir, *old_pagedir = pm_pagedir_nosave;
++      void **eaten_memory = NULL;
++      void **c = eaten_memory, *m, *f;
++
++      printk("Relocating pagedir");
++
++      if(!does_collide_order(old_pagedir, (unsigned long)old_pagedir, pagedir_order)) {
++              printk("not necessary\n");
++              return 0;
++      }
++
++      while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
++              memset(m, 0, PAGE_SIZE);
++              if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
++                      break;
++              eaten_memory = m;
++              printk( "." ); 
++              *eaten_memory = c;
++              c = eaten_memory;
++      }
++
++      if (!m)
++              return -ENOMEM;
++
++      pm_pagedir_nosave = new_pagedir = m;
++      copy_pagedir(new_pagedir, old_pagedir);
++
++      c = eaten_memory;
++      while(c) {
++              printk(":");
++              f = *c;
++              c = *c;
++              if (f)
++                      free_pages((unsigned long)f, pagedir_order);
++      }
++      printk("|\n");
++      return 0;
++}
++
++/*
++ * Sanity check if this image makes sense with this kernel/swap context
++ * I really don't think that it's foolproof but more than nothing..
++ */
++
++static int __init sanity_check_failed(char *reason)
++{
++      printk(KERN_ERR "%s%s\n",name_resume,reason);
++      return -EPERM;
++}
++
++static int __init sanity_check(struct suspend_header *sh)
++{
++      if(sh->version_code != LINUX_VERSION_CODE)
++              return sanity_check_failed("Incorrect kernel version");
++      if(sh->num_physpages != num_physpages)
++              return sanity_check_failed("Incorrect memory size");
++      if(strncmp(sh->machine, system_utsname.machine, 8))
++              return sanity_check_failed("Incorrect machine type");
++      if(strncmp(sh->version, system_utsname.version, 20))
++              return sanity_check_failed("Incorrect version");
++      if(sh->num_cpus != num_online_cpus())
++              return sanity_check_failed("Incorrect number of cpus");
++      if(sh->page_size != PAGE_SIZE)
++              return sanity_check_failed("Incorrect PAGE_SIZE");
++      return 0;
++}
++
++static struct block_device * resume_bdev;
++
++
++/**
++ *    Using bio to read from swap.
++ *    This code requires a bit more work than just using buffer heads
++ *    but, it is the recommended way for 2.5/2.6.
++ *    The following are to signal the beginning and end of I/O. Bios
++ *    finish asynchronously, while we want them to happen synchronously.
++ *    A simple atomic_t, and a wait loop take care of this problem.
++ */
++
++static atomic_t io_done = ATOMIC_INIT(0);
++
++static void start_io(void)
++{
++      atomic_set(&io_done,1);
++}
++
++static int end_io(struct bio * bio, unsigned int num, int err)
++{
++      atomic_set(&io_done,0);
++      return 0;
++}
++
++static void wait_io(void)
++{
++      blk_run_queues();
++      while(atomic_read(&io_done))
++              io_schedule();
++}
++
++
++/**
++ *    submit - submit BIO request.
++ *    @rw:    READ or WRITE.
++ *    @off    physical offset of page.
++ *    @page:  page we're reading or writing.
++ *
++ *    Straight from the textbook - allocate and initialize the bio.
++ *    If we're writing, make sure the page is marked as dirty.
++ *    Then submit it and wait.
++ */
++
++static int submit(int rw, pgoff_t page_off, void * page)
++{
++      int error = 0;
++      struct bio * bio;
++
++      bio = bio_alloc(GFP_ATOMIC,1);
++      if (!bio)
++              return -ENOMEM;
++      bio->bi_sector = page_off * (PAGE_SIZE >> 9);
++      bio_get(bio);
++      bio->bi_bdev = resume_bdev;
++      bio->bi_end_io = end_io;
++
++      if (bio_add_page(bio, virt_to_page(page), PAGE_SIZE, 0) < PAGE_SIZE) {
++              printk("ERROR: adding page to bio at %ld\n",page_off);
++              error = -EFAULT;
++              goto Done;
++      }
++
++      if (rw == WRITE)
++              bio_set_pages_dirty(bio);
++      start_io();
++      submit_bio(rw,bio);
++      wait_io();
++ Done:
++      bio_put(bio);
++      return error;
++}
++
++static int
++read_page(pgoff_t page_off, void * page)
++{
++      return submit(READ,page_off,page);
++}
++
++static int
++write_page(pgoff_t page_off, void * page)
++{
++      return submit(WRITE,page_off,page);
++}
++
++
++extern dev_t __init name_to_dev_t(const char *line);
++
++
++#define next_entry(diskpage)  diskpage->link.next
++
++static int __init read_suspend_image(void)
++{
++      swp_entry_t next;
++      int i, nr_pgdir_pages;
++      union diskpage *cur;
++      int error = 0;
++
++      cur = (union diskpage *)get_zeroed_page(GFP_ATOMIC);
++      if (!cur)
++              return -ENOMEM;
++
++      if ((error = read_page(0, cur)))
++              goto Done;
++
++      /*
++       * We have to read next position before we overwrite it
++       */
++      next = next_entry(cur);
++
++      if (!memcmp("S1",cur->swh.magic.magic,2))
++              memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
++      else if (!memcmp("S2",cur->swh.magic.magic,2))
++              memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
++      else if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)) ||
++               (!memcmp("SWAPSPACE2",cur->swh.magic.magic,10))) {
++              printk(KERN_ERR "pmdisk: Partition is normal swap space\n");
++              error = -EINVAL;
++              goto Done;
++      } else {
++              printk(KERN_ERR "pmdisk: Invalid partition type.\n");
++              error = -EINVAL;
++              goto Done;
++      }
++
++      /*
++       * Reset swap signature now.
++       */
++      if ((error = write_page(0,cur)))
++              goto Done;
++
++      printk( "%sSignature found, resuming\n", name_resume );
++      MDELAY(1000);
++
++      if ((error = read_page(swp_offset(next), cur)))
++              goto Done;
++      /* Is this same machine? */
++      if ((error = sanity_check(&cur->sh)))
++              goto Done;
++      next = next_entry(cur);
++
++      pagedir_save = cur->sh.suspend_pagedir;
++      pmdisk_pages = cur->sh.num_pbes;
++      nr_pgdir_pages = SUSPEND_PD_PAGES(pmdisk_pages);
++      pagedir_order = get_bitmask_order(nr_pgdir_pages);
++
++      pm_pagedir_nosave = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, pagedir_order);
++      if (!pm_pagedir_nosave) {
++              error = -ENOMEM;
++              goto Done;
++      }
++
++      PRINTK( "%sReading pagedir, ", name_resume );
++
++      /* We get pages in reverse order of saving! */
++      for (i=nr_pgdir_pages-1; i>=0; i--) {
++              BUG_ON (!next.val);
++              cur = (union diskpage *)((char *) pm_pagedir_nosave)+i;
++              error = read_page(swp_offset(next), cur);
++              if (error)
++                      goto FreePagedir;
++              next = next_entry(cur);
++      }
++      BUG_ON (next.val);
++
++      if ((error = relocate_pagedir()))
++              goto FreePagedir;
++      if ((error = check_pagedir()))
++              goto FreePagedir;
++
++      printk( "Reading image data (%d pages): ", pmdisk_pages );
++      for(i=0; i < pmdisk_pages; i++) {
++              swp_entry_t swap_address = (pm_pagedir_nosave+i)->swap_address;
++              if (!(i%100))
++                      printk( "." );
++              /* You do not need to check for overlaps...
++                 ... check_pagedir already did this work */
++              error = read_page(swp_offset(swap_address),
++                                (char *)((pm_pagedir_nosave+i)->address));
++              if (error)
++                      goto FreePagedir;
++      }
++      printk( "|\n" );
++ Done:
++      free_page((unsigned long)cur);
++      return error;
++ FreePagedir:
++      free_pages((unsigned long)pm_pagedir_nosave,pagedir_order);
++      goto Done;
++}
++
++/**
++ *    pmdisk_save - Snapshot memory
++ */
++
++int pmdisk_save(void) 
++{
++      int error;
++
++#if defined (CONFIG_HIGHMEM) || defined (COFNIG_DISCONTIGMEM)
++      printk("pmdisk is not supported with high- or discontig-mem.\n");
++      return -EPERM;
++#endif
++      if ((error = arch_prepare_suspend()))
++              return error;
++      local_irq_disable();
++      error = pmdisk_arch_suspend(0);
++      local_irq_enable();
++      return error;
++}
++
++
++/**
++ *    pmdisk_write - Write saved memory image to swap.
++ *
++ *    pmdisk_arch_suspend(0) returns after system is resumed.
++ *
++ *    pmdisk_arch_suspend() copies all "used" memory to "free" memory,
++ *    then unsuspends all device drivers, and writes memory to disk
++ *    using normal kernel mechanism.
++ */
++
++int pmdisk_write(void)
++{
++      return suspend_save_image();
++}
++
++
++/**
++ *    pmdisk_read - Read saved image from swap.
++ */
++
++int __init pmdisk_read(void)
++{
++      int error;
++      char b[BDEVNAME_SIZE];
++
++      if (!strlen(resume_file))
++              return -ENOENT;
++
++      resume_device = name_to_dev_t(resume_file);
++      printk("pmdisk: Resume From Partition: %s, Device: %s\n", 
++             resume_file, __bdevname(resume_device, b));
++
++      resume_bdev = open_by_devnum(resume_device, FMODE_READ, BDEV_RAW);
++      if (!IS_ERR(resume_bdev)) {
++              set_blocksize(resume_bdev, PAGE_SIZE);
++              error = read_suspend_image();
++              blkdev_put(resume_bdev, BDEV_RAW);
++      } else
++              error = PTR_ERR(resume_bdev);
++
++      if (!error)
++              PRINTK("Reading resume file was successful\n");
++      else
++              printk( "%sError %d resuming\n", name_resume, error );
++      MDELAY(1000);
++      return error;
++}
++
++
++/**
++ *    pmdisk_restore - Replace running kernel with saved image.
++ */
++
++int __init pmdisk_restore(void)
++{
++      int error;
++      local_irq_disable();
++      error = pmdisk_arch_suspend(1);
++      local_irq_enable();
++      return error;
++}
++
++
++/**
++ *    pmdisk_free - Free memory allocated to hold snapshot.
++ */
++
++int pmdisk_free(void)
++{
++      PRINTK( "Freeing prev allocated pagedir\n" );
++      free_suspend_pagedir((unsigned long) pagedir_save);
++      return 0;
++}
++
++static int __init pmdisk_setup(char *str)
++{
++      if (strlen(str)) {
++              if (!strcmp(str,"off"))
++                      resume_file[0] = '\0';
++              else
++                      strncpy(resume_file, str, 255);
++      } else
++              resume_file[0] = '\0';
++      return 1;
++}
++
++__setup("pmdisk=", pmdisk_setup);
++
+Index: linux-2.6.0-test5/kernel/power/power.h
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/power.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/power.h     2003-09-27 11:38:41.295250552 +0800
+@@ -9,35 +9,28 @@
+ #endif
+-#ifdef CONFIG_SOFTWARE_SUSPEND
+-extern int swsusp_save(void);
+-extern int swsusp_write(void);
+-extern int swsusp_read(void);
+-extern int swsusp_restore(void);
+-extern int swsusp_free(void);
++#ifdef CONFIG_PM_DISK
++extern int pm_suspend_disk(void);
++
+ #else
+-static inline int swsusp_save(void) 
+-{
+-      return 0;
+-}
+-static inline int swsusp_write(void)
++static inline int pm_suspend_disk(void)
+ {
+-      return 0;
+-}
+-static inline int swsusp_read(void)
+-{
+-      return 0;
+-}
+-static inline int swsusp_restore(void)
+-{
+-      return 0;
+-}
+-static inline int swsusp_free(void)
+-{
+-      return 0;
++      return -EPERM;
+ }
+ #endif
++extern struct semaphore pm_sem;
++#define power_attr(_name) \
++static struct subsys_attribute _name##_attr = {       \
++      .attr   = {                             \
++              .name = __stringify(_name),     \
++              .mode = 0644,                   \
++      },                                      \
++      .show   = _name##_show,                 \
++      .store  = _name##_store,                \
++}
++
++extern struct subsystem power_subsys;
+ extern int freeze_processes(void);
+ extern void thaw_processes(void);
+Index: linux-2.6.0-test5/kernel/power/swsusp.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/power/swsusp.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/power/swsusp.c    2003-09-27 11:38:41.302249488 +0800
+@@ -65,7 +65,15 @@
+ #include "power.h"
+-unsigned char software_suspend_enabled = 1;
++extern long sys_sync(void);
++
++unsigned char software_suspend_enabled = 0;
++
++extern void do_magic(int resume);
++
++#define NORESUME              1
++#define RESUME_SPECIFIED      2
++
+ #define __ADDRESS(x)  ((unsigned long) phys_to_virt(x))
+ #define ADDRESS(x) __ADDRESS((x) << PAGE_SHIFT)
+@@ -83,7 +91,8 @@
+ static int pagedir_order_check;
+ static int nr_copy_pages_check;
+-static char resume_file[256];                 /* For resume= kernel option */
++static int resume_status;
++static char resume_file[256] = "";                    /* For resume= kernel option */
+ static dev_t resume_device;
+ /* Local variables that should not be affected by save */
+ unsigned int nr_copy_pages __nosavedata = 0;
+@@ -347,10 +356,15 @@
+       int pfn;
+       struct page *page;
+       
++#ifdef CONFIG_DISCONTIGMEM
++      panic("Discontingmem not supported");
++#else
+       BUG_ON (max_pfn != num_physpages);
+-
++#endif
+       for (pfn = 0; pfn < max_pfn; pfn++) {
+               page = pfn_to_page(pfn);
++              if (PageHighMem(page))
++                      panic("Swsusp not supported on highmem boxes. Send 1GB of RAM to <pavel@ucw.cz> and try again ;-).");
+               if (!PageReserved(page)) {
+                       if (PageNosave(page))
+@@ -435,6 +449,56 @@
+       return pagedir;
+ }
++static int prepare_suspend_processes(void)
++{
++      sys_sync();     /* Syncing needs pdflushd, so do it before stopping processes */
++      if (freeze_processes()) {
++              printk( KERN_ERR "Suspend failed: Not all processes stopped!\n" );
++              thaw_processes();
++              return 1;
++      }
++      return 0;
++}
++
++/*
++ * Try to free as much memory as possible, but do not OOM-kill anyone
++ *
++ * Notice: all userland should be stopped at this point, or livelock is possible.
++ */
++static void free_some_memory(void)
++{
++      printk("Freeing memory: ");
++      while (shrink_all_memory(10000))
++              printk(".");
++      printk("|\n");
++}
++
++/* Make disk drivers accept operations, again */
++static void drivers_unsuspend(void)
++{
++      device_resume();
++}
++
++/* Called from process context */
++static int drivers_suspend(void)
++{
++      return device_suspend(4);
++}
++
++#define RESUME_PHASE1 1 /* Called from interrupts disabled */
++#define RESUME_PHASE2 2 /* Called with interrupts enabled */
++#define RESUME_ALL_PHASES (RESUME_PHASE1 | RESUME_PHASE2)
++static void drivers_resume(int flags)
++{
++      if (flags & RESUME_PHASE1) {
++              device_resume();
++      }
++      if (flags & RESUME_PHASE2) {
++#ifdef SUSPEND_CONSOLE
++              update_screen(fg_console);      /* Hmm, is this the problem? */
++#endif
++      }
++}
+ static int suspend_prepare_image(void)
+ {
+@@ -488,14 +552,12 @@
+       return 0;
+ }
+-static int suspend_save_image(void)
++static void suspend_save_image(void)
+ {
+-      int error;
+-
+-      device_resume();
++      drivers_unsuspend();
+       lock_swapdevices();
+-      error = write_suspend_image();
++      write_suspend_image();
+       lock_swapdevices();     /* This will unlock ignored swap devices since writing is finished */
+       /* It is important _NOT_ to umount filesystems at this point. We want
+@@ -503,7 +565,29 @@
+        * filesystem clean: it is not. (And it does not matter, if we resume
+        * correctly, we'll mark system clean, anyway.)
+        */
+-      return error;
++}
++
++static void suspend_power_down(void)
++{
++      extern int C_A_D;
++      C_A_D = 0;
++      printk(KERN_EMERG "%s%s Trying to power down.\n", name_suspend, TEST_SWSUSP ? "Disable TEST_SWSUSP. NOT ": "");
++#ifdef CONFIG_VT
++      PRINTK(KERN_EMERG "shift_state: %04x\n", shift_state);
++      mdelay(1000);
++      if (TEST_SWSUSP ^ (!!(shift_state & (1 << KG_CTRL))))
++              machine_restart(NULL);
++      else
++#endif
++      {
++              device_shutdown();
++              machine_power_off();
++      }
++
++      printk(KERN_EMERG "%sProbably not capable for powerdown. System halted.\n", name_suspend);
++      machine_halt();
++      while (1);
++      /* NOTREACHED */
+ }
+ /*
+@@ -515,21 +599,32 @@
+       barrier();
+       mb();
+       spin_lock_irq(&suspend_pagedir_lock);   /* Done to disable interrupts */ 
++
+       PRINTK( "Waiting for DMAs to settle down...\n");
+-      /* We do not want some readahead with DMA to corrupt our memory, right?
+-         Do it with disabled interrupts for best effect. That way, if some
+-         driver scheduled DMA, we have good chance for DMA to finish ;-). */
+-      mdelay(1000);
++      mdelay(1000);   /* We do not want some readahead with DMA to corrupt our memory, right?
++                         Do it with disabled interrupts for best effect. That way, if some
++                         driver scheduled DMA, we have good chance for DMA to finish ;-). */
+ }
+ void do_magic_resume_2(void)
+ {
+       BUG_ON (nr_copy_pages_check != nr_copy_pages);
+       BUG_ON (pagedir_order_check != pagedir_order);
+-      
+-      /* Even mappings of "global" things (vmalloc) need to be fixed */
+-      __flush_tlb_global();
++
++      __flush_tlb_global();           /* Even mappings of "global" things (vmalloc) need to be fixed */
++
++      PRINTK( "Freeing prev allocated pagedir\n" );
++      free_suspend_pagedir((unsigned long) pagedir_save);
+       spin_unlock_irq(&suspend_pagedir_lock);
++      drivers_resume(RESUME_ALL_PHASES);
++
++      PRINTK( "Fixing swap signatures... " );
++      mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
++      PRINTK( "ok\n" );
++
++#ifdef SUSPEND_CONSOLE
++      update_screen(fg_console);      /* Hmm, is this the problem? */
++#endif
+ }
+ /* do_magic() is implemented in arch/?/kernel/suspend_asm.S, and basically does:
+@@ -554,28 +649,91 @@
+ {
+       mb();
+       barrier();
++      BUG_ON(in_atomic());
+       spin_lock_irq(&suspend_pagedir_lock);
+ }
+-int do_magic_suspend_2(void)
++void do_magic_suspend_2(void)
+ {
+       int is_problem;
+       read_swapfiles();
+       is_problem = suspend_prepare_image();
+       spin_unlock_irq(&suspend_pagedir_lock);
+-      if (!is_problem)
+-              return suspend_save_image();
++      if (!is_problem) {
++              kernel_fpu_end();       /* save_processor_state() does kernel_fpu_begin, and we need to revert it in order to pass in_atomic() checks */
++              BUG_ON(in_atomic());
++              suspend_save_image();
++              suspend_power_down();   /* FIXME: if suspend_power_down is commented out, console is lost after few suspends ?! */
++      }
++
+       printk(KERN_EMERG "%sSuspend failed, trying to recover...\n", name_suspend);
++      MDELAY(1000); /* So user can wait and report us messages if armageddon comes :-) */
++
+       barrier();
+       mb();
++      spin_lock_irq(&suspend_pagedir_lock);   /* Done to disable interrupts */ 
+       mdelay(1000);
+-      return -EFAULT;
++
++      free_pages((unsigned long) pagedir_nosave, pagedir_order);
++      spin_unlock_irq(&suspend_pagedir_lock);
++      mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
++}
++
++static void do_software_suspend(void)
++{
++      arch_prepare_suspend();
++      if (pm_prepare_console())
++              printk( "%sCan't allocate a console... proceeding\n", name_suspend);
++      if (!prepare_suspend_processes()) {
++
++              /* At this point, all user processes and "dangerous"
++                   kernel threads are stopped. Free some memory, as we
++                   need half of memory free. */
++
++              free_some_memory();
++              
++              /* No need to invalidate any vfsmnt list -- 
++               * they will be valid after resume, anyway.
++               */
++              blk_run_queues();
++
++              /* Save state of all device drivers, and stop them. */             
++              if(drivers_suspend()==0)
++                      /* If stopping device drivers worked, we proceed basically into
++                       * suspend_save_image.
++                       *
++                       * do_magic(0) returns after system is resumed.
++                       *
++                       * do_magic() copies all "used" memory to "free" memory, then
++                       * unsuspends all device drivers, and writes memory to disk
++                       * using normal kernel mechanism.
++                       */
++                      do_magic(0);
++              thaw_processes();
++      }
++      software_suspend_enabled = 1;
++      MDELAY(1000);
++      pm_restore_console();
++}
++
++/*
++ * This is main interface to the outside world. It needs to be
++ * called from process context.
++ */
++void software_suspend(void)
++{
++      if(!software_suspend_enabled)
++              return;
++
++      software_suspend_enabled = 0;
++      might_sleep();
++      do_software_suspend();
+ }
+ /* More restore stuff */
+ /* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
+-static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
++static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
+ {
+       int i;
+       char *topointer=(char *)to, *frompointer=(char *)from;
+@@ -592,8 +750,8 @@
+ /*
+  * Returns true if given address/order collides with any orig_address 
+  */
+-static int __init does_collide_order(suspend_pagedir_t *pagedir, 
+-                                   unsigned long addr, int order)
++static int does_collide_order(suspend_pagedir_t *pagedir, unsigned long addr,
++              int order)
+ {
+       int i;
+       unsigned long addre = addr + (PAGE_SIZE<<order);
+@@ -610,7 +768,7 @@
+  * We check here that pagedir & pages it points to won't collide with pages
+  * where we're going to restore from the loaded pages later
+  */
+-static int __init check_pagedir(void)
++static int check_pagedir(void)
+ {
+       int i;
+@@ -628,7 +786,7 @@
+       return 0;
+ }
+-static int __init relocate_pagedir(void)
++static int relocate_pagedir(void)
+ {
+       /*
+        * We have to avoid recursion (not to overflow kernel stack),
+@@ -678,13 +836,13 @@
+  * I really don't think that it's foolproof but more than nothing..
+  */
+-static int __init sanity_check_failed(char *reason)
++static int sanity_check_failed(char *reason)
+ {
+       printk(KERN_ERR "%s%s\n",name_resume,reason);
+       return -EPERM;
+ }
+-static int __init sanity_check(struct suspend_header *sh)
++static int sanity_check(struct suspend_header *sh)
+ {
+       if(sh->version_code != LINUX_VERSION_CODE)
+               return sanity_check_failed("Incorrect kernel version");
+@@ -701,8 +859,7 @@
+       return 0;
+ }
+-static int __init bdev_read_page(struct block_device *bdev, 
+-                               long pos, void *buf)
++static int bdev_read_page(struct block_device *bdev, long pos, void *buf)
+ {
+       struct buffer_head *bh;
+       BUG_ON (pos%PAGE_SIZE);
+@@ -716,10 +873,31 @@
+       return 0;
+ } 
++static int bdev_write_page(struct block_device *bdev, long pos, void *buf)
++{
++#if 0
++      struct buffer_head *bh;
++      BUG_ON (pos%PAGE_SIZE);
++      bh = __bread(bdev, pos/PAGE_SIZE, PAGE_SIZE);
++      if (!bh || (!bh->b_data)) {
++              return -1;
++      }
++      memcpy(bh->b_data, buf, PAGE_SIZE);     /* FIXME: may need kmap() */
++      BUG_ON(!buffer_uptodate(bh));
++      generic_make_request(WRITE, bh);
++      if (!buffer_uptodate(bh))
++              printk(KERN_CRIT "%sWarning %s: Fixing swap signatures unsuccessful...\n", name_resume, resume_file);
++      wait_on_buffer(bh);
++      brelse(bh);
++      return 0;
++#endif
++      printk(KERN_CRIT "%sWarning %s: Fixing swap signatures unimplemented...\n", name_resume, resume_file);
++      return 0;
++}
++
+ extern dev_t __init name_to_dev_t(const char *line);
+-static int __init read_suspend_image(struct block_device *bdev, 
+-                                   union diskpage *cur)
++static int __read_suspend_image(struct block_device *bdev, union diskpage *cur, int noresume)
+ {
+       swp_entry_t next;
+       int i, nr_pgdir_pages;
+@@ -744,9 +922,18 @@
+       else if (!memcmp("S2",cur->swh.magic.magic,2))
+               memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
+       else {
+-              printk("swsusp: %s: Unable to find suspended-data signature (%.10s - misspelled?\n", 
++              if (noresume)
++                      return -EINVAL;
++              panic("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
+                       name_resume, cur->swh.magic.magic);
+-              return -EFAULT;
++      }
++      if (noresume) {
++              /* We don't do a sanity check here: we want to restore the swap
++                 whatever version of kernel made the suspend image;
++                 We need to write swap, but swap is *not* enabled so
++                 we must write the device directly */
++              printk("%s: Fixing swap signatures %s...\n", name_resume, resume_file);
++              bdev_write_page(bdev, 0, cur);
+       }
+       printk( "%sSignature found, resuming\n", name_resume );
+@@ -796,115 +983,117 @@
+       return 0;
+ }
+-/**
+- *    swsusp_save - Snapshot memory
+- */
+-
+-int swsusp_save(void) 
+-{
+-#if defined (CONFIG_HIGHMEM) || defined (COFNIG_DISCONTIGMEM)
+-      printk("swsusp is not supported with high- or discontig-mem.\n");
+-      return -EPERM;
+-#endif
+-      return 0;
+-}
+-
+-
+-/**
+- *    swsusp_write - Write saved memory image to swap.
+- *
+- *    do_magic(0) returns after system is resumed.
+- *
+- *    do_magic() copies all "used" memory to "free" memory, then
+- *    unsuspends all device drivers, and writes memory to disk
+- *    using normal kernel mechanism.
+- */
+-
+-int swsusp_write(void)
+-{
+-      arch_prepare_suspend();
+-      return do_magic(0);
+-}
+-
+-
+-/**
+- *    swsusp_read - Read saved image from swap.
+- */
+-
+-int __init swsusp_read(void)
++static int read_suspend_image(const char * specialfile, int noresume)
+ {
+       union diskpage *cur;
++      unsigned long scratch_page = 0;
+       int error;
+       char b[BDEVNAME_SIZE];
+-      if (!strlen(resume_file))
+-              return -ENOENT;
+-
+-      resume_device = name_to_dev_t(resume_file);
+-      printk("swsusp: Resume From Partition: %s, Device: %s\n", 
+-             resume_file, __bdevname(resume_device, b));
+-
+-      cur = (union diskpage *)get_zeroed_page(GFP_ATOMIC);
++      resume_device = name_to_dev_t(specialfile);
++      scratch_page = get_zeroed_page(GFP_ATOMIC);
++      cur = (void *) scratch_page;
+       if (cur) {
+               struct block_device *bdev;
++              printk("Resuming from device %s\n",
++                              __bdevname(resume_device, b));
+               bdev = open_by_devnum(resume_device, FMODE_READ, BDEV_RAW);
+-              if (!IS_ERR(bdev)) {
++              if (IS_ERR(bdev)) {
++                      error = PTR_ERR(bdev);
++              } else {
+                       set_blocksize(bdev, PAGE_SIZE);
+-                      error = read_suspend_image(bdev, cur);
++                      error = __read_suspend_image(bdev, cur, noresume);
+                       blkdev_put(bdev, BDEV_RAW);
+-              } else
+-                      error = PTR_ERR(bdev);
+-              free_page((unsigned long)cur);
+-      } else
+-              error = -ENOMEM;
++              }
++      } else error = -ENOMEM;
+-      if (!error)
+-              PRINTK("Reading resume file was successful\n");
+-      else
+-              printk( "%sError %d resuming\n", name_resume, error );
++      if (scratch_page)
++              free_page(scratch_page);
++      switch (error) {
++              case 0:
++                      PRINTK("Reading resume file was successful\n");
++                      break;
++              case -EINVAL:
++                      break;
++              case -EIO:
++                      printk( "%sI/O error\n", name_resume);
++                      break;
++              case -ENOENT:
++                      printk( "%s%s: No such file or directory\n", name_resume, specialfile);
++                      break;
++              case -ENOMEM:
++                      printk( "%sNot enough memory\n", name_resume);
++                      break;
++              default:
++                      printk( "%sError %d resuming\n", name_resume, error );
++      }
+       MDELAY(1000);
+       return error;
+ }
+-
+-/**
+- *    swsusp_restore - Replace running kernel with saved image.
++/*
++ * Called from init kernel_thread.
++ * We check if we have an image and if so we try to resume
+  */
+-int __init swsusp_restore(void)
++void software_resume(void)
+ {
+-      return do_magic(1);
+-}
++      if (num_online_cpus() > 1) {
++              printk(KERN_WARNING "Software Suspend has malfunctioning SMP support. Disabled :(\n");  
++              return;
++      }
++      /* We enable the possibility of machine suspend */
++      software_suspend_enabled = 1;
++      if (!resume_status)
++              return;
++      printk( "%s", name_resume );
++      if (resume_status == NORESUME) {
++              if(resume_file[0])
++                      read_suspend_image(resume_file, 1);
++              printk( "disabled\n" );
++              return;
++      }
++      MDELAY(1000);
+-/**
+- *    swsusp_free - Free memory allocated to hold snapshot.
+- */
++      if (pm_prepare_console())
++              printk("swsusp: Can't allocate a console... proceeding\n");
+-int swsusp_free(void)
+-{
+-      PRINTK( "Freeing prev allocated pagedir\n" );
+-      free_suspend_pagedir((unsigned long) pagedir_save);
++      if (!resume_file[0] && resume_status == RESUME_SPECIFIED) {
++              printk( "suspension device unspecified\n" );
++              return;
++      }
+-      PRINTK( "Fixing swap signatures... " );
+-      mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
+-      PRINTK( "ok\n" );
+-      return 0;
++      printk( "resuming from %s\n", resume_file);
++      if (read_suspend_image(resume_file, 0))
++              goto read_failure;
++      do_magic(1);
++      panic("This never returns");
++
++read_failure:
++      pm_restore_console();
++      return;
+ }
+ static int __init resume_setup(char *str)
+ {
+-      if (strlen(str))
+-              strncpy(resume_file, str, 255);
++      if (resume_status == NORESUME)
++              return 1;
++
++      strncpy( resume_file, str, 255 );
++      resume_status = RESUME_SPECIFIED;
++
+       return 1;
+ }
+ static int __init noresume_setup(char *str)
+ {
+-      resume_file[0] = '\0';
++      resume_status = NORESUME;
+       return 1;
+ }
+ __setup("noresume", noresume_setup);
+ __setup("resume=", resume_setup);
++EXPORT_SYMBOL(software_suspend);
++EXPORT_SYMBOL(software_suspend_enabled);
+Index: linux-2.6.0-test5/kernel/printk.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/printk.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/printk.c  2003-09-27 11:38:41.308248576 +0800
+@@ -399,9 +399,13 @@
+       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 @@
+       /* 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);
+Index: linux-2.6.0-test5/kernel/ptrace.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/ptrace.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/ptrace.c  2003-09-27 11:38:41.310248272 +0800
+@@ -179,19 +179,14 @@
+               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);
+Index: linux-2.6.0-test5/kernel/sched.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sched.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/sched.c   2003-09-27 11:38:41.329245384 +0800
+@@ -14,6 +14,7 @@
+  *            an array-switch method of distributing timeslices
+  *            and per-CPU runqueues.  Cleanups and useful suggestions
+  *            by Davide Libenzi, preemptible kernel bits by Robert Love.
++ *  2003-09-03        Interactivity tuning by Con Kolivas.
+  */
+ #include <linux/mm.h>
+@@ -28,6 +29,7 @@
+ #include <linux/kernel_stat.h>
+ #include <linux/security.h>
+ #include <linux/notifier.h>
++#include <linux/suspend.h>
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/timer.h>
+@@ -58,6 +60,14 @@
+ #define USER_PRIO(p)          ((p)-MAX_RT_PRIO)
+ #define TASK_USER_PRIO(p)     USER_PRIO((p)->static_prio)
+ #define MAX_USER_PRIO         (USER_PRIO(MAX_PRIO))
++#define AVG_TIMESLICE (MIN_TIMESLICE + ((MAX_TIMESLICE - MIN_TIMESLICE) *\
++                      (MAX_PRIO-1-NICE_TO_PRIO(0))/(MAX_USER_PRIO - 1)))
++
++/*
++ * Some helpers for converting nanosecond timing to jiffy resolution
++ */
++#define NS_TO_JIFFIES(TIME)   ((TIME) / (1000000000 / HZ))
++#define JIFFIES_TO_NS(TIME)   ((TIME) * (1000000000 / HZ))
+ /*
+  * These are the 'tuning knobs' of the scheduler:
+@@ -68,14 +78,18 @@
+  */
+ #define MIN_TIMESLICE         ( 10 * HZ / 1000)
+ #define MAX_TIMESLICE         (200 * HZ / 1000)
+-#define CHILD_PENALTY         50
++#define ON_RUNQUEUE_WEIGHT    30
++#define CHILD_PENALTY         95
+ #define PARENT_PENALTY                100
+ #define EXIT_WEIGHT           3
+ #define PRIO_BONUS_RATIO      25
++#define MAX_BONUS             (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
+ #define INTERACTIVE_DELTA     2
+-#define MAX_SLEEP_AVG         (10*HZ)
+-#define STARVATION_LIMIT      (10*HZ)
++#define MAX_SLEEP_AVG         (AVG_TIMESLICE * MAX_BONUS)
++#define STARVATION_LIMIT      (MAX_SLEEP_AVG)
++#define NS_MAX_SLEEP_AVG      (JIFFIES_TO_NS(MAX_SLEEP_AVG))
+ #define NODE_THRESHOLD                125
++#define CREDIT_LIMIT          100
+ /*
+  * If a task is 'interactive' then we reinsert it in the active
+@@ -105,6 +119,19 @@
+  * too hard.
+  */
++#define CURRENT_BONUS(p) \
++      (NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \
++              MAX_SLEEP_AVG)
++
++#ifdef CONFIG_SMP
++#define TIMESLICE_GRANULARITY(p)      (MIN_TIMESLICE * \
++              (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \
++                      num_online_cpus())
++#else
++#define TIMESLICE_GRANULARITY(p)      (MIN_TIMESLICE * \
++              (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)))
++#endif
++
+ #define SCALE(v1,v1_max,v2_max) \
+       (v1) * (v2_max) / (v1_max)
+@@ -115,6 +142,19 @@
+ #define TASK_INTERACTIVE(p) \
+       ((p)->prio <= (p)->static_prio - DELTA(p))
++#define JUST_INTERACTIVE_SLEEP(p) \
++      (JIFFIES_TO_NS(MAX_SLEEP_AVG * \
++              (MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
++
++#define HIGH_CREDIT(p) \
++      ((p)->interactive_credit > CREDIT_LIMIT)
++
++#define LOW_CREDIT(p) \
++      ((p)->interactive_credit < -CREDIT_LIMIT)
++
++#define TASK_PREEMPTS_CURR(p, rq) \
++      ((p)->prio < (rq)->curr->prio)
++
+ /*
+  * BASE_TIMESLICE scales user-nice values [ -20 ... 19 ]
+  * to time slice values.
+@@ -179,7 +219,6 @@
+ #define this_rq()             (&__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)
+ /*
+  * Default context-switch locking:
+@@ -319,8 +358,7 @@
+       if (rt_task(p))
+               return p->prio;
+-      bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*p->sleep_avg/MAX_SLEEP_AVG/100 -
+-                      MAX_USER_PRIO*PRIO_BONUS_RATIO/100/2;
++      bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
+       prio = p->static_prio - bonus;
+       if (prio < MAX_RT_PRIO)
+@@ -339,6 +377,82 @@
+       nr_running_inc(rq);
+ }
++static void recalc_task_prio(task_t *p, unsigned long long now)
++{
++      unsigned long long __sleep_time = now - p->timestamp;
++      unsigned long sleep_time;
++
++      if (__sleep_time > NS_MAX_SLEEP_AVG)
++              sleep_time = NS_MAX_SLEEP_AVG;
++      else
++              sleep_time = (unsigned long)__sleep_time;
++
++      if (likely(sleep_time > 0)) {
++              /*
++               * User tasks that sleep a long time are categorised as
++               * idle and will get just interactive status to stay active &
++               * prevent them suddenly becoming cpu hogs and starving
++               * other processes.
++               */
++              if (p->mm && p->activated != -1 &&
++                      sleep_time > JUST_INTERACTIVE_SLEEP(p)){
++                              p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG -
++                                              AVG_TIMESLICE);
++                              if (!HIGH_CREDIT(p))
++                                      p->interactive_credit++;
++              } else {
++                      /*
++                       * The lower the sleep avg a task has the more
++                       * rapidly it will rise with sleep time.
++                       */
++                      sleep_time *= (MAX_BONUS - CURRENT_BONUS(p)) ? : 1;
++
++                      /*
++                       * Tasks with low interactive_credit are limited to
++                       * one timeslice worth of sleep avg bonus.
++                       */
++                      if (LOW_CREDIT(p) &&
++                              sleep_time > JIFFIES_TO_NS(task_timeslice(p)))
++                                      sleep_time =
++                                              JIFFIES_TO_NS(task_timeslice(p));
++
++                      /*
++                       * Non high_credit tasks waking from uninterruptible
++                       * sleep are limited in their sleep_avg rise as they
++                       * are likely to be cpu hogs waiting on I/O
++                       */
++                      if (p->activated == -1 && !HIGH_CREDIT(p) && p->mm){
++                              if (p->sleep_avg >= JUST_INTERACTIVE_SLEEP(p))
++                                      sleep_time = 0;
++                              else if (p->sleep_avg + sleep_time >=
++                                      JUST_INTERACTIVE_SLEEP(p)){
++                                              p->sleep_avg =
++                                                      JUST_INTERACTIVE_SLEEP(p);
++                                              sleep_time = 0;
++                                      }
++                      }
++
++                      /*
++                       * This code gives a bonus to interactive tasks.
++                       *
++                       * The boost works by updating the 'average sleep time'
++                       * value here, based on ->timestamp. 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;
++
++                      if (p->sleep_avg > NS_MAX_SLEEP_AVG){
++                              p->sleep_avg = NS_MAX_SLEEP_AVG;
++                              if (!HIGH_CREDIT(p))
++                                      p->interactive_credit++;
++                      }
++              }
++      }
++
++      p->prio = effective_prio(p);
++}
++
+ /*
+  * activate_task - move a task to the runqueue and do priority recalculation
+  *
+@@ -347,34 +461,33 @@
+  */
+ static inline void activate_task(task_t *p, runqueue_t *rq)
+ {
+-      long sleep_time = jiffies - p->last_run - 1;
++      unsigned long long now = sched_clock();
+-      if (sleep_time > 0) {
+-              int sleep_avg;
++      recalc_task_prio(p, now);
++      /*
++       * This checks to make sure it's not an uninterruptible task
++       * that is now waking up.
++       */
++      if (!p->activated){
+               /*
+-               * 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.
++               * Tasks which were woken up by interrupts (ie. hw events)
++               * are most likely of interactive nature. So we give them
++               * the credit of extending their sleep time to the period
++               * of time they spend on the runqueue, waiting for execution
++               * on a CPU, first time around:
+                */
+-              sleep_avg = p->sleep_avg + sleep_time;
+-
++              if (in_interrupt())
++                      p->activated = 2;
++              else
+               /*
+-               * '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.
++               * Normal first-time wakeups get a credit too for on-runqueue
++               * time, but it will be weighted down:
+                */
+-              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);
++                      p->activated = 1;
+               }
+-      }
++      p->timestamp = now;
++
+       __activate_task(p, rq);
+ }
+@@ -495,13 +608,19 @@
+                               task_rq_unlock(rq, &flags);
+                               goto repeat_lock_task;
+                       }
+-                      if (old_state == TASK_UNINTERRUPTIBLE)
++                      if (old_state == TASK_UNINTERRUPTIBLE){
+                               rq->nr_uninterruptible--;
++                              /*
++                               * Tasks on involuntary sleep don't earn
++                               * sleep_avg beyond just interactive state.
++                               */
++                              p->activated = -1;
++                      }
+                       if (sync)
+                               __activate_task(p, rq);
+                       else {
+                               activate_task(p, rq);
+-                              if (p->prio < rq->curr->prio)
++                              if (TASK_PREEMPTS_CURR(p, rq))
+                                       resched_task(rq->curr);
+                       }
+                       success = 1;
+@@ -550,8 +669,14 @@
+        * and children as well, to keep max-interactive tasks
+        * from forking tasks that are max-interactive.
+        */
+-      current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100;
+-      p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100;
++      current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) *
++              PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
++
++      p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) *
++              CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
++
++      p->interactive_credit = 0;
++
+       p->prio = effective_prio(p);
+       set_task_cpu(p, smp_processor_id());
+@@ -592,8 +717,9 @@
+        * the sleep_avg of the parent as well.
+        */
+       if (p->sleep_avg < p->parent->sleep_avg)
+-              p->parent->sleep_avg = (p->parent->sleep_avg * EXIT_WEIGHT +
+-                      p->sleep_avg) / (EXIT_WEIGHT + 1);
++              p->parent->sleep_avg = p->parent->sleep_avg /
++              (EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg /
++              (EXIT_WEIGHT + 1);
+ }
+ /**
+@@ -959,10 +1085,10 @@
+       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;
+       }
+@@ -972,7 +1098,7 @@
+        * 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,13 +1121,31 @@
+        * Note that idle threads have a prio of MAX_PRIO, for this test
+        * to be always true for them.
+        */
+-      if (p->prio < this_rq->curr->prio)
++      if (TASK_PREEMPTS_CURR(p, this_rq))
+               set_need_resched();
+-      else {
+-              if (p->prio == this_rq->curr->prio &&
+-                              p->time_slice > this_rq->curr->time_slice)
+-                      set_need_resched();
+-      }
++}
++
++/*
++ * Previously:
++ *
++ * #define CAN_MIGRATE_TASK(p,rq,this_cpu)    \
++ *    ((!idle || (NS_TO_JIFFIES(now - (p)->timestamp) > \
++ *            cache_decay_ticks)) && !task_running(rq, p) && \
++ *                    cpu_isset(this_cpu, (p)->cpus_allowed))
++ */
++
++static inline int
++can_migrate_task(task_t *tsk, runqueue_t *rq, int this_cpu, int idle)
++{
++      unsigned long delta = sched_clock() - tsk->timestamp;
++
++      if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks)))
++              return 0;
++      if (task_running(rq, tsk))
++              return 0;
++      if (!cpu_isset(this_cpu, tsk->cpus_allowed))
++              return 0;
++      return 1;
+ }
+ /*
+@@ -1025,6 +1169,12 @@
+               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
+@@ -1063,14 +1213,9 @@
+        * 3) are cache-hot on their current CPU.
+        */
+-#define CAN_MIGRATE_TASK(p,rq,this_cpu)                                       \
+-      ((!idle || (jiffies - (p)->last_run > cache_decay_ticks)) &&    \
+-              !task_running(rq, p) &&                                 \
+-                      cpu_isset(this_cpu, (p)->cpus_allowed))
+-
+       curr = curr->prev;
+-      if (!CAN_MIGRATE_TASK(tmp, busiest, this_cpu)) {
++      if (!can_migrate_task(tmp, busiest, this_cpu, idle)) {
+               if (curr != head)
+                       goto skip_queue;
+               idx++;
+@@ -1232,14 +1377,11 @@
+       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. 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.
+        */
+-      if (p->sleep_avg)
+-              p->sleep_avg--;
+       if (unlikely(rt_task(p))) {
+               /*
+                * RR tasks need a special form of timeslice management.
+@@ -1263,12 +1405,39 @@
+               p->time_slice = task_timeslice(p);
+               p->first_time_slice = 0;
++              if (!rq->expired_timestamp)
++                      rq->expired_timestamp = jiffies;
+               if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
+-                      if (!rq->expired_timestamp)
+-                              rq->expired_timestamp = jiffies;
+                       enqueue_task(p, rq->expired);
+               } else
+                       enqueue_task(p, rq->active);
++      } else {
++              /*
++               * Prevent a too long timeslice allowing a task to monopolize
++               * the CPU. We do this by splitting up the timeslice into
++               * smaller pieces.
++               *
++               * Note: this does not mean the task's timeslices expire or
++               * get lost in any way, they just might be preempted by
++               * another task of equal priority. (one with higher
++               * priority would have preempted this task already.) We
++               * requeue this task to the end of the list on this priority
++               * level, which is in essence a round-robin of tasks with
++               * equal priority.
++               *
++               * This only applies to tasks in the interactive
++               * delta range with at least TIMESLICE_GRANULARITY to requeue.
++               */
++              if (TASK_INTERACTIVE(p) && !((task_timeslice(p) -
++                      p->time_slice) % TIMESLICE_GRANULARITY(p)) &&
++                      (p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
++                      (p->array == rq->active)) {
++
++                      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);
+@@ -1287,6 +1456,8 @@
+       runqueue_t *rq;
+       prio_array_t *array;
+       struct list_head *queue;
++      unsigned long long now;
++      unsigned long run_time;
+       int idx;
+       /*
+@@ -1307,7 +1478,20 @@
+       rq = this_rq();
+       release_kernel_lock(prev);
+-      prev->last_run = jiffies;
++      now = sched_clock();
++      if (likely(now - prev->timestamp < NS_MAX_SLEEP_AVG))
++              run_time = now - prev->timestamp;
++      else
++              run_time = NS_MAX_SLEEP_AVG;
++
++      /*
++       * Tasks with interactive credits get charged less run_time
++       * at high sleep_avg to delay them losing their interactive
++       * status
++       */
++      if (HIGH_CREDIT(prev))
++              run_time /= (CURRENT_BONUS(prev) ? : 1);
++
+       spin_lock_irq(&rq->lock);
+       /*
+@@ -1357,12 +1541,33 @@
+       queue = array->queue + idx;
+       next = list_entry(queue->next, task_t, run_list);
++      if (next->activated > 0) {
++              unsigned long long delta = now - next->timestamp;
++
++              if (next->activated == 1)
++                      delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
++
++              array = next->array;
++              dequeue_task(next, array);
++              recalc_task_prio(next, next->timestamp + delta);
++              enqueue_task(next, array);
++      }
++      next->activated = 0;
+ switch_tasks:
+       prefetch(next);
+       clear_tsk_need_resched(prev);
+       RCU_qsctr(task_cpu(prev))++;
++      prev->sleep_avg -= run_time;
++      if ((long)prev->sleep_avg <= 0){
++              prev->sleep_avg = 0;
++              if (!(HIGH_CREDIT(prev) || LOW_CREDIT(prev)))
++                      prev->interactive_credit--;
++      }
++      prev->timestamp = now;
++
+       if (likely(prev != next)) {
++              next->timestamp = now;
+               rq->nr_switches++;
+               rq->curr = next;
+@@ -1602,6 +1807,7 @@
+       unsigned long flags;
+       prio_array_t *array;
+       runqueue_t *rq;
++      int old_prio, new_prio, delta;
+       if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
+               return;
+@@ -1610,6 +1816,12 @@
+        * the task might be in the middle of scheduling on another CPU.
+        */
+       rq = task_rq_lock(p, &flags);
++      /*
++       * The RT priorities are set via setscheduler(), but we still
++       * allow the 'normal' nice value to be set - but as expected
++       * it wont have any effect on scheduling until the task is
++       * not SCHED_NORMAL:
++       */
+       if (rt_task(p)) {
+               p->static_prio = NICE_TO_PRIO(nice);
+               goto out_unlock;
+@@ -1617,22 +1829,33 @@
+       array = p->array;
+       if (array)
+               dequeue_task(p, array);
++
++      old_prio = p->prio;
++      new_prio = NICE_TO_PRIO(nice);
++      delta = new_prio - old_prio;
+       p->static_prio = NICE_TO_PRIO(nice);
+-      p->prio = NICE_TO_PRIO(nice);
++      p->prio += delta;
++
+       if (array) {
+               enqueue_task(p, array);
+               /*
+-               * If the task is running and lowered its priority,
+-               * or increased its priority then reschedule its CPU:
++               * If the task increased its priority or is running and
++               * lowered its priority, then reschedule its CPU:
+                */
+-              if ((NICE_TO_PRIO(nice) < p->static_prio) ||
+-                                                      task_running(rq, p))
++              if (delta < 0 || (delta > 0 && task_running(rq, p)))
+                       resched_task(rq->curr);
+       }
+ 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__
+ /*
+@@ -2186,17 +2409,16 @@
+ 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  ");
+@@ -2208,13 +2430,7 @@
+       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
+@@ -2241,12 +2457,12 @@
+ #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) {
+@@ -2383,6 +2599,12 @@
+       local_irq_restore(flags);
+ }
++typedef struct {
++      int cpu;
++      struct completion startup_done;
++      task_t *task;
++} migration_startup_t;
++
+ /*
+  * migration_thread - this is a highprio system thread that performs
+  * thread migration by bumping thread off CPU then 'pushing' onto
+@@ -2392,20 +2614,21 @@
+ {
+       /* Marking "param" __user is ok, since we do a set_fs(KERNEL_DS); */
+       struct sched_param __user param = { .sched_priority = MAX_RT_PRIO-1 };
+-      int cpu = (long) data;
++      migration_startup_t *startup = data;
++      int cpu = startup->cpu;
+       runqueue_t *rq;
+       int ret;
++      startup->task = current;
++      complete(&startup->startup_done);
++      set_current_state(TASK_UNINTERRUPTIBLE);
++      schedule();
++
++      BUG_ON(smp_processor_id() != cpu);
++
+       daemonize("migration/%d", cpu);
+       set_fs(KERNEL_DS);
+-      /*
+-       * Either we are running on the right CPU, or there's a a
+-       * migration thread on this CPU, guaranteed (we're started
+-       * serially).
+-       */
+-      set_cpus_allowed(current, cpumask_of_cpu(cpu));
+-
+       ret = setscheduler(0, SCHED_FIFO, &param);
+       rq = this_rq();
+@@ -2415,6 +2638,9 @@
+               struct list_head *head;
+               migration_req_t *req;
++              if (current->flags & PF_FREEZE)
++                      refrigerator(PF_IOTHREAD);
++
+               spin_lock_irq(&rq->lock);
+               head = &rq->migration_queue;
+               current->state = TASK_INTERRUPTIBLE;
+@@ -2441,13 +2667,30 @@
+                         unsigned long action,
+                         void *hcpu)
+ {
++      long cpu = (long) hcpu;
++      migration_startup_t startup;
++
+       switch (action) {
+       case CPU_ONLINE:
+-              printk("Starting migration thread for cpu %li\n",
+-                     (long)hcpu);
+-              kernel_thread(migration_thread, hcpu, CLONE_KERNEL);
+-              while (!cpu_rq((long)hcpu)->migration_thread)
++
++              printk("Starting migration thread for cpu %li\n", cpu);
++
++              startup.cpu = cpu;
++              startup.task = NULL;
++              init_completion(&startup.startup_done);
++
++              kernel_thread(migration_thread, &startup, CLONE_KERNEL);
++              wait_for_completion(&startup.startup_done);
++              wait_task_inactive(startup.task);
++
++              startup.task->thread_info->cpu = cpu;
++              startup.task->cpus_allowed = cpumask_of_cpu(cpu);
++
++              wake_up_process(startup.task);
++
++              while (!cpu_rq(cpu)->migration_thread)
+                       yield();
++
+               break;
+       }
+       return NOTIFY_OK;
+@@ -2570,6 +2813,8 @@
+               prev_jiffy = jiffies;
+               printk(KERN_ERR "Debug: sleeping function called from invalid"
+                               " context at %s:%d\n", file, line);
++              printk("in_atomic():%d, irqs_disabled():%d\n",
++                              in_atomic(), irqs_disabled());
+               dump_stack();
+       }
+ #endif
+Index: linux-2.6.0-test5/kernel/signal.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/signal.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/signal.c  2003-09-27 11:38:41.346242800 +0800
+@@ -1139,7 +1139,7 @@
+ static int kill_something_info(int sig, struct siginfo *info, int pid)
+ {
+       if (!pid) {
+-              return kill_pg_info(sig, info, current->pgrp);
++              return kill_pg_info(sig, info, process_group(current));
+       } else if (pid == -1) {
+               int retval = 0, count = 0;
+               struct task_struct * p;
+@@ -1798,7 +1798,7 @@
+                       /* signals can be posted during this window */
+-                      if (is_orphaned_pgrp(current->pgrp))
++                      if (is_orphaned_pgrp(process_group(current)))
+                               goto relock;
+                       spin_lock_irq(&current->sighand->siglock);
+Index: linux-2.6.0-test5/kernel/softirq.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/softirq.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/softirq.c 2003-09-27 11:38:41.349242344 +0800
+@@ -9,8 +9,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/interrupt.h>
+-#include <linux/notifier.h>
+-#include <linux/percpu.h>
+ #include <linux/init.h>
+ #include <linux/mm.h>
+ #include <linux/notifier.h>
+@@ -59,11 +57,22 @@
+               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 +84,6 @@
+       if (pending) {
+               struct softirq_action *h;
+-              mask = ~pending;
+               local_bh_disable();
+ restart:
+               /* Reset the pending bitmask before enabling irqs */
+@@ -95,10 +103,8 @@
+               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();
+Index: linux-2.6.0-test5/kernel/sys.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sys.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/sys.c     2003-09-27 11:38:41.358240976 +0800
+@@ -290,7 +290,7 @@
+                       break;
+               case PRIO_PGRP:
+                       if (!who)
+-                              who = current->pgrp;
++                              who = process_group(current);
+                       for_each_task_pid(who, PIDTYPE_PGID, p, l, pid)
+                               error = set_one_prio(p, niceval, error);
+                       break;
+@@ -346,7 +346,7 @@
+                       break;
+               case PRIO_PGRP:
+                       if (!who)
+-                              who = current->pgrp;
++                              who = process_group(current);
+                       for_each_task_pid(who, PIDTYPE_PGID, p, l, pid) {
+                               niceval = 20 - task_nice(p);
+                               if (niceval > retval)
+@@ -456,8 +456,11 @@
+ #ifdef CONFIG_SOFTWARE_SUSPEND
+       case LINUX_REBOOT_CMD_SW_SUSPEND:
+-              if (!pm_suspend(PM_SUSPEND_DISK))
+-                      break;
++              if (!software_suspend_enabled) {
++                      unlock_kernel();
++                      return -EAGAIN;
++              }
++              software_suspend();
+               do_exit(0);
+               break;
+ #endif
+@@ -979,11 +982,12 @@
+       if (err)
+               goto out;
+-      if (p->pgrp != pgid) {
++      if (process_group(p) != pgid) {
+               detach_pid(p, PIDTYPE_PGID);
+-              p->pgrp = pgid;
++              p->group_leader->__pgrp = pgid;
+               attach_pid(p, PIDTYPE_PGID, pgid);
+       }
++
+       err = 0;
+ out:
+       /* All paths lead to here, thus we are safe. -DaveM */
+@@ -994,7 +998,7 @@
+ asmlinkage long sys_getpgid(pid_t pid)
+ {
+       if (!pid) {
+-              return current->pgrp;
++              return process_group(current);
+       } else {
+               int retval;
+               struct task_struct *p;
+@@ -1006,7 +1010,7 @@
+               if (p) {
+                       retval = security_task_getpgid(p);
+                       if (!retval)
+-                              retval = p->pgrp;
++                              retval = process_group(p);
+               }
+               read_unlock(&tasklist_lock);
+               return retval;
+@@ -1016,7 +1020,7 @@
+ asmlinkage long sys_getpgrp(void)
+ {
+       /* SMP - assuming writes are word atomic this is fine */
+-      return current->pgrp;
++      return process_group(current);
+ }
+ asmlinkage long sys_getsid(pid_t pid)
+@@ -1059,7 +1063,7 @@
+       __set_special_pids(current->pid, current->pid);
+       current->tty = NULL;
+       current->tty_old_pgrp = 0;
+-      err = current->pgrp;
++      err = process_group(current);
+ out:
+       write_unlock_irq(&tasklist_lock);
+       return err;
+Index: linux-2.6.0-test5/kernel/sysctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sysctl.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/sysctl.c  2003-09-27 11:38:41.370239152 +0800
+@@ -643,7 +643,7 @@
+               .data           = &dirty_writeback_centisecs,
+               .maxlen         = sizeof(dirty_writeback_centisecs),
+               .mode           = 0644,
+-              .proc_handler   = dirty_writeback_centisecs_handler,
++              .proc_handler   = &dirty_writeback_centisecs_handler,
+       },
+       {
+               .ctl_name       = VM_DIRTY_EXPIRE_CS,
+Index: linux-2.6.0-test5/lib/inflate.c
+===================================================================
+--- linux-2.6.0-test5.orig/lib/inflate.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/lib/inflate.c    2003-09-27 11:38:41.380237632 +0800
+@@ -871,7 +871,7 @@
+   {
+ DEBG("dyn5b ");
+     if (i == 1) {
+-      error(" incomplete literal tree\n");
++      error("incomplete literal tree");
+       huft_free(tl);
+     }
+     return i;                   /* incomplete code set */
+@@ -882,7 +882,7 @@
+   {
+ DEBG("dyn5d ");
+     if (i == 1) {
+-      error(" incomplete distance tree\n");
++      error("incomplete distance tree");
+ #ifdef PKZIP_BUG_WORKAROUND
+       i = 0;
+     }
+@@ -1097,15 +1097,15 @@
+     flags  = (uch)get_byte();
+     if ((flags & ENCRYPTED) != 0) {
+-          error("Input is encrypted\n");
++          error("Input is encrypted");
+           return -1;
+     }
+     if ((flags & CONTINUATION) != 0) {
+-          error("Multi part input\n");
++          error("Multi part input");
+           return -1;
+     }
+     if ((flags & RESERVED) != 0) {
+-          error("Input has invalid flags\n");
++          error("Input has invalid flags");
+           return -1;
+     }
+     (ulg)get_byte();  /* Get timestamp */
+Index: linux-2.6.0-test5/lib/kobject.c
+===================================================================
+--- linux-2.6.0-test5.orig/lib/kobject.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/lib/kobject.c    2003-09-27 11:38:41.385236872 +0800
+@@ -236,8 +236,6 @@
+               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 @@
+       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)
+Index: linux-2.6.0-test5/lib/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/lib/Makefile        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/lib/Makefile     2003-09-27 11:38:41.386236720 +0800
+@@ -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
+Index: linux-2.6.0-test5/lib/parser.c
+===================================================================
+--- linux-2.6.0-test5.orig/lib/parser.c        2003-09-27 11:38:18.489717520 +0800
++++ linux-2.6.0-test5/lib/parser.c     2003-09-27 11:38:41.387236568 +0800
+@@ -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, 0);
++      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);
+Index: linux-2.6.0-test5/MAINTAINERS
+===================================================================
+--- linux-2.6.0-test5.orig/MAINTAINERS 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/MAINTAINERS      2003-09-27 11:38:41.399234744 +0800
+@@ -169,8 +169,8 @@
+ S:    Supported
+ ACPI
+-P:    Andy Grover
+-M:    andrew.grover@intel.com
++P:    Len Brown
++M:    len.brown@intel.com
+ L:    acpi-devel@lists.sourceforge.net
+ W:    http://sf.net/projects/acpi/
+ S:    Maintained
+@@ -212,7 +212,7 @@
+ ALCATEL SPEEDTOUCH USB DRIVER
+ P:    Duncan Sands
+-M:    duncan.sands@wanadoo.fr
++M:    duncan.sands@free.fr
+ L:    linux-usb-users@lists.sourceforge.net
+ L:    linux-usb-devel@lists.sourceforge.net
+ W:    http://www.linux-usb.org/SpeedTouch/
+@@ -328,18 +328,66 @@
+ L:    linux-kernel@vger.kernel.org
+ S:    Maintained
+-BLUETOOTH SUBSYSTEM (BlueZ)
++BLUETOOTH SUBSYSTEM
+ P:    Maxim Krasnyansky
+ M:    maxk@qualcomm.com
+ W:    http://bluez.sf.net
+ S:    Maintained
+-BLUETOOTH SUBSYSTEM (PC Card Drivers)
++BLUETOOTH RFCOMM LAYER
++P:    Maxim Krasnyansky
++M:    maxk@qualcomm.com
++W:    http://bluez.sf.net
++S:    Maintained
++
++BLUETOOTH BNEP LAYER
++P:    Maxim Krasnyansky
++M:    maxk@qualcomm.com
++W:    http://bluez.sf.net
++S:    Maintained
++
++BLUETOOTH HCI USB DRIVER
++P:    Maxim Krasnyansky
++M:    maxk@qualcomm.com
++W:    http://bluez.sf.net
++S:    Maintained
++
++BLUETOOTH HCI UART DRIVER
++P:    Maxim Krasnyansky
++M:    maxk@qualcomm.com
++W:    http://bluez.sf.net
++S:    Maintained
++
++BLUETOOTH HCI DTL1 DRIVER
++P:    Marcel Holtmann
++M:    marcel@holtmann.org
++W:    http://www.holtmann.org/linux/bluetooth/
++S:    Maintained
++
++BLUETOOTH HCI BLUECARD DRIVER
+ P:    Marcel Holtmann
+ M:    marcel@holtmann.org
+ W:    http://www.holtmann.org/linux/bluetooth/
+ S:    Maintained
++BLUETOOTH HCI BT3C DRIVER
++P:    Marcel Holtmann
++M:    marcel@holtmann.org
++W:    http://www.holtmann.org/linux/bluetooth/
++S:    Maintained
++
++BLUETOOTH HCI BTUART DRIVER
++P:    Marcel Holtmann
++M:    marcel@holtmann.org
++W:    http://www.holtmann.org/linux/bluetooth/
++S:    Maintained
++
++BLUETOOTH HCI VHCI DRIVER
++P:    Maxim Krasnyansky
++M:    maxk@qualcomm.com
++W:    http://bluez.sf.net
++S:    Maintained
++
+ BONDING DRIVER
+ P:   Chad Tindel
+ M:   ctindel@users.sourceforge.net
+@@ -557,21 +605,19 @@
+ S:    Maintained
+ DEVICE FILESYSTEM
+-P:    Richard Gooch
+-M:    rgooch@atnf.csiro.au
+-L:    linux-kernel@vger.kernel.org
+-S:    Maintained
++S:    Obsolete
+-DIGI INTL. EPCA DRIVER
++DIGI INTL. EPCA PCI (DGAP) DRIVER
+ P:    Digi International, Inc
+ M:    Eng.Linux@digi.com
+ L:    Eng.Linux@digi.com
+ W:    http://www.digi.com
+-S:    Maintained
++S:    Supported
+-DIGI RIGHTSWITCH NETWORK DRIVER
+-P:    Rick Richardson
+-L:    linux-net@vger.kernel.org
++DIGI INTL. EPCA ISA DRIVER
++P:    Digi International, Inc
++M:    Eng.Linux@digi.com
++L:    Eng.Linux@digi.com
+ W:    http://www.digi.com
+ S:    Orphaned
+@@ -582,6 +628,12 @@
+ L:    digilnux@dgii.com
+ S:    Orphaned
++DIGI RIGHTSWITCH NETWORK DRIVER
++P:    Rick Richardson
++L:    linux-net@vger.kernel.org
++W:    http://www.digi.com
++S:    Orphaned
++
+ DIRECTORY NOTIFICATION
+ P:    Stephen Rothwell
+ M:    sfr@canb.auug.org.au
+@@ -661,6 +713,11 @@
+ 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
+@@ -1094,6 +1151,12 @@
+ 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
+@@ -1159,6 +1222,13 @@
+ L:    linuxppc64-dev@lists.linuxppc.org
+ S:    Supported
++LINUX SECURITY MODULE (LSM) FRAMEWORK
++P:    Chris Wright
++M:    chrisw@osdl.org
++L:    linux-security-module@wirex.com
++W:    http://lsm.immunix.org
++S:    Supported
++
+ LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
+ P:    Richard Russon (FlatCap)
+ M:    ldm@flatcap.org
+Index: linux-2.6.0-test5/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/Makefile    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/Makefile 2003-09-27 11:38:41.408233376 +0800
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 0
+-EXTRAVERSION = -test5
++EXTRAVERSION = -test5-mm4
+ # *DOCUMENTATION*
+ # To see a list of typical targets execute "make help"
+@@ -9,6 +9,9 @@
+ # Comments in this file are targeted only to the developer, do not
+ # expect to learn how to build the kernel reading this file.
++# Do not print "Entering directory ..."
++MAKEFLAGS += --no-print-directory
++
+ # We are using a recursive build, so we need to do a little thinking
+ # to get the ordering right.
+ #
+@@ -25,6 +28,87 @@
+ # descending is started. They are now explicitly listed as the
+ # prepare rule.
++# To put more focus on warnings, be less verbose as default
++# Use 'make V=1' to see the full commands
++
++ifdef V
++  ifeq ("$(origin V)", "command line")
++    KBUILD_VERBOSE = $(V)
++  endif
++endif
++ifndef KBUILD_VERBOSE
++  KBUILD_VERBOSE = 0
++endif
++
++# Call sparse as part of compilation of C files
++# Use 'make C=1' to enable sparse checking
++
++ifdef C
++  ifeq ("$(origin C)", "command line")
++    KBUILD_CHECKSRC = $(C)
++  endif
++endif
++ifndef KBUILD_CHECKSRC
++  KBUILD_CHECKSRC = 0
++endif
++
++# kbuild supports saving output files in a separate directory.
++# To locate output files in a separate directory two syntax'es are supported.
++# In both cases the working directory must be the root of the kernel src.
++# 1) O=
++# Use "make O=dir/to/store/output/files/"
++#
++# 2) Set KBUILD_OUTPUT
++# Set the environment variable KBUILD_OUTPUT to point to the directory
++# where the output files shall be placed.
++# export KBUILD_OUTPUT=dir/to/store/output/files/
++# make
++#
++# The O= assigment takes precedence over the KBUILD_OUTPUT environment variable.
++
++
++# KBUILD_SRC is set on invocation of make in OBJ directory
++# KBUILD_SRC is not intended to be used by the regular user (for now)
++ifeq ($(KBUILD_SRC),)
++
++# OK, Make called in directory where kernel src resides
++# Do we want to locate output files in a separate directory?
++ifdef O
++  ifeq ("$(origin O)", "command line")
++    KBUILD_OUTPUT := $(O)
++  endif
++endif
++
++ifneq ($(KBUILD_OUTPUT),)
++# Invoke a second make in the output directory, passing relevant variables
++      KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT); /bin/pwd)
++
++.PHONY: $(MAKECMDGOALS) 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)
++
++# Leave processing to above invocation of make
++skip-makefile := 1
++endif # ifneq ($(KBUILD_OUTPUT),)
++endif # ifeq ($(KBUILD_SRC),)
++
++# We process the rest of the Makefile if this is the final invocation of make
++ifeq ($(skip-makefile),)
++
++srctree               := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
++TOPDIR                := $(srctree)
++# FIXME - TOPDIR is obsolete, use srctree/objtree
++objtree               := $(CURDIR)
++src           := $(srctree)
++obj           := $(objtree)
++
++VPATH         := $(srctree)
++
++export srctree objtree VPATH TOPDIR
++
+ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+ # SUBARCH tells the usermode build what the underlying arch is.  That is set
+@@ -37,9 +121,6 @@
+                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
+                                 -e s/s390x/s390/ -e s/parisc64/parisc/ )
+-# Remove hyphens since they have special meaning in RPM filenames
+-KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE))
+-
+ # Cross compiling and selecting different set of gcc/bin-utils
+ # ---------------------------------------------------------------------------
+ #
+@@ -69,7 +150,6 @@
+ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+         else if [ -x /bin/bash ]; then echo /bin/bash; \
+         else echo sh; fi ; fi)
+-TOPDIR        := $(CURDIR)
+ HOSTCC        = gcc
+ HOSTCXX       = g++
+@@ -110,40 +190,8 @@
+   KBUILD_MODULES := 1
+ endif
+-export KBUILD_MODULES KBUILD_BUILTIN KBUILD_VERBOSE KBUILD_CHECKSRC
+-
+-# To put more focus on warnings, less verbose as default
+-# Use 'make V=1' to see the full commands
+-
+-ifdef V
+-  ifeq ("$(origin V)", "command line")
+-    KBUILD_VERBOSE = $(V)
+-  endif
+-endif
+-ifndef KBUILD_VERBOSE
+-  KBUILD_VERBOSE = 0 
+-endif
+-
+-# Call sparse as part of compilation of C files
+-# Use 'make C=1' to enable sparse checking
+-
+-ifdef C
+-  ifeq ("$(origin C)", "command line")
+-    KBUILD_CHECKSRC = $(C)
+-  endif
+-endif
+-ifndef KBUILD_CHECKSRC
+-  KBUILD_CHECKSRC = 0
+-endif
+-
+-# Do not print 'Entering directory ...'
+-
+-MAKEFLAGS += --no-print-directory
+-
+-# For maximum performance (+ possibly random breakage, uncomment
+-# the following)
+-
+-#MAKEFLAGS += -rR
++export KBUILD_MODULES KBUILD_BUILTIN KBUILD_VERBOSE
++export KBUILD_CHECKSRC KBUILD_SRC
+ # Beautify output
+ # ---------------------------------------------------------------------------
+@@ -183,16 +231,17 @@
+   quiet=silent_
+ endif
+-export quiet Q KBUILD_VERBOSE
++check_gcc = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+-# Paths to obj / src tree
++export quiet Q KBUILD_VERBOSE check_gcc
+-src   := .
+-obj   := .
+-srctree := .
+-objtree := .
++# Look for make include files relative to root of kernel src
++MAKEFLAGS += --include-dir=$(srctree)
++
++# For maximum performance (+ possibly random breakage, uncomment
++# the following)
+-export srctree objtree
++#MAKEFLAGS += -rR
+ # Make variables (CC, etc...)
+@@ -222,13 +271,15 @@
+ NOSTDINC_FLAGS  = -nostdinc -iwithprefix include
+-CPPFLAGS      := -D__KERNEL__ -Iinclude
++CPPFLAGS        := -D__KERNEL__ -Iinclude \
++                 $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include)
++
+ CFLAGS                := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
+                  -fno-strict-aliasing -fno-common
+ AFLAGS                := -D__ASSEMBLY__
+ export        VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
+-      CONFIG_SHELL TOPDIR HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
++      CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
+       CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
+       HOSTCXX HOSTCXXFLAGS LDFLAGS_BLOB LDFLAGS_MODULE CHECK
+@@ -294,7 +345,7 @@
+ # Handle them one by one.
+ %:: FORCE
+-      $(Q)$(MAKE) $@
++      $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
+ else
+ ifeq ($(config-targets),1)
+@@ -341,7 +392,7 @@
+ endif
+-include arch/$(ARCH)/Makefile
++include $(srctree)/arch/$(ARCH)/Makefile
+ # Let architecture Makefiles change CPPFLAGS if needed
+ CFLAGS := $(CPPFLAGS) $(CFLAGS)
+@@ -378,6 +429,9 @@
+ CFLAGS                += -g
+ endif
++# warn about C99 declaration after statement
++CFLAGS += $(call check_gcc,-Wdeclaration-after-statement,)
++
+ #
+ # INSTALL_PATH specifies where to place the updated kernel and system map
+ # images.  Uncomment if you want to place them anywhere other than root.
+@@ -487,14 +541,34 @@
+ #     Handle descending into subdirectories listed in $(SUBDIRS)
+ .PHONY: $(SUBDIRS)
+-$(SUBDIRS): prepare
++$(SUBDIRS): prepare-all
+       $(Q)$(MAKE) $(build)=$@
+-#     Things we need done before we descend to build or make
+-#     module versions are listed in "prepare"
++# Things we need to do before we recursively start building the kernel
++# or the modules are listed in "prepare-all".
++# A multi level approach is used. prepare1 is updated first, then prepare0.
++# prepare-all is the collection point for the prepare targets.
++
++.PHONY: prepare-all prepare prepare0 prepare1
++
++# prepare1 is used to check if we are building in a separate output directory,
++# and if so do:
++# 1) Check that make has not been executed in the kernel src $(srctree)
++# 2) Create the include2 directory, used for the second asm symlink
++
++prepare1:
++ifneq ($(KBUILD_SRC),)
++      @echo '  Using $(srctree) as source for kernel'
++      $(Q)if [ -h $(srctree)/include/asm -o -f $(srctree)/.config ]; then \
++              echo "  $(srctree) is not clean, please run 'make mrproper'";\
++              echo "  in the '$(srctree)' directory.";\
++              /bin/false; \
++      fi;
++      $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
++      $(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
++endif
+-.PHONY: prepare
+-prepare: include/linux/version.h include/asm include/config/MARKER
++prepare0: prepare1 include/linux/version.h include/asm include/config/MARKER
+ ifdef KBUILD_MODULES
+ ifeq ($(origin SUBDIRS),file)
+       $(Q)rm -rf $(MODVERDIR)
+@@ -505,6 +579,9 @@
+ endif
+       $(if $(CONFIG_MODULES),$(Q)mkdir -p $(MODVERDIR))
++# All the preparing..
++prepare-all: prepare0 prepare
++
+ #     Leave this as default for preprocessing vmlinux.lds.S, which is now
+ #     done in arch/$(ARCH)/kernel/Makefile
+@@ -533,8 +610,9 @@
+ #     before switching between archs anyway.
+ include/asm:
+-      @echo '  Making asm->asm-$(ARCH) symlink'
+-      @ln -s asm-$(ARCH) $@
++      @echo '  SYMLINK $@ -> include/asm-$(ARCH)'
++      $(Q)if [ ! -d include ]; then mkdir -p include; fi;
++      @ln -fsn asm-$(ARCH) $@
+ #     Split autoconf.h into include/linux/config/*
+@@ -585,7 +663,7 @@
+ .PHONY: modules
+ modules: $(SUBDIRS) $(if $(KBUILD_BUILTIN),vmlinux)
+       @echo '  Building modules, stage 2.';
+-      $(Q)$(MAKE) -rR -f scripts/Makefile.modpost
++      $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+ #     Install modules
+@@ -603,7 +681,7 @@
+       @rm -f $(MODLIB)/build
+       @mkdir -p $(MODLIB)/kernel
+       @ln -s $(TOPDIR) $(MODLIB)/build
+-      $(Q)$(MAKE) -rR -f scripts/Makefile.modinst
++      $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst
+ # If System.map exists, run depmod.  This deliberately does not have a
+ # dependency on System.map since that would run the dependency tree on
+@@ -680,7 +758,8 @@
+       $(MODVERDIR) \
+       .tmp_export-objs \
+       include/config \
+-      include/linux/modules
++      include/linux/modules \
++      include2
+ # clean - Delete all intermediate files
+ #
+@@ -759,31 +838,32 @@
+ .PHONY: rpm
++# Remove hyphens since they have special meaning in RPM filenames
++KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE))
++
+ #     If you do a make spec before packing the tarball you can rpm -ta it
+ spec:
+-      . $(srctree)/scripts/mkspec >kernel.spec
++      $(CONFIG_SHELL) $(srctree)/scripts/mkspec > $(objtree)/kernel.spec
+-#     Build a tar ball, generate an rpm from it and pack the result
+-#     There are two bits of magic here
+-#     1) The use of /. to avoid tar packing just the symlink
+-#     2) Removing the .dep files as they have source paths in them that
+-#        will become invalid
++#     a) Build a tar ball
++#     b) generate an rpm from it
++#     c) and pack the result
++#     - Use /. to avoid tar packing just the symlink
+ rpm:  clean spec
+-      find . $(RCS_FIND_IGNORE) \
+-              \( -size 0 -o -name .depend -o -name .hdepend \) \
+-              -type f -print | xargs rm -f
+       set -e; \
+-      cd $(TOPDIR)/.. ; \
+-      ln -sf $(TOPDIR) $(KERNELPATH) ; \
++      cd .. ; \
++      ln -sf $(srctree) $(KERNELPATH) ; \
+       tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
+-      rm $(KERNELPATH) ; \
+-      cd $(TOPDIR) ; \
+-      $(CONFIG_SHELL) $(srctree)/scripts/mkversion > .tmp_version ; \
+-      mv -f .tmp_version .version; \
+-      $(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
+-      rm $(TOPDIR)/../$(KERNELPATH).tar.gz
++      rm $(KERNELPATH)
++
++      set -e; \
++      $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version;\
++      mv -f $(objtree)/.tmp_version $(objtree)/.version;
++
++      $(RPM) -ta ../$(KERNELPATH).tar.gz
++      rm ../$(KERNELPATH).tar.gz
+ # Brief documentation of the typical targets used
+ # ---------------------------------------------------------------------------
+@@ -814,6 +894,7 @@
+               echo '  No architecture specific help defined for $(ARCH)')
+       @echo  ''
+       @echo  '  make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
++      @echo  '  make O=dir [targets] Locate all output files in "dir", including .config'
+       @echo  '  make C=1   [targets] Check all c source with checker tool'
+       @echo  ''
+       @echo  'Execute "make" or "make all" to build all targets marked with [*] '
+@@ -849,7 +930,8 @@
+ # FIXME Should go into a make.lib or something 
+ # ===========================================================================
+-a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) $(NOSTDINC_FLAGS) \
++a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \
++        $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+         $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+ quiet_cmd_as_o_S = AS      $@
+@@ -907,6 +989,7 @@
+ define filechk
+       @set -e;                                \
+       echo '  CHK     $@';                    \
++      mkdir -p $(dir $@);                     \
+       $(filechk_$(1)) < $< > $@.tmp;          \
+       if [ -r $@ ] && cmp -s $@ $@.tmp; then  \
+               rm -f $@.tmp;                   \
+@@ -919,16 +1002,18 @@
+ # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=dir
+ # Usage:
+ # $(Q)$(MAKE) $(build)=dir
+-build := -f scripts/Makefile.build obj
++build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
+ # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
+ # Usage:
+ # $(Q)$(MAKE) $(clean)=dir
+-clean := -f scripts/Makefile.clean obj
++clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+ #     $(call descend,<dir>,<target>)
+ #     Recursively call a sub-make in <dir> with target <target>
+ # Usage is deprecated, because make does not see this as an invocation of make.
+-descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
++descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
++
++endif # skip-makefile
+ FORCE:
+Index: linux-2.6.0-test5/mm/fadvise.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/fadvise.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/fadvise.c     2003-09-27 11:38:41.410233072 +0800
+@@ -20,7 +20,7 @@
+  * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
+  * deactivate the pages and clear PG_Referenced.
+  */
+-long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
++asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
+ {
+       struct file *file = fget(fd);
+       struct inode *inode;
+@@ -80,7 +80,7 @@
+       return ret;
+ }
+-long sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
++asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
+ {
+       return sys_fadvise64_64(fd, offset, len, advice);
+ }
+Index: linux-2.6.0-test5/mm/filemap.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/filemap.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/filemap.c     2003-09-27 11:38:41.423231096 +0800
+@@ -70,6 +70,9 @@
+  *  ->mmap_sem
+  *    ->i_sem                 (msync)
+  *
++ *  ->i_alloc_sem
++ *    ->i_sem                   (various)
++ *
+  *  ->inode_lock
+  *    ->sb_lock                       (fs/fs-writeback.c)
+  *    ->mapping->page_lock    (__sync_single_inode)
+@@ -281,21 +284,42 @@
+       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 +329,9 @@
+  * 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
+@@ -342,26 +368,51 @@
+ 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);
+@@ -411,8 +462,8 @@
+  *
+  * 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 +474,10 @@
+               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 +492,12 @@
+       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
+  *
+@@ -496,9 +556,12 @@
+  * 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 +569,12 @@
+       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;
+ }
+@@ -560,21 +626,47 @@
+                            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 +677,6 @@
+               }
+               cond_resched();
+-              page_cache_readahead(mapping, ra, filp, index);
+               nr = nr - offset;
+ find_page:
+@@ -635,7 +726,12 @@
+                       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 +753,23 @@
+               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;
+@@ -782,6 +888,10 @@
+                       goto out; /* skip atime */
+               size = i_size_read(inode);
+               if (pos < size) {
++                      if (S_ISREG(inode->i_mode)) {
++                              down_read(&inode->i_alloc_sem);
++                              down(&inode->i_sem);
++                      }
+                       retval = generic_file_direct_IO(READ, iocb,
+                                               iov, pos, nr_segs);
+                       if (retval >= 0 && !is_sync_kiocb(iocb))
+@@ -790,6 +900,12 @@
+                               *ppos = pos + retval;
+               }
+               update_atime(filp->f_dentry->d_inode);
++              /*
++               * i_sem and i_alloc_sem release are handled by
++               * the direct i/o code, the former is released after
++               * i/o submission, the latter set up to be released
++               * on actual i/o completion.
++               */
+               goto out;
+       }
+@@ -816,19 +932,18 @@
+       return retval;
+ }
+-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;
+@@ -841,7 +956,8 @@
+       return ret;
+ }
+-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;
+@@ -1266,6 +1382,20 @@
+                       page_cache_release(page);
+                       return err;
+               }
++      } else {
++              /*
++               * If a nonlinear mapping then store the file page offset
++               * in the pte.
++               */
++              unsigned long pgidx;
++              pgidx = (addr - vma->vm_start) >> PAGE_SHIFT;
++              pgidx += vma->vm_pgoff;
++              pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
++              if (pgoff != pgidx) {
++                      err = install_file_pte(mm, vma, addr, pgoff, prot);
++                      if (err)
++                              return err;
++              }
+       }
+       len -= PAGE_SIZE;
+@@ -1404,7 +1534,9 @@
+       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);
+@@ -1437,7 +1569,7 @@
+       /* was any of the uid bits set? */
+       if (mode && !capable(CAP_FSETID)) {
+-              newattrs.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
++              newattrs.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_FORCE;
+               notify_change(dentry, &newattrs);
+       }
+ }
+@@ -1628,6 +1760,9 @@
+ /*
+  * Write to a file through the page cache. 
++ * Should be called with the following semaphores already held:
++ *    i_alloc_sem (only for O_DIRECT writes to regular files)
++ *    i_sem (only for regular 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
+@@ -1636,7 +1771,7 @@
+  *                                                    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;
+@@ -1691,7 +1826,6 @@
+       if (err)
+               goto out;
+-
+       if (count == 0)
+               goto out;
+@@ -1721,7 +1855,14 @@
+                       status = generic_osync_inode(inode, 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;
++              if (S_ISREG(inode->i_mode))
++                      down(&inode->i_sem);
+       }
+       buf = iov->iov_base;
+@@ -1745,6 +1886,10 @@
+               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;
+@@ -1793,7 +1938,11 @@
+               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;
+@@ -1804,12 +1953,21 @@
+       /*
+        * 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);
++              }
++      }
++
++      if (unlikely(file->f_flags & O_DIRECT)) {
++              if (written)
++                      do_fdatasync(file);
++              if (S_ISREG(inode->i_mode))
++                      up(&inode->i_sem);
+       }
+-      
++
+ out_status:   
+       err = written ? written : status;
+ out:
+@@ -1818,6 +1976,65 @@
+       return err;
+ }
++/*
++ * Should be called with the following semaphores already held:
++ *    i_alloc_sem (only for O_DIRECT writes to regular files)
++ *    i_sem (only for regular files)
++ */
++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_dentry->d_inode->i_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;
++}
++
++/*
++ * Should be called with the following semaphores already held:
++ *    i_alloc_sem (only for O_DIRECT writes to regular files)
++ *    i_sem (only for regular files)
++ */
+ ssize_t
+ generic_file_write_nolock(struct file *file, const struct iovec *iov,
+                               unsigned long nr_segs, loff_t *ppos)
+@@ -1836,18 +2053,44 @@
+                              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, 
++      if (file->f_flags & O_DIRECT)
++              down_read(&inode->i_alloc_sem);
++      ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
+                                               &iocb->ki_pos);
+-      up(&inode->i_sem);
++      /*
++       * For O_DIRECT, i_sem would have already been released and
++       * i_alloc_sem is released on i/o completion.
++       */
++      if (!(file->f_flags & O_DIRECT))
++              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);
+@@ -1855,15 +2098,31 @@
+ 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 };
++      if (file->f_flags & O_DIRECT)
++              down_read(&inode->i_alloc_sem);
+       down(&inode->i_sem);
+-      err = generic_file_write_nolock(file, &local_iov, 1, ppos);
+-      up(&inode->i_sem);
++      ret = __generic_file_write_nolock(file, &local_iov, 1, ppos);
++      /*
++       * For O_DIRECT, i_sem would have already been released and
++       * i_alloc_sem is released on i/o completion
++       */
++      if (!(file->f_flags & O_DIRECT))
++              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,
+@@ -1880,23 +2139,45 @@
+ }
+ 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;
++      if (file->f_flags & O_DIRECT)
++              down_read(&inode->i_alloc_sem);
+       down(&inode->i_sem);
+-      ret = generic_file_write_nolock(file, iov, nr_segs, ppos);
+-      up(&inode->i_sem);
++      ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);
++      /*
++       * For O_DIRECT, i_sem would have already been released and
++       * i_alloc_sem is released on i/o completion.
++       */
++      if (!(file->f_flags & O_DIRECT))
++              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;
+ }
++/*
++ * For regular files, i_sem and i_alloc_sem should be held already.
++ * i_sem may be dropped later once we've mapped the new IO.
++ * i_alloc_sem is kept until the IO completes.
++ */
+ 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 inode *inode = file->f_dentry->d_inode;
++      struct address_space *mapping = inode->i_mapping;
+       ssize_t retval;
+       if (mapping->nrpages) {
+@@ -1910,6 +2191,10 @@
+       retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs);
+       if (rw == WRITE && mapping->nrpages)
+               invalidate_inode_pages2(mapping);
++      return retval;
+ out:
++      up(&inode->i_sem);
++      if (S_ISREG(inode->i_mode))
++              up_read(&inode->i_alloc_sem);
+       return retval;
+ }
+Index: linux-2.6.0-test5/mm/fremap.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/fremap.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/fremap.c      2003-09-27 11:38:41.426230640 +0800
+@@ -61,6 +61,7 @@
+       pte_t *pte;
+       pgd_t *pgd;
+       pmd_t *pmd;
++      pte_t pte_val;
+       struct pte_chain *pte_chain;
+       pte_chain = pte_chain_alloc(GFP_KERNEL);
+@@ -83,10 +84,11 @@
+       flush_icache_page(vma, page);
+       set_pte(pte, mk_pte(page, prot));
+       pte_chain = page_add_rmap(page, pte, pte_chain);
++      pte_val = *pte;
+       pte_unmap(pte);
+       if (flush)
+               flush_tlb_page(vma, addr);
+-      update_mmu_cache(vma, addr, *pte);
++      update_mmu_cache(vma, addr, pte_val);
+       spin_unlock(&mm->page_table_lock);
+       pte_chain_free(pte_chain);
+       return 0;
+@@ -100,6 +102,47 @@
+ EXPORT_SYMBOL(install_page);
++/*
++ * Install a file pte to a given virtual memory address, release any
++ * previously existing mapping.
++ */
++int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma,
++              unsigned long addr, unsigned long pgoff, pgprot_t prot)
++{
++      int err = -ENOMEM, flush;
++      pte_t *pte;
++      pgd_t *pgd;
++      pmd_t *pmd;
++      pte_t pte_val;
++
++      pgd = pgd_offset(mm, addr);
++      spin_lock(&mm->page_table_lock);
++
++      pmd = pmd_alloc(mm, pgd, addr);
++      if (!pmd)
++              goto err_unlock;
++
++      pte = pte_alloc_map(mm, pmd, addr);
++      if (!pte)
++              goto err_unlock;
++
++      flush = zap_pte(mm, vma, addr, pte);
++
++      set_pte(pte, pgoff_to_pte(pgoff));
++      pte_val = *pte;
++      pte_unmap(pte);
++      if (flush)
++              flush_tlb_page(vma, addr);
++      update_mmu_cache(vma, addr, pte_val);
++      spin_unlock(&mm->page_table_lock);
++      return 0;
++
++err_unlock:
++      spin_unlock(&mm->page_table_lock);
++      return err;
++}
++
++
+ /***
+  * sys_remap_file_pages - remap arbitrary pages of a shared backing store
+  *                        file within an existing vma.
+Index: linux-2.6.0-test5/mm/highmem.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/highmem.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/highmem.c     2003-09-27 11:38:41.430230032 +0800
+@@ -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 @@
+ {
+       int i;
+-      flush_cache_all();
++      flush_cache_kmaps();
+       for (i = 0; i < LAST_PKMAP; i++) {
+               struct page *page;
+Index: linux-2.6.0-test5/mm/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/mm/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/Makefile      2003-09-27 11:38:41.432229728 +0800
+@@ -12,3 +12,6 @@
+                          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
++
+Index: linux-2.6.0-test5/mm/memory.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/memory.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/memory.c      2003-09-27 11:38:41.443228056 +0800
+@@ -100,7 +100,8 @@
+       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 @@
+       }
+       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 @@
+ 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 @@
+               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 @@
+       }
+       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; 
+@@ -596,6 +603,11 @@
+       might_sleep();
+       if (is_vm_hugetlb_page(vma)) {
++              static int x;
++              if (x < 10) {
++                      x++;
++                      dump_stack();
++              }
+               zap_hugepage_range(vma, address, size);
+               return;
+       }
+@@ -1398,6 +1410,7 @@
+       spin_unlock(&mm->page_table_lock);
+       if (vma->vm_file) {
++              WARN_ON(!atomic_read(&vma->vm_file->f_count));
+               mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
+               sequence = atomic_read(&mapping->truncate_count);
+       }
+@@ -1655,6 +1668,8 @@
+       len = (end+PAGE_SIZE-1)/PAGE_SIZE-addr/PAGE_SIZE;
+       ret = get_user_pages(current, current->mm, addr,
+                       len, write, 0, NULL, NULL);
++      if (ret < 0)
++              return ret;
+       return ret == len ? 0 : -1;
+ }
+Index: linux-2.6.0-test5/mm/mlock.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/mlock.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/mlock.c       2003-09-27 11:38:41.445227752 +0800
+@@ -13,21 +13,24 @@
+       unsigned long start, unsigned long end, unsigned int newflags)
+ {
+       struct mm_struct * mm = vma->vm_mm;
+-      int pages, error;
++      int pages;
++      int ret = 0;
+       if (newflags == vma->vm_flags)
+-              return 0;
++              goto out;
+       if (start != vma->vm_start) {
+-              error = split_vma(mm, vma, start, 1);
+-              if (error)
+-                      return -EAGAIN;
++              if (split_vma(mm, vma, start, 1)) {
++                      ret = -EAGAIN;
++                      goto out;
++              }
+       }
+       if (end != vma->vm_end) {
+-              error = split_vma(mm, vma, end, 0);
+-              if (error)
+-                      return -EAGAIN;
++              if (split_vma(mm, vma, end, 0)) {
++                      ret = -EAGAIN;
++                      goto out;
++              }
+       }
+       
+       spin_lock(&mm->page_table_lock);
+@@ -40,11 +43,12 @@
+       pages = (end - start) >> PAGE_SHIFT;
+       if (newflags & VM_LOCKED) {
+               pages = -pages;
+-              make_pages_present(start, end);
++              ret = make_pages_present(start, end);
+       }
+       vma->vm_mm->locked_vm -= pages;
+-      return 0;
++out:
++      return ret;
+ }
+ static int do_mlock(unsigned long start, size_t len, int on)
+Index: linux-2.6.0-test5/mm/page_alloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/page_alloc.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/page_alloc.c  2003-09-27 11:38:41.455226232 +0800
+@@ -50,7 +50,7 @@
+  * 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" };
+@@ -520,7 +520,8 @@
+  *
+  * Herein lies the mysterious "incremental min".  That's the
+  *
+- *    min += z->pages_low;
++ *    local_low = z->pages_low;
++ *    min += local_low;
+  *
+  * thing.  The intent here is to provide additional protection to low zones for
+  * allocation requests which _could_ use higher zones.  So a GFP_HIGHMEM
+@@ -538,10 +539,11 @@
+       unsigned long min;
+       struct zone **zones, *classzone;
+       struct page *page;
++      struct reclaim_state reclaim_state;
++      struct task_struct *p = current;
+       int i;
+       int cold;
+       int do_retry;
+-      struct reclaim_state reclaim_state;
+       might_sleep_if(wait);
+@@ -558,8 +560,17 @@
+       min = 1UL << order;
+       for (i = 0; zones[i] != NULL; i++) {
+               struct zone *z = zones[i];
++              unsigned long local_low;
++
++              /*
++               * This is the fabled 'incremental min'. We let real-time tasks
++               * dip their real-time paws a little deeper into reserves.
++               */
++              local_low = z->pages_low;
++              if (rt_task(p))
++                      local_low >>= 1;
++              min += local_low;
+-              min += z->pages_low;
+               if (z->free_pages >= min ||
+                               (!wait && z->free_pages >= z->pages_high)) {
+                       page = buffered_rmqueue(z, order, cold);
+@@ -582,6 +593,8 @@
+               local_min = z->pages_min;
+               if (gfp_mask & __GFP_HIGH)
+                       local_min >>= 2;
++              if (rt_task(p))
++                      local_min >>= 1;
+               min += local_min;
+               if (z->free_pages >= min ||
+                               (!wait && z->free_pages >= z->pages_high)) {
+@@ -595,7 +608,7 @@
+       /* here we're in the low on memory slow path */
+ rebalance:
+-      if ((current->flags & (PF_MEMALLOC | PF_MEMDIE)) && !in_interrupt()) {
++      if ((p->flags & (PF_MEMALLOC | PF_MEMDIE)) && !in_interrupt()) {
+               /* go through the zonelist yet again, ignoring mins */
+               for (i = 0; zones[i] != NULL; i++) {
+                       struct zone *z = zones[i];
+@@ -611,14 +624,14 @@
+       if (!wait)
+               goto nopage;
+-      current->flags |= PF_MEMALLOC;
++      p->flags |= PF_MEMALLOC;
+       reclaim_state.reclaimed_slab = 0;
+-      current->reclaim_state = &reclaim_state;
++      p->reclaim_state = &reclaim_state;
+       try_to_free_pages(classzone, gfp_mask, order);
+-      current->reclaim_state = NULL;
+-      current->flags &= ~PF_MEMALLOC;
++      p->reclaim_state = NULL;
++      p->flags &= ~PF_MEMALLOC;
+       /* go through the zonelist yet one more time */
+       min = 1UL << order;
+@@ -658,7 +671,7 @@
+       if (!(gfp_mask & __GFP_NOWARN)) {
+               printk("%s: page allocation failure."
+                       " order:%d, mode:0x%x\n",
+-                      current->comm, order, gfp_mask);
++                      p->comm, order, gfp_mask);
+       }
+       return NULL;
+ got_pg:
+Index: linux-2.6.0-test5/mm/page-writeback.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/page-writeback.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/page-writeback.c      2003-09-27 11:38:41.460225472 +0800
+@@ -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
+@@ -111,6 +112,7 @@
+       int unmapped_ratio;
+       long background;
+       long dirty;
++      struct task_struct *tsk;
+       get_page_state(ps);
+@@ -129,7 +131,8 @@
+       background = (background_ratio * total_pages) / 100;
+       dirty = (dirty_ratio * total_pages) / 100;
+-      if (current->flags & PF_LESS_THROTTLE) {
++      tsk = current;
++      if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) {
+               background += background / 4;
+               dirty += dirty / 4;
+       }
+@@ -144,7 +147,7 @@
+  * If we're over `background_thresh' then pdflush is woken to perform some
+  * writeout.
+  */
+-void balance_dirty_pages(struct address_space *mapping)
++static int balance_dirty_pages(struct address_space *mapping)
+ {
+       struct page_state ps;
+       long nr_reclaimable;
+@@ -161,6 +164,7 @@
+                       .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 +191,11 @@
+                       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 +203,8 @@
+       if (!writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
+               pdflush_operation(background_writeout, 0);
++
++      return 0;
+ }
+ /**
+@@ -210,7 +220,7 @@
+  * 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;
+@@ -219,13 +229,17 @@
+       if (dirty_exceeded)
+               ratelimit = 8;
++      /*
++       * Check the rate limiting. Also, we do not want to throttle real-time
++       * tasks in balance_dirty_pages(). Period.
++       */
+       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 +574,152 @@
+       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, 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, OSYNC_METADATA);
++      }
++do_wait:
++      if (ret >= 0)
++              ret = wait_on_page_range(mapping, pos, count);
++      return ret;
++}
+Index: linux-2.6.0-test5/mm/pdflush.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/pdflush.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/pdflush.c     2003-09-27 11:38:41.462225168 +0800
+@@ -84,6 +84,8 @@
+       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 @@
+               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 @@
+ {
+       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 @@
+       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))
+Index: linux-2.6.0-test5/mm/shmem.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/shmem.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/shmem.c       2003-09-27 11:38:41.474223344 +0800
+@@ -984,7 +984,22 @@
+                               page_cache_release(page);
+                               return err;
+                       }
++              } else if (nonblock) {
++                      /*
++                       * If a nonlinear mapping then store the file page
++                       * offset in the pte.
++                       */
++                      unsigned long pgidx;
++                      pgidx = (addr - vma->vm_start) >> PAGE_SHIFT;
++                      pgidx += vma->vm_pgoff;
++                      pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
++                      if (pgoff != pgidx) {
++                              err = install_file_pte(mm, vma, addr, pgoff, prot);
++                              if (err)
++                                      return err;
++                      }
+               }
++
+               len -= PAGE_SIZE;
+               addr += PAGE_SIZE;
+               pgoff++;
+Index: linux-2.6.0-test5/mm/slab.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/slab.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/slab.c        2003-09-27 11:38:41.495220152 +0800
+@@ -153,8 +153,9 @@
+  * is less than 512 (PAGE_SIZE<<3), but greater than 256.
+  */
+-#define BUFCTL_END 0xffffFFFF
+-#define       SLAB_LIMIT 0xffffFFFE
++#define BUFCTL_END    0xffffFFFF
++#define BUFCTL_FREE   0xffffFFFE
++#define       SLAB_LIMIT      0xffffFFFD
+ typedef unsigned int kmem_bufctl_t;
+ /* Max number of objs-per-slab for caches which use off-slab slabs.
+@@ -249,7 +250,7 @@
+       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 */
+@@ -293,6 +294,10 @@
+       atomic_t                freehit;
+       atomic_t                freemiss;
+ #endif
++#if DEBUG
++      int                     dbghead;
++      int                     reallen;
++#endif
+ };
+ #define CFLGS_OFF_SLAB                (0x80000000UL)
+@@ -356,32 +361,68 @@
+ #define POISON_AFTER  0x6b    /* for use-after-free poisoning */
+ #define       POISON_END      0xa5    /* end-byte of poisoning */
++/* memory layout of objects:
++ * 0          : objp
++ * 0 .. cachep->dbghead - BYTES_PER_WORD - 1: padding. This ensures that
++ *            the end of an object is aligned with the end of the real
++ *            allocation. Catches writes behind the end of the allocation.
++ * cachep->dbghead - BYTES_PER_WORD .. cachep->dbghead - 1:
++ *            redzone word.
++ * cachep->dbghead: The real object.
++ * cachep->objsize - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long]
++ * cachep->objsize - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long]
++ */
+ static inline int obj_dbghead(kmem_cache_t *cachep)
+ {
+-      if (cachep->flags & SLAB_RED_ZONE)
+-              return BYTES_PER_WORD;
+-      return 0;
++      return cachep->dbghead;
+ }
+-static inline int obj_dbglen(kmem_cache_t *cachep)
++static inline int obj_reallen(kmem_cache_t *cachep)
+ {
+-      int len = 0;
++      return cachep->reallen;
++}
+-      if (cachep->flags & SLAB_RED_ZONE) {
+-              len += 2*BYTES_PER_WORD;
+-      }
+-      if (cachep->flags & SLAB_STORE_USER) {
+-              len += BYTES_PER_WORD;
+-      }
+-      return len;
++static unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp)
++{
++      BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
++      return (unsigned long*) (objp+obj_dbghead(cachep)-BYTES_PER_WORD);
++}
++
++static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
++{
++      BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
++      if (cachep->flags & SLAB_STORE_USER)
++              return (unsigned long*) (objp+cachep->objsize-2*BYTES_PER_WORD);
++      return (unsigned long*) (objp+cachep->objsize-BYTES_PER_WORD);
++}
++
++static void **dbg_userword(kmem_cache_t *cachep, void *objp)
++{
++      BUG_ON(!(cachep->flags & SLAB_STORE_USER));
++      return (void**)(objp+cachep->objsize-BYTES_PER_WORD);
+ }
+ #else
+ static inline int obj_dbghead(kmem_cache_t *cachep)
+ {
+       return 0;
+ }
+-static inline int obj_dbglen(kmem_cache_t *cachep)
++static inline int obj_reallen(kmem_cache_t *cachep)
++{
++      return cachep->objsize;
++}
++static inline unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp)
++{
++      BUG();
++      return 0;
++}
++static inline unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
+ {
++      BUG();
++      return 0;
++}
++static inline void **dbg_userword(kmem_cache_t *cachep, void *objp)
++{
++      BUG();
+       return 0;
+ }
+ #endif
+@@ -804,7 +845,7 @@
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+ static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr, unsigned long caller)
+ {
+-      int size = cachep->objsize-obj_dbglen(cachep);
++      int size = obj_reallen(cachep);
+       addr = (unsigned long *)&((char*)addr)[obj_dbghead(cachep)];
+@@ -836,7 +877,7 @@
+ static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val)
+ {
+-      int size = cachep->objsize-obj_dbglen(cachep);
++      int size = obj_reallen(cachep);
+       addr = &((char*)addr)[obj_dbghead(cachep)];
+       memset(addr, val, size);
+@@ -858,47 +899,42 @@
+       return NULL;
+ }
+-static void check_poison_obj(kmem_cache_t *cachep, void *addr)
++static void check_poison_obj(kmem_cache_t *cachep, void *objp)
+ {
+       void *end;
+-      int size = cachep->objsize-obj_dbglen(cachep);
++      void *realobj;
++      int size = obj_reallen(cachep);
+-      addr = &((char*)addr)[obj_dbghead(cachep)];
++      realobj = objp+obj_dbghead(cachep);
+-      end = scan_poisoned_obj(addr, size);
++      end = scan_poisoned_obj(realobj, size);
+       if (end) {
+               int s;
+               printk(KERN_ERR "Slab corruption: start=%p, expend=%p, "
+-                              "problemat=%p\n", addr, addr+size-1, end);
++                              "problemat=%p\n", realobj, realobj+size-1, end);
+               if (cachep->flags & SLAB_STORE_USER) {
+-                      void *pc;
+-
+-                      if (cachep->flags & SLAB_RED_ZONE)
+-                              pc = *(void**)(addr+size+BYTES_PER_WORD);
+-                      else
+-                              pc = *(void**)(addr+size);
+-                      printk(KERN_ERR "Last user: [<%p>]", pc);
+-                      print_symbol("(%s)", (unsigned long)pc);
++                      printk(KERN_ERR "Last user: [<%p>]", *dbg_userword(cachep, objp));
++                      print_symbol("(%s)", (unsigned long)*dbg_userword(cachep, objp));
+                       printk("\n");
+               }
+               printk(KERN_ERR "Data: ");
+               for (s = 0; s < size; s++) {
+-                      if (((char*)addr)[s] == POISON_BEFORE)
++                      if (((char*)realobj)[s] == POISON_BEFORE)
+                               printk(".");
+-                      else if (((char*)addr)[s] == POISON_AFTER)
++                      else if (((char*)realobj)[s] == POISON_AFTER)
+                               printk("*");
+                       else
+-                              printk("%02X ", ((unsigned char*)addr)[s]);
++                              printk("%02X ", ((unsigned char*)realobj)[s]);
+               }
+               printk("\n");
+               printk(KERN_ERR "Next: ");
+               for (; s < size + 32; s++) {
+-                      if (((char*)addr)[s] == POISON_BEFORE)
++                      if (((char*)realobj)[s] == POISON_BEFORE)
+                               printk(".");
+-                      else if (((char*)addr)[s] == POISON_AFTER)
++                      else if (((char*)realobj)[s] == POISON_AFTER)
+                               printk("*");
+                       else
+-                              printk("%02X ", ((unsigned char*)addr)[s]);
++                              printk("%02X ", ((unsigned char*)realobj)[s]);
+               }
+               printk("\n");
+               slab_error(cachep, "object was modified after freeing");
+@@ -916,7 +952,6 @@
+       int i;
+       for (i = 0; i < cachep->num; i++) {
+               void *objp = slabp->s_mem + cachep->objsize * i;
+-              int objlen = cachep->objsize;
+               if (cachep->flags & SLAB_POISON) {
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+@@ -928,21 +963,16 @@
+                       check_poison_obj(cachep, objp);
+ #endif
+               }
+-              if (cachep->flags & SLAB_STORE_USER)
+-                      objlen -= BYTES_PER_WORD;
+-
+               if (cachep->flags & SLAB_RED_ZONE) {
+-                      if (*((unsigned long*)(objp)) != RED_INACTIVE)
++                      if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
+                               slab_error(cachep, "start of a freed object "
+                                                       "was overwritten");
+-                      if (*((unsigned long*)(objp + objlen - BYTES_PER_WORD))
+-                                      != RED_INACTIVE)
++                      if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
+                               slab_error(cachep, "end of a freed object "
+                                                       "was overwritten");
+-                      objp += BYTES_PER_WORD;
+               }
+               if (cachep->dtor && !(cachep->flags & SLAB_POISON))
+-                      (cachep->dtor)(objp, cachep, 0);
++                      (cachep->dtor)(objp+obj_dbghead(cachep), cachep, 0);
+       }
+ #else
+       if (cachep->dtor) {
+@@ -1013,6 +1043,7 @@
+                       BUG();
+ #if DEBUG
++      BUG_ON(strchr(name, ' '));      /* It confuses parsers */
+       if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
+               /* No constructor, but inital state check requested */
+               printk("%sNo con, but init state check requested - %s\n", func_nm, name);
+@@ -1020,10 +1051,6 @@
+       }
+ #if FORCED_DEBUG
+-#ifdef CONFIG_DEBUG_PAGEALLOC
+-      if (size < PAGE_SIZE-3*BYTES_PER_WORD && size > 128)
+-              size = PAGE_SIZE-3*BYTES_PER_WORD;
+-#endif
+       /*
+        * Enable redzoning and last user accounting, except
+        * - for caches with forced alignment: redzoning would violate the
+@@ -1054,6 +1081,9 @@
+               goto opps;
+       memset(cachep, 0, sizeof(kmem_cache_t));
++#if DEBUG
++      cachep->reallen = size;
++#endif
+       /* Check that size is in terms of words.  This is needed to avoid
+        * unaligned accesses for some archs when redzoning is used, and makes
+        * sure any on-slab bufctl's are also correctly aligned.
+@@ -1071,13 +1101,21 @@
+                * when redzoning.
+                */
+               flags &= ~SLAB_HWCACHE_ALIGN;
+-              size += 2*BYTES_PER_WORD;       /* words for redzone */
++              /* add space for red zone words */
++              cachep->dbghead += BYTES_PER_WORD;
++              size += 2*BYTES_PER_WORD;
+       }
+       if (flags & SLAB_STORE_USER) {
+               flags &= ~SLAB_HWCACHE_ALIGN;
+-              size += BYTES_PER_WORD;         /* word for kfree caller address */
++              size += BYTES_PER_WORD; /* add space */
++      }
++#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
++      if (size > 128 && cachep->reallen > L1_CACHE_BYTES && size < PAGE_SIZE) {
++              cachep->dbghead += PAGE_SIZE - size;
++              size = PAGE_SIZE;
+       }
+ #endif
++#endif
+       align = BYTES_PER_WORD;
+       if (flags & SLAB_HWCACHE_ALIGN)
+               align = L1_CACHE_BYTES;
+@@ -1140,7 +1178,8 @@
+               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
+@@ -1184,10 +1223,13 @@
+                        * 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;
+@@ -1201,7 +1243,7 @@
+       } 
+       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);
+@@ -1214,16 +1256,24 @@
+               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(); 
+                       }       
+@@ -1444,20 +1494,15 @@
+       for (i = 0; i < cachep->num; i++) {
+               void* objp = slabp->s_mem+cachep->objsize*i;
+ #if DEBUG
+-              int objlen = cachep->objsize;
+               /* need to poison the objs? */
+               if (cachep->flags & SLAB_POISON)
+                       poison_obj(cachep, objp, POISON_BEFORE);
+-              if (cachep->flags & SLAB_STORE_USER) {
+-                      objlen -= BYTES_PER_WORD;
+-                      ((unsigned long*)(objp+objlen))[0] = 0;
+-              }
++              if (cachep->flags & SLAB_STORE_USER)
++                      *dbg_userword(cachep, objp) = NULL;
+               if (cachep->flags & SLAB_RED_ZONE) {
+-                      *((unsigned long*)(objp)) = RED_INACTIVE;
+-                      objp += BYTES_PER_WORD;
+-                      objlen -= 2* BYTES_PER_WORD;
+-                      *((unsigned long*)(objp + objlen)) = RED_INACTIVE;
++                      *dbg_redzone1(cachep, objp) = RED_INACTIVE;
++                      *dbg_redzone2(cachep, objp) = RED_INACTIVE;
+               }
+               /*
+                * Constructors are not allowed to allocate memory from
+@@ -1465,14 +1510,13 @@
+                * Otherwise, deadlock. They must also be threaded.
+                */
+               if (cachep->ctor && !(cachep->flags & SLAB_POISON))
+-                      cachep->ctor(objp, cachep, ctor_flags);
++                      cachep->ctor(objp+obj_dbghead(cachep), cachep, ctor_flags);
+               if (cachep->flags & SLAB_RED_ZONE) {
+-                      if (*((unsigned long*)(objp + objlen)) != RED_INACTIVE)
++                      if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
+                               slab_error(cachep, "constructor overwrote the"
+                                                       " end of an object");
+-                      objp -= BYTES_PER_WORD;
+-                      if (*((unsigned long*)(objp)) != RED_INACTIVE)
++                      if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
+                               slab_error(cachep, "constructor overwrote the"
+                                                       " start of an object");
+               }
+@@ -1623,9 +1667,9 @@
+ #if DEBUG
+       struct page *page;
+       unsigned int objnr;
+-      int objlen = cachep->objsize;
+       struct slab *slabp;
++      objp -= obj_dbghead(cachep);
+       kfree_debugcheck(objp);
+       page = virt_to_page(objp);
+@@ -1638,21 +1682,18 @@
+       }
+       slabp = GET_PAGE_SLAB(page);
+-      if (cachep->flags & SLAB_STORE_USER) {
+-              objlen -= BYTES_PER_WORD;
+-      }
+       if (cachep->flags & SLAB_RED_ZONE) {
+-              objp -= BYTES_PER_WORD;
+-              if (xchg((unsigned long *)objp, RED_INACTIVE) != RED_ACTIVE)
+-                      slab_error(cachep, "double free, or memory before"
++              if (*dbg_redzone1(cachep, objp) != RED_ACTIVE || *dbg_redzone2(cachep, objp) != RED_ACTIVE) {
++                      slab_error(cachep, "double free, or memory outside"
+                                               " object was overwritten");
+-              if (xchg((unsigned long *)(objp+objlen-BYTES_PER_WORD), RED_INACTIVE) != RED_ACTIVE)
+-                      slab_error(cachep, "double free, or memory after "
+-                                              " object was overwritten");
+-      }
+-      if (cachep->flags & SLAB_STORE_USER) {
+-              *((void**)(objp+objlen)) = caller;
++                      printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
++                                      objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp));
++              }
++              *dbg_redzone1(cachep, objp) = RED_INACTIVE;
++              *dbg_redzone2(cachep, objp) = RED_INACTIVE;
+       }
++      if (cachep->flags & SLAB_STORE_USER)
++              *dbg_userword(cachep, objp) = caller;
+       objnr = (objp-slabp->s_mem)/cachep->objsize;
+@@ -1699,40 +1740,23 @@
+       /* Check slab's freelist to see if this obj is there. */
+       for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
+               entries++;
+-              BUG_ON(entries > cachep->num);
+-              BUG_ON(i < 0 || i >= cachep->num);
++              if (entries > cachep->num || i < 0 || i >= cachep->num)
++                      goto bad;
+       }
+-      BUG_ON(entries != cachep->num - slabp->inuse);
+-#endif
+-}
+-
+-static inline void * cache_alloc_one_tail (kmem_cache_t *cachep,
+-                                              struct slab *slabp)
+-{
+-      void *objp;
+-
+-      check_spinlock_acquired(cachep);
+-
+-      STATS_INC_ALLOCED(cachep);
+-      STATS_INC_ACTIVE(cachep);
+-      STATS_SET_HIGH(cachep);
+-
+-      /* get obj pointer */
+-      slabp->inuse++;
+-      objp = slabp->s_mem + slabp->free*cachep->objsize;
+-      slabp->free=slab_bufctl(slabp)[slabp->free];
+-
+-      return objp;
+-}
+-
+-static inline void cache_alloc_listfixup(struct kmem_list3 *l3, struct slab *slabp)
+-{
+-      list_del(&slabp->list);
+-      if (slabp->free == BUFCTL_END) {
+-              list_add(&slabp->list, &l3->slabs_full);
+-      } else {
+-              list_add(&slabp->list, &l3->slabs_partial);
++      if (entries != cachep->num - slabp->inuse) {
++              int i;
++bad:
++              printk(KERN_ERR "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n",
++                              cachep->name, cachep->num, slabp, slabp->inuse);
++              for (i=0;i<sizeof(slabp)+cachep->num*sizeof(kmem_bufctl_t);i++) {
++                      if ((i%16)==0)
++                              printk("\n%03x:", i);
++                      printk(" %02x", ((unsigned char*)slabp)[i]);
++              }
++              printk("\n");
++              BUG();
+       }
++#endif
+ }
+ static void* cache_alloc_refill(kmem_cache_t* cachep, int flags)
+@@ -1783,11 +1807,31 @@
+               slabp = list_entry(entry, struct slab, list);
+               check_slabp(cachep, slabp);
+-              while (slabp->inuse < cachep->num && batchcount--)
+-                      ac_entry(ac)[ac->avail++] =
+-                              cache_alloc_one_tail(cachep, slabp);
++              check_spinlock_acquired(cachep);
++              while (slabp->inuse < cachep->num && batchcount--) {
++                      kmem_bufctl_t next;
++                      STATS_INC_ALLOCED(cachep);
++                      STATS_INC_ACTIVE(cachep);
++                      STATS_SET_HIGH(cachep);
++
++                      /* get obj pointer */
++                      ac_entry(ac)[ac->avail++] = slabp->s_mem + slabp->free*cachep->objsize;
++
++                      slabp->inuse++;
++                      next = slab_bufctl(slabp)[slabp->free];
++#if DEBUG
++                      slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
++#endif
++                      slabp->free = next;
++              }
+               check_slabp(cachep, slabp);
+-              cache_alloc_listfixup(l3, slabp);
++
++              /* move slabp to correct slabp list: */
++              list_del(&slabp->list);
++              if (slabp->free == BUFCTL_END)
++                      list_add(&slabp->list, &l3->slabs_full);
++              else
++                      list_add(&slabp->list, &l3->slabs_partial);
+       }
+ must_grow:
+@@ -1825,8 +1869,6 @@
+                       unsigned long flags, void *objp, void *caller)
+ {
+ #if DEBUG
+-      int objlen = cachep->objsize;
+-
+       if (!objp)      
+               return objp;
+       if (cachep->flags & SLAB_POISON) {
+@@ -1840,24 +1882,20 @@
+ #endif
+               poison_obj(cachep, objp, POISON_BEFORE);
+       }
+-      if (cachep->flags & SLAB_STORE_USER) {
+-              objlen -= BYTES_PER_WORD;
+-              *((void **)(objp+objlen)) = caller;
+-      }
++      if (cachep->flags & SLAB_STORE_USER)
++              *dbg_userword(cachep, objp) = caller;
+       if (cachep->flags & SLAB_RED_ZONE) {
+-              /* Set alloc red-zone, and check old one. */
+-              if (xchg((unsigned long *)objp, RED_ACTIVE) != RED_INACTIVE) {
+-                      slab_error(cachep, "memory before object was "
+-                                              "overwritten");
+-              }
+-              if (xchg((unsigned long *)(objp+objlen - BYTES_PER_WORD),
+-                                      RED_ACTIVE) != RED_INACTIVE) {
+-                      slab_error(cachep, "memory after object was "
+-                                              "overwritten");
++              if (*dbg_redzone1(cachep, objp) != RED_INACTIVE || *dbg_redzone2(cachep, objp) != RED_INACTIVE) {
++                      slab_error(cachep, "double free, or memory outside"
++                                              " object was overwritten");
++                      printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
++                                      objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp));
+               }
+-              objp += BYTES_PER_WORD;
++              *dbg_redzone1(cachep, objp) = RED_ACTIVE;
++              *dbg_redzone2(cachep, objp) = RED_ACTIVE;
+       }
++      objp += obj_dbghead(cachep);
+       if (cachep->ctor && cachep->flags & SLAB_POISON) {
+               unsigned long   ctor_flags = SLAB_CTOR_CONSTRUCTOR;
+@@ -1917,6 +1955,13 @@
+               list_del(&slabp->list);
+               objnr = (objp - slabp->s_mem) / cachep->objsize;
+               check_slabp(cachep, slabp);
++#if DEBUG
++              if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
++                      printk(KERN_ERR "slab: double free detected in cache '%s', objp %p.\n",
++                                              cachep->name, objp);
++                      BUG();
++              }
++#endif
+               slab_bufctl(slabp)[objnr] = slabp->free;
+               slabp->free = objnr;
+               STATS_DEC_ACTIVE(cachep);
+@@ -2175,7 +2220,7 @@
+ unsigned int kmem_cache_size(kmem_cache_t *cachep)
+ {
+-      return cachep->objsize-obj_dbglen(cachep);
++      return obj_reallen(cachep);
+ }
+ kmem_cache_t * kmem_find_general_cachep (size_t size, int gfpflags)
+@@ -2763,12 +2808,17 @@
+               if (objnr >= c->num) {
+                       printk("Bad obj number.\n");
+               } else {
+-                      kernel_map_pages(virt_to_page(objp), c->objsize/PAGE_SIZE, 1);
++                      kernel_map_pages(virt_to_page(objp),
++                                      c->objsize/PAGE_SIZE, 1);
+-                      printk("redzone: %lxh/%lxh/%lxh.\n",
+-                              ((unsigned long*)objp)[0],
+-                              ((unsigned long*)(objp+c->objsize))[-2],
+-                              ((unsigned long*)(objp+c->objsize))[-1]);
++                      if (c->flags & SLAB_RED_ZONE)
++                              printk("redzone: 0x%lx/0x%lx.\n",
++                                      *dbg_redzone1(c, objp),
++                                      *dbg_redzone2(c, objp));
++
++                      if (c->flags & SLAB_STORE_USER)
++                              printk("Last user: %p.\n",
++                                      *dbg_userword(c, objp));
+               }
+               spin_unlock_irqrestore(&c->spinlock, flags);
+Index: linux-2.6.0-test5/mm/swap.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/swap.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/swap.c        2003-09-27 11:38:41.499219544 +0800
+@@ -339,12 +339,15 @@
+  * 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);
+ }
+Index: linux-2.6.0-test5/mm/truncate.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/truncate.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/truncate.c    2003-09-27 11:38:41.501219240 +0800
+@@ -121,14 +121,10 @@
+       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 @@
+       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 @@
+                       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 @@
+       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 @@
+       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
+Index: linux-2.6.0-test5/mm/usercopy.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/usercopy.c       2003-09-27 11:38:18.490717368 +0800
++++ linux-2.6.0-test5/mm/usercopy.c    2003-09-27 11:38:41.502219088 +0800
+@@ -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);
++
+Index: linux-2.6.0-test5/mm/vmalloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/vmalloc.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/mm/vmalloc.c     2003-09-27 11:38:41.506218480 +0800
+@@ -135,23 +135,23 @@
+ 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 @@
+       } while (address && (address < end));
+       spin_unlock(&init_mm.page_table_lock);
+-      flush_cache_all();
++      flush_cache_vmap((unsigned long) area->addr, end);
+       return err;
+ }
+Index: linux-2.6.0-test5/net/8021q/vlanproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/8021q/vlanproc.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/8021q/vlanproc.c     2003-09-27 11:38:41.509218024 +0800
+@@ -46,10 +46,6 @@
+ static void vlan_seq_stop(struct seq_file *seq, void *);
+ static int vlandev_seq_show(struct seq_file *seq, void *v);
+-/* Miscellaneous */
+-#define SEQ_START_TOKEN               ((void *) 1)
+-
+-
+ /*
+  *    Global Data
+  */
+Index: linux-2.6.0-test5/net/802/p8022.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/802/p8022.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/802/p8022.c  2003-09-27 11:38:41.511217720 +0800
+@@ -22,8 +22,8 @@
+ #include <linux/mm.h>
+ #include <linux/in.h>
+ #include <linux/init.h>
++#include <net/llc.h>
+ #include <net/p8022.h>
+-#include <net/llc_sap.h>
+ static int p8022_request(struct datalink_proto *dl, struct sk_buff *skb,
+                        unsigned char *dest)
+Index: linux-2.6.0-test5/net/802/psnap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/802/psnap.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/802/psnap.c  2003-09-27 11:38:41.512217568 +0800
+@@ -15,9 +15,8 @@
+ #include <linux/netdevice.h>
+ #include <linux/skbuff.h>
+ #include <net/datalink.h>
++#include <net/llc.h>
+ #include <net/psnap.h>
+-#include <net/llc_if.h>
+-#include <net/llc_sap.h>
+ #include <linux/mm.h>
+ #include <linux/in.h>
+ #include <linux/init.h>
+Index: linux-2.6.0-test5/net/802/tr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/802/tr.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/802/tr.c     2003-09-27 11:38:41.516216960 +0800
+@@ -464,8 +464,6 @@
+  */
+  
+ #ifdef CONFIG_PROC_FS
+-/* Magic token to indicate first entry (header line) */
+-#define RIF_PROC_START        ((void *)1)
+ static struct rif_cache_s *rif_get_idx(loff_t pos)
+ {
+@@ -487,7 +485,7 @@
+ {
+       spin_lock_bh(&rif_lock);
+-      return *pos ? rif_get_idx(*pos - 1) : RIF_PROC_START;
++      return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -497,7 +495,7 @@
+       ++*pos;
+-      if (v == RIF_PROC_START) {
++      if (v == SEQ_START_TOKEN) {
+               i = -1;
+               goto scan;
+       }
+@@ -524,7 +522,7 @@
+       int j, rcf_len, segment, brdgnmb;
+       struct rif_cache_s *entry = v;
+-      if (v == RIF_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq,
+                    "if     TR address       TTL   rcf   routing segments\n");
+       else {
+Index: linux-2.6.0-test5/net/appletalk/aarp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/appletalk/aarp.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/appletalk/aarp.c     2003-09-27 11:38:41.524215744 +0800
+@@ -941,7 +941,7 @@
+       iter->table     = resolved;
+       iter->bucket    = 0;
+-      return *pos ? iter_next(iter, pos) : ((void *)1);
++      return *pos ? iter_next(iter, pos) : SEQ_START_TOKEN;
+ }
+ static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -952,7 +952,7 @@
+       ++*pos;
+       /* first line after header */
+-      if (v == ((void *)1)) 
++      if (v == SEQ_START_TOKEN) 
+               entry = iter_next(iter, NULL);
+               
+       /* next entry in current bucket */
+@@ -987,7 +987,7 @@
+       struct aarp_entry *entry = v;
+       unsigned long now = jiffies;
+-      if (v == ((void *)1))
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, 
+                        "Address  Interface   Hardware Address"
+                        "   Expires LastSend  Retry Status\n");
+Index: linux-2.6.0-test5/net/appletalk/atalk_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/appletalk/atalk_proc.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/appletalk/atalk_proc.c       2003-09-27 11:38:41.526215440 +0800
+@@ -33,7 +33,7 @@
+       loff_t l = *pos;
+       read_lock_bh(&atalk_interfaces_lock);
+-      return l ? atalk_get_interface_idx(--l) : (void *)1;
++      return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -41,7 +41,7 @@
+       struct atalk_iface *i;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               i = NULL;
+               if (atalk_interfaces)
+                       i = atalk_interfaces;
+@@ -62,7 +62,7 @@
+ {
+       struct atalk_iface *iface;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Interface        Address   Networks  "
+                             "Status\n");
+               goto out;
+@@ -92,7 +92,7 @@
+       loff_t l = *pos;
+       read_lock_bh(&atalk_routes_lock);
+-      return l ? atalk_get_route_idx(--l) : (void *)1;
++      return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -100,7 +100,7 @@
+       struct atalk_route *r;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               r = NULL;
+               if (atalk_routes)
+                       r = atalk_routes;
+@@ -121,7 +121,7 @@
+ {
+       struct atalk_route *rt;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Target        Router  Flags Dev\n");
+               goto out;
+       }
+@@ -160,7 +160,7 @@
+       loff_t l = *pos;
+       read_lock_bh(&atalk_sockets_lock);
+-      return l ? atalk_get_socket_idx(--l) : (void *)1;
++      return l ? atalk_get_socket_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -168,7 +168,7 @@
+       struct sock *i;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               i = sk_head(&atalk_sockets);
+               goto out;
+       }
+@@ -187,7 +187,7 @@
+       struct sock *s;
+       struct atalk_sock *at;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, "Type Local_addr  Remote_addr Tx_queue "
+                               "Rx_queue St UID\n");
+               goto out;
+Index: linux-2.6.0-test5/net/atm/br2684.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/br2684.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/br2684.c 2003-09-27 11:38:41.532214528 +0800
+@@ -732,9 +732,10 @@
+ #ifdef CONFIG_ATM_BR2684_IPFILTER
+ #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte]
+ #define bs(var)               b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3)
+-                      if (brvcc->filter.netmask != 0 && pos-- == 0)
+-                              return sprintf(buf, "    filter=%d.%d.%d.%d/"
+-                                  "%d.%d.%d.%d\n", bs(prefix), bs(netmask));
++                      if (brvcc->filter.netmask != 0)
++                              seq_printf(seq, "    filter=%d.%d.%d.%d/"
++                                              "%d.%d.%d.%d\n",
++                                              bs(prefix), bs(netmask));
+ #undef bs
+ #undef b1
+ #endif /* CONFIG_ATM_BR2684_IPFILTER */
+Index: linux-2.6.0-test5/net/atm/clip.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/clip.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/clip.c   2003-09-27 11:38:41.539213464 +0800
+@@ -93,6 +93,7 @@
+               printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
+               return;
+       }
++      spin_lock_bh(&entry->neigh->dev->xmit_lock);    /* block clip_start_xmit() */
+       entry->neigh->used = jiffies;
+       for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
+               if (*walk == clip_vcc) {
+@@ -102,17 +103,20 @@
+                       clip_vcc->entry = NULL;
+                       if (clip_vcc->xoff)
+                               netif_wake_queue(entry->neigh->dev);
+-                      if (entry->vccs) return;
++                      if (entry->vccs)
++                              goto out;
+                       entry->expires = jiffies-1;
+                               /* force resolution or expiration */
+                       error = neigh_update(entry->neigh,NULL,NUD_NONE,0,0);
+                       if (error)
+                               printk(KERN_CRIT "unlink_clip_vcc: "
+                                   "neigh_update failed with %d\n",error);
+-                      return;
++                      goto out;
+               }
+       printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
+         "0x%p)\n",entry,clip_vcc);
++out:
++      spin_unlock_bh(&entry->neigh->dev->xmit_lock);
+ }
+@@ -189,6 +193,13 @@
+       return 0;
+ }
++static const unsigned char llc_oui[] = {
++      0xaa,   /* DSAP: non-ISO */
++      0xaa,   /* SSAP: non-ISO */
++      0x03,   /* Ctrl: Unnumbered Information Command PDU */
++      0x00,   /* OUI: EtherType */
++      0x00,
++      0x00 };
+ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+Index: linux-2.6.0-test5/net/atm/ipcommon.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/ipcommon.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/ipcommon.c       2003-09-27 11:38:41.540213312 +0800
+@@ -22,15 +22,6 @@
+ #endif
+-const unsigned char llc_oui[] = {
+-      0xaa,   /* DSAP: non-ISO */
+-      0xaa,   /* SSAP: non-ISO */
+-      0x03,   /* Ctrl: Unnumbered Information Command PDU */
+-      0x00,   /* OUI: EtherType */
+-      0x00,
+-      0x00 };
+-
+-
+ /*
+  * skb_migrate appends the list at "from" to "to", emptying "from" in the
+  * process. skb_migrate is atomic with respect to all other skb operations on
+@@ -67,5 +58,4 @@
+ }
+-EXPORT_SYMBOL(llc_oui);
+ EXPORT_SYMBOL(skb_migrate);
+Index: linux-2.6.0-test5/net/atm/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/proc.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/proc.c   2003-09-27 11:38:41.548212096 +0800
+@@ -1,21 +1,13 @@
+-/* net/atm/proc.c - ATM /proc interface */
+-
+-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
+-
+-/*
+- * The mechanism used here isn't designed for speed but rather for convenience
+- * of implementation. We only return one entry per read system call, so we can
+- * be reasonably sure not to overrun the page and race conditions may lead to
+- * the addition or omission of some lines but never to any corruption of a
+- * line's internal structure.
++/* net/atm/proc.c - ATM /proc interface
++ *
++ * Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA
+  *
+- * Making the whole thing slightly more efficient is left as an exercise to the
+- * reader. (Suggestions: wrapper which loops to get several entries per system
+- * call; or make --left slightly more clever to avoid O(n^2) characteristics.)
+- * I find it fast enough on my unloaded 266 MHz Pentium 2 :-)
++ * seq_file api usage by romieu@fr.zoreil.com
++ *
++ * Evaluating the efficiency of the whole thing if left as an exercise to
++ * the reader.
+  */
+-
+ #include <linux/config.h>
+ #include <linux/module.h> /* for EXPORT_SYMBOL */
+ #include <linux/string.h>
+@@ -24,6 +16,7 @@
+ #include <linux/fs.h>
+ #include <linux/stat.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/errno.h>
+ #include <linux/atm.h>
+ #include <linux/atmdev.h>
+@@ -51,119 +44,202 @@
+ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
+     loff_t *pos);
+-static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count,
+-    loff_t *pos);
+-static struct file_operations proc_dev_atm_operations = {
++static struct file_operations proc_atm_dev_ops = {
+       .owner =        THIS_MODULE,
+       .read =         proc_dev_atm_read,
+ };
+-static struct file_operations proc_spec_atm_operations = {
+-      .owner =        THIS_MODULE,
+-      .read =         proc_spec_atm_read,
+-};
+-
+-static void add_stats(char *buf,const char *aal,
++static void add_stats(struct seq_file *seq, const char *aal,
+   const struct k_atm_aal_stats *stats)
+ {
+-      sprintf(strchr(buf,0),"%s ( %d %d %d %d %d )",aal,
++      seq_printf(seq, "%s ( %d %d %d %d %d )", aal,
+           atomic_read(&stats->tx),atomic_read(&stats->tx_err),
+           atomic_read(&stats->rx),atomic_read(&stats->rx_err),
+           atomic_read(&stats->rx_drop));
+ }
+-
+-static void atm_dev_info(const struct atm_dev *dev,char *buf)
++static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev)
+ {
+-      int off,i;
++      int i;
+-      off = sprintf(buf,"%3d %-8s",dev->number,dev->type);
++      seq_printf(seq, "%3d %-8s", dev->number, dev->type);
+       for (i = 0; i < ESI_LEN; i++)
+-              off += sprintf(buf+off,"%02x",dev->esi[i]);
+-      strcat(buf,"  ");
+-      add_stats(buf,"0",&dev->stats.aal0);
+-      strcat(buf,"  ");
+-      add_stats(buf,"5",&dev->stats.aal5);
+-      sprintf(strchr(buf,0), "\t[%d]", atomic_read(&dev->refcnt));
+-      strcat(buf,"\n");
++              seq_printf(seq, "%02x", dev->esi[i]);
++      seq_puts(seq, "  ");
++      add_stats(seq, "0", &dev->stats.aal0);
++      seq_puts(seq, "  ");
++      add_stats(seq, "5", &dev->stats.aal5);
++      seq_printf(seq, "\t[%d]", atomic_read(&dev->refcnt));
++      seq_putc(seq, '\n');
+ }
+-
+ #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-
+-static int svc_addr(char *buf,struct sockaddr_atmsvc *addr)
++static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
+ {
+       static int code[] = { 1,2,10,6,1,0 };
+       static int e164[] = { 1,8,4,6,1,0 };
+-      int *fields;
+-      int len,i,j,pos;
+-      len = 0;
+       if (*addr->sas_addr.pub) {
+-              strcpy(buf,addr->sas_addr.pub);
+-              len = strlen(addr->sas_addr.pub);
+-              buf += len;
+-              if (*addr->sas_addr.prv) {
+-                      *buf++ = '+';
+-                      len++;
+-              }
++              seq_printf(seq, "%s", addr->sas_addr.pub);
++              if (*addr->sas_addr.prv)
++                      seq_putc(seq, '+');
++      } else if (!*addr->sas_addr.prv) {
++              seq_printf(seq, "%s", "(none)");
++              return;
+       }
+-      else if (!*addr->sas_addr.prv) {
+-                      strcpy(buf,"(none)");
+-                      return strlen(buf);
+-              }
+       if (*addr->sas_addr.prv) {
+-              len += 44;
+-              pos = 0;
+-              fields = *addr->sas_addr.prv == ATM_AFI_E164 ? e164 : code;
++              unsigned char *prv = addr->sas_addr.prv;
++              int *fields;
++              int i, j;
++
++              fields = *prv == ATM_AFI_E164 ? e164 : code;
+               for (i = 0; fields[i]; i++) {
+-                      for (j = fields[i]; j; j--) {
+-                              sprintf(buf,"%02X",addr->sas_addr.prv[pos++]);
+-                              buf += 2;
+-                      }
+-                      if (fields[i+1]) *buf++ = '.';
++                      for (j = fields[i]; j; j--)
++                              seq_printf(seq, "%02X", *prv++);
++                      if (fields[i+1])
++                              seq_putc(seq, '.');
+               }
+       }
+-      return len;
+ }
+-
+-static void atmarp_info(struct net_device *dev,struct atmarp_entry *entry,
+-    struct clip_vcc *clip_vcc,char *buf)
++static void atmarp_info(struct seq_file *seq, struct net_device *dev,
++                      struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
+ {
+-      unsigned char *ip;
+-      int svc,off,ip_len;
++      char buf[17];
++      int svc, off;
+       svc = !clip_vcc || clip_vcc->vcc->sk->sk_family == AF_ATMSVC;
+-      off = sprintf(buf,"%-6s%-4s%-4s%5ld ",dev->name,svc ? "SVC" : "PVC",
++      seq_printf(seq, "%-6s%-4s%-4s%5ld ", dev->name, svc ? "SVC" : "PVC",
+           !clip_vcc || clip_vcc->encap ? "LLC" : "NULL",
+-          (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/
+-          HZ);
+-      ip = (unsigned char *) &entry->ip;
+-      ip_len = sprintf(buf+off,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);
+-      off += ip_len;
+-      while (ip_len++ < 16) buf[off++] = ' ';
+-      if (!clip_vcc)
++          (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/HZ);
++
++      off = snprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d", NIPQUAD(entry->ip));
++      while (off < 16)
++              buf[off++] = ' ';
++      buf[off] = '\0';
++      seq_printf(seq, "%s", buf);
++
++      if (!clip_vcc) {
+               if (time_before(jiffies, entry->expires))
+-                      strcpy(buf+off,"(resolving)\n");
+-              else sprintf(buf+off,"(expired, ref %d)\n",
+-                          atomic_read(&entry->neigh->refcnt));
+-      else if (!svc)
+-                      sprintf(buf+off,"%d.%d.%d\n",clip_vcc->vcc->dev->number,
+-                          clip_vcc->vcc->vpi,clip_vcc->vcc->vci);
+-              else {
+-                      off += svc_addr(buf+off,&clip_vcc->vcc->remote);
+-                      strcpy(buf+off,"\n");
+-              }
++                      seq_printf(seq, "(resolving)\n");
++              else
++                      seq_printf(seq, "(expired, ref %d)\n",
++                                 atomic_read(&entry->neigh->refcnt));
++      } else if (!svc) {
++              seq_printf(seq, "%d.%d.%d\n", clip_vcc->vcc->dev->number,
++                         clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
++      } else {
++              svc_addr(seq, &clip_vcc->vcc->remote);
++              seq_putc(seq, '\n');
++      }
++}
++
++#endif /* CONFIG_ATM_CLIP */
++
++struct vcc_state {
++      struct sock *sk;
++      int family;
++      int clip_info;
++};
++
++static inline int compare_family(struct sock *sk, int family)
++{
++      struct atm_vcc *vcc = atm_sk(sk);
++
++      return !family || (vcc->sk->sk_family == family);
++}
++
++static int __vcc_walk(struct sock **sock, int family, loff_t l)
++{
++      struct sock *sk = *sock;
++
++      if (sk == (void *)1) {
++              sk = hlist_empty(&vcc_sklist) ? NULL : __sk_head(&vcc_sklist);
++              l--;
++      } 
++      for (; sk; sk = sk_next(sk)) {
++              l -= compare_family(sk, family);
++              if (l < 0)
++                      goto out;
++      }
++      sk = (void *)1;
++out:
++      *sock = sk;
++      return (l < 0);
++}
++
++static inline void *vcc_walk(struct vcc_state *state, loff_t l)
++{
++      return __vcc_walk(&state->sk, state->family, l) ?
++             state : NULL;
++}
++
++static int __vcc_seq_open(struct inode *inode, struct file *file,
++      int family, struct seq_operations *ops)
++{
++      struct vcc_state *state;
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++
++      state = kmalloc(sizeof(*state), GFP_KERNEL);
++      if (!state)
++              goto out;
++
++      rc = seq_open(file, ops);
++      if (rc)
++              goto out_kfree;
++
++      state->family = family;
++      state->clip_info = try_atm_clip_ops();
++
++      seq = file->private_data;
++      seq->private = state;
++out:
++      return rc;
++out_kfree:
++      kfree(state);
++      goto out;
+ }
++static int vcc_seq_release(struct inode *inode, struct file *file)
++{
++#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
++      struct seq_file *seq = file->private_data;
++      struct vcc_state *state = seq->private;
++      if (state->clip_info)
++              module_put(atm_clip_ops->owner);
+ #endif
++      return seq_release_private(inode, file);
++}
++static void *vcc_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct vcc_state *state = seq->private;
++      loff_t left = *pos;
+-static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info)
++      read_lock(&vcc_sklist_lock);
++      state->sk = (void *)1;
++      return left ? vcc_walk(state, left) : (void *)1;
++}
++
++static void vcc_seq_stop(struct seq_file *seq, void *v)
++{
++      read_unlock(&vcc_sklist_lock);
++}
++
++static void *vcc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct vcc_state *state = seq->private;
++
++      v = vcc_walk(state, 1);
++      *pos += !!PTR_ERR(v);
++      return v;
++}
++
++static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc, int clip_info)
+ {
+       static const char *class_name[] = { "off","UBR","CBR","VBR","ABR" };
+       static const char *aal_name[] = {
+@@ -171,9 +247,8 @@
+               "???",  "5",    "???",  "???",  /*  4- 7 */
+               "???",  "???",  "???",  "???",  /*  8-11 */
+               "???",  "0",    "???",  "???"}; /* 12-15 */
+-      int off;
+-      off = sprintf(buf,"%3d %3d %5d %-3s %7d %-5s %7d %-6s",
++      seq_printf(seq, "%3d %3d %5d %-3s %7d %-5s %7d %-6s",
+           vcc->dev->number,vcc->vpi,vcc->vci,
+           vcc->qos.aal >= sizeof(aal_name)/sizeof(aal_name[0]) ? "err" :
+           aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr,
+@@ -185,18 +260,14 @@
+               struct net_device *dev;
+               dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
+-              off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",
++              seq_printf(seq, "CLIP, Itf:%s, Encap:",
+                   dev ? dev->name : "none?");
+-              if (clip_vcc->encap)
+-                      off += sprintf(buf+off,"LLC/SNAP");
+-              else
+-                      off += sprintf(buf+off,"None");
++              seq_printf(seq, "%s", clip_vcc->encap ? "LLC/SNAP" : "None");
+       }
+ #endif
+-      strcpy(buf+off,"\n");
++      seq_putc(seq, '\n');
+ }
+-
+ static const char *vcc_state(struct atm_vcc *vcc)
+ {
+       static const char *map[] = { ATM_VS2TXT_MAP };
+@@ -204,337 +275,592 @@
+       return map[ATM_VF2VS(vcc->flags)];
+ }
+-
+-static void vc_info(struct atm_vcc *vcc,char *buf)
++static void vcc_info(struct seq_file *seq, struct atm_vcc *vcc)
+ {
+-      char *here;
+-
+-      here = buf+sprintf(buf,"%p ",vcc);
+-      if (!vcc->dev) here += sprintf(here,"Unassigned    ");
+-      else here += sprintf(here,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,
+-                  vcc->vci);
++      seq_printf(seq, "%p ", vcc);
++      if (!vcc->dev)
++              seq_printf(seq, "Unassigned    ");
++      else 
++              seq_printf(seq, "%3d %3d %5d ", vcc->dev->number, vcc->vpi,
++                      vcc->vci);
+       switch (vcc->sk->sk_family) {
+               case AF_ATMPVC:
+-                      here += sprintf(here,"PVC");
++                      seq_printf(seq, "PVC");
+                       break;
+               case AF_ATMSVC:
+-                      here += sprintf(here,"SVC");
++                      seq_printf(seq, "SVC");
+                       break;
+               default:
+-                      here += sprintf(here, "%3d", vcc->sk->sk_family);
++                      seq_printf(seq, "%3d", vcc->sk->sk_family);
+       }
+-      here += sprintf(here," %04lx  %5d %7d/%7d %7d/%7d\n",vcc->flags,
+-          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);
++      seq_printf(seq, " %04lx  %5d %7d/%7d %7d/%7d\n", vcc->flags, 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);
+ }
+-
+-static void svc_info(struct atm_vcc *vcc,char *buf)
++static void svc_info(struct seq_file *seq, struct atm_vcc *vcc)
+ {
+-      char *here;
+-      int i;
+-
+       if (!vcc->dev)
+-              sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%10s" : "N/A@%p%2s",
+-                  vcc,"");
+-      else sprintf(buf,"%3d %3d %5d         ",vcc->dev->number,vcc->vpi,
+-                  vcc->vci);
+-      here = strchr(buf,0);
+-      here += sprintf(here,"%-10s ",vcc_state(vcc));
+-      here += sprintf(here,"%s%s",vcc->remote.sas_addr.pub,
++              seq_printf(seq, sizeof(void *) == 4 ?
++                         "N/A@%p%10s" : "N/A@%p%2s", vcc, "");
++      else
++              seq_printf(seq, "%3d %3d %5d         ",
++                         vcc->dev->number, vcc->vpi, vcc->vci);
++      seq_printf(seq, "%-10s ", vcc_state(vcc));
++      seq_printf(seq, "%s%s", vcc->remote.sas_addr.pub,
+           *vcc->remote.sas_addr.pub && *vcc->remote.sas_addr.prv ? "+" : "");
+-      if (*vcc->remote.sas_addr.prv)
++      if (*vcc->remote.sas_addr.prv) {
++              int i;
++
+               for (i = 0; i < ATM_ESA_LEN; i++)
+-                      here += sprintf(here,"%02x",
+-                          vcc->remote.sas_addr.prv[i]);
+-      strcat(here,"\n");
++                      seq_printf(seq, "%02x", vcc->remote.sas_addr.prv[i]);
++      }
++      seq_putc(seq, '\n');
+ }
+-
+ #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+-static char*
+-lec_arp_get_status_string(unsigned char status)
++static char* lec_arp_get_status_string(unsigned char status)
+ {
+-  switch(status) {
+-  case ESI_UNKNOWN:
+-    return "ESI_UNKNOWN       ";
+-  case ESI_ARP_PENDING:
+-    return "ESI_ARP_PENDING   ";
+-  case ESI_VC_PENDING:
+-    return "ESI_VC_PENDING    ";
+-  case ESI_FLUSH_PENDING:
+-    return "ESI_FLUSH_PENDING ";
+-  case ESI_FORWARD_DIRECT:
+-    return "ESI_FORWARD_DIRECT";
+-  default:
+-    return "<Unknown>         ";
+-  }
++      static char *lec_arp_status_string[] = {
++              "ESI_UNKNOWN       ",
++              "ESI_ARP_PENDING   ",
++              "ESI_VC_PENDING    ",
++              "<Unknown>         ",
++              "ESI_FLUSH_PENDING ",
++              "ESI_FORWARD_DIRECT",
++              "<Undefined>"
++      };
++
++      if (status > ESI_FORWARD_DIRECT)
++              status = ESI_FORWARD_DIRECT + 1;
++      return lec_arp_status_string[status];
+ }
+-static void 
+-lec_info(struct lec_arp_table *entry, char *buf)
++static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
+ {
+-        int j, offset=0;
++      int i;
+-        for(j=0;j<ETH_ALEN;j++) {
+-                offset+=sprintf(buf+offset,"%2.2x",0xff&entry->mac_addr[j]);
+-        }
+-        offset+=sprintf(buf+offset, " ");
+-        for(j=0;j<ATM_ESA_LEN;j++) {
+-                offset+=sprintf(buf+offset,"%2.2x",0xff&entry->atm_addr[j]);
++      for (i = 0; i < ETH_ALEN; i++)
++              seq_printf(seq, "%2.2x", entry->mac_addr[i] & 0xff);
++      seq_printf(seq, " ");
++      for (i = 0; i < ATM_ESA_LEN; i++)
++              seq_printf(seq, "%2.2x", entry->atm_addr[i] & 0xff);
++      seq_printf(seq, " %s %4.4x", lec_arp_get_status_string(entry->status),
++                 entry->flags & 0xffff);
++      if (entry->vcc)
++              seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
++      else
++              seq_printf(seq, "        ");
++      if (entry->recv_vcc) {
++              seq_printf(seq, "     %3d %3d", entry->recv_vcc->vpi,
++                         entry->recv_vcc->vci);
+         }
+-        offset+=sprintf(buf+offset, " %s %4.4x",
+-                        lec_arp_get_status_string(entry->status),
+-                        entry->flags&0xffff);
+-        if (entry->vcc) {
+-                offset+=sprintf(buf+offset, "%3d %3d ", entry->vcc->vpi, 
+-                                entry->vcc->vci);                
+-        } else
+-                offset+=sprintf(buf+offset, "        ");
+-        if (entry->recv_vcc) {
+-                offset+=sprintf(buf+offset, "     %3d %3d", 
+-                                entry->recv_vcc->vpi, entry->recv_vcc->vci);
+-        }
+-
+-        sprintf(buf+offset,"\n");
++        seq_putc(seq, '\n');
+ }
+-#endif
++#endif /* CONFIG_ATM_LANE */
+-static int atm_devices_info(loff_t pos,char *buf)
++static int atm_dev_seq_show(struct seq_file *seq, void *v)
+ {
+-      struct atm_dev *dev;
+-      struct list_head *p;
+-      int left;
++      static char atm_dev_banner[] =
++              "Itf Type    ESI/\"MAC\"addr "
++              "AAL(TX,err,RX,err,drop) ...               [refcnt]\n";
++ 
++      if (v == (void *)1)
++              seq_puts(seq, atm_dev_banner);
++      else {
++              struct atm_dev *dev = list_entry(v, struct atm_dev, dev_list);
+-      if (!pos) {
+-              return sprintf(buf,"Itf Type    ESI/\"MAC\"addr "
+-                  "AAL(TX,err,RX,err,drop) ...               [refcnt]\n");
+-      }
+-      left = pos-1;
+-      spin_lock(&atm_dev_lock);
+-      list_for_each(p, &atm_devs) {
+-              dev = list_entry(p, struct atm_dev, dev_list);
+-              if (left-- == 0) {
+-                      atm_dev_info(dev,buf);
+-                      spin_unlock(&atm_dev_lock);
+-                      return strlen(buf);
+-              }
++              atm_dev_info(seq, dev);
++      }
++      return 0;
++}
++ 
++static struct seq_operations atm_dev_seq_ops = {
++      .start  = atm_dev_seq_start,
++      .next   = atm_dev_seq_next,
++      .stop   = atm_dev_seq_stop,
++      .show   = atm_dev_seq_show,
++};
++ 
++static int atm_dev_seq_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &atm_dev_seq_ops);
++}
++ 
++static struct file_operations devices_seq_fops = {
++      .open           = atm_dev_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release,
++};
++
++static int pvc_seq_show(struct seq_file *seq, void *v)
++{
++      static char atm_pvc_banner[] = 
++              "Itf VPI VCI   AAL RX(PCR,Class) TX(PCR,Class)\n";
++
++      if (v == (void *)1)
++              seq_puts(seq, atm_pvc_banner);
++      else {
++              struct vcc_state *state = seq->private;
++              struct atm_vcc *vcc = atm_sk(state->sk);
++
++              pvc_info(seq, vcc, state->clip_info);
+       }
+-      spin_unlock(&atm_dev_lock);
+       return 0;
+ }
+-/*
+- * FIXME: it isn't safe to walk the VCC list without turning off interrupts.
+- * What is really needed is some lock on the devices. Ditto for ATMARP.
+- */
++static struct seq_operations pvc_seq_ops = {
++      .start  = vcc_seq_start,
++      .next   = vcc_seq_next,
++      .stop   = vcc_seq_stop,
++      .show   = pvc_seq_show,
++};
++
++static int pvc_seq_open(struct inode *inode, struct file *file)
++{
++      return __vcc_seq_open(inode, file, PF_ATMPVC, &pvc_seq_ops);
++}
++
++static struct file_operations pvc_seq_fops = {
++      .open           = pvc_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = vcc_seq_release,
++};
+-static int atm_pvc_info(loff_t pos,char *buf)
++static int vcc_seq_show(struct seq_file *seq, void *v)
+ {
+-      struct hlist_node *node;
+-      struct sock *s;
+-      struct atm_vcc *vcc;
+-      int left, clip_info = 0;
+-
+-      if (!pos) {
+-              return sprintf(buf,"Itf VPI VCI   AAL RX(PCR,Class) "
+-                  "TX(PCR,Class)\n");
++      if (v == (void *)1) {
++              seq_printf(seq, sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s",
++                      "Address ", "Itf VPI VCI   Fam Flags Reply "
++                      "Send buffer     Recv buffer\n");
++      } else {
++              struct vcc_state *state = seq->private;
++              struct atm_vcc *vcc = atm_sk(state->sk);
++  
++              vcc_info(seq, vcc);
++      }
++      return 0;
++}
++  
++static struct seq_operations vcc_seq_ops = {
++      .start  = vcc_seq_start,
++      .next   = vcc_seq_next,
++      .stop   = vcc_seq_stop,
++      .show   = vcc_seq_show,
++};
++ 
++static int vcc_seq_open(struct inode *inode, struct file *file)
++{
++      return __vcc_seq_open(inode, file, 0, &vcc_seq_ops);
++}
++ 
++static struct file_operations vcc_seq_fops = {
++      .open           = vcc_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = vcc_seq_release,
++};
++
++static int svc_seq_show(struct seq_file *seq, void *v)
++{
++      static char atm_svc_banner[] = 
++              "Itf VPI VCI           State      Remote\n";
++
++      if (v == (void *)1)
++              seq_puts(seq, atm_svc_banner);
++      else {
++              struct vcc_state *state = seq->private;
++              struct atm_vcc *vcc = atm_sk(state->sk);
++
++              svc_info(seq, vcc);
+       }
+-      left = pos-1;
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-      if (try_atm_clip_ops())
+-              clip_info = 1;
+-#endif
+-      read_lock(&vcc_sklist_lock);
+-      sk_for_each(s, node, &vcc_sklist) {
+-              vcc = atm_sk(s);
+-              if (vcc->sk->sk_family == PF_ATMPVC && vcc->dev && !left--) {
+-                      pvc_info(vcc,buf,clip_info);
+-                      read_unlock(&vcc_sklist_lock);
++      return 0;
++}
++
++static struct seq_operations svc_seq_ops = {
++      .start  = vcc_seq_start,
++      .next   = vcc_seq_next,
++      .stop   = vcc_seq_stop,
++      .show   = svc_seq_show,
++};
++
++static int svc_seq_open(struct inode *inode, struct file *file)
++{
++      return __vcc_seq_open(inode, file, PF_ATMSVC, &svc_seq_ops);
++}
++
++static struct file_operations svc_seq_fops = {
++      .open           = svc_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = vcc_seq_release,
++};
++
+ #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-                      if (clip_info)
+-                              module_put(atm_clip_ops->owner);
+-#endif
+-                      return strlen(buf);
+-              }
++
++struct arp_state {
++      int bucket;
++      struct neighbour *n;
++      struct clip_vcc *vcc;
++};
++  
++static void *arp_vcc_walk(struct arp_state *state,
++                        struct atmarp_entry *e, loff_t *l)
++{
++      struct clip_vcc *vcc = state->vcc;
++
++      if (!vcc)
++              vcc = e->vccs;
++      if (vcc == (void *)1) {
++              vcc = e->vccs;
++              --*l;
++      }
++      for (; vcc; vcc = vcc->next) {
++              if (--*l < 0)
++                      break;
+       }
+-      read_unlock(&vcc_sklist_lock);
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-      if (clip_info)
+-              module_put(atm_clip_ops->owner);
+-#endif
+-      return 0;
++      state->vcc = vcc;
++      return (*l < 0) ? state : NULL;
+ }
++  
++static void *arp_get_idx(struct arp_state *state, loff_t l)
++{
++      void *v = NULL;
++      for (; state->bucket <= NEIGH_HASHMASK; state->bucket++) {
++              for (; state->n; state->n = state->n->next) {
++                      v = arp_vcc_walk(state, NEIGH2ENTRY(state->n), &l);
++                      if (v)
++                              goto done;
++              }
++              state->n = clip_tbl_hook->hash_buckets[state->bucket + 1];
++      }
++done:
++      return v;
++}
+-static int atm_vc_info(loff_t pos,char *buf)
++static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+-      struct atm_vcc *vcc;
+-      struct hlist_node *node;
+-      struct sock *s;
+-      int left;
+-
+-      if (!pos)
+-              return sprintf(buf,sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s",
+-                  "Address"," Itf VPI VCI   Fam Flags Reply Send buffer"
+-                  "     Recv buffer\n");
+-      left = pos-1;
+-      read_lock(&vcc_sklist_lock);
+-      sk_for_each(s, node, &vcc_sklist) {
+-              vcc = atm_sk(s);
+-              if (!left--) {
+-                      vc_info(vcc,buf);
+-                      read_unlock(&vcc_sklist_lock);
+-                      return strlen(buf);
+-              }
++      struct arp_state *state = seq->private;
++      void *ret = (void *)1;
++
++      if (!clip_tbl_hook) {
++              state->bucket = -1;
++              goto out;
+       }
+-      read_unlock(&vcc_sklist_lock);
+-      return 0;
++      read_lock_bh(&clip_tbl_hook->lock);
++      state->bucket = 0;
++      state->n = clip_tbl_hook->hash_buckets[0];
++      state->vcc = (void *)1;
++      if (*pos)
++              ret = arp_get_idx(state, *pos);
++out:
++      return ret;
+ }
++static void arp_seq_stop(struct seq_file *seq, void *v)
++{
++      struct arp_state *state = seq->private;
+-static int atm_svc_info(loff_t pos,char *buf)
++      if (state->bucket != -1)
++              read_unlock_bh(&clip_tbl_hook->lock);
++}
++
++static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+-      struct hlist_node *node;
+-      struct sock *s;
+-      struct atm_vcc *vcc;
+-      int left;
+-
+-      if (!pos)
+-              return sprintf(buf,"Itf VPI VCI           State      Remote\n");
+-      left = pos-1;
+-      read_lock(&vcc_sklist_lock);
+-      sk_for_each(s, node, &vcc_sklist) {
+-              vcc = atm_sk(s);
+-              if (vcc->sk->sk_family == PF_ATMSVC && !left--) {
+-                      svc_info(vcc,buf);
+-                      read_unlock(&vcc_sklist_lock);
+-                      return strlen(buf);
+-              }
+-      }
+-      read_unlock(&vcc_sklist_lock);
++      struct arp_state *state = seq->private;
+-      return 0;
++      v = arp_get_idx(state, 1);
++      *pos += !!PTR_ERR(v);
++      return v;
+ }
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-static int atm_arp_info(loff_t pos,char *buf)
++static int arp_seq_show(struct seq_file *seq, void *v)
+ {
+-      struct neighbour *n;
+-      int i,count;
++      static char atm_arp_banner[] = 
++              "IPitf TypeEncp Idle IP address      ATM address\n";
++
++      if (v == (void *)1)
++              seq_puts(seq, atm_arp_banner);
++      else {
++              struct arp_state *state = seq->private;
++              struct neighbour *n = state->n; 
++              struct clip_vcc *vcc = state->vcc;
+-      if (!pos) {
+-              return sprintf(buf,"IPitf TypeEncp Idle IP address      "
+-                  "ATM address\n");
++              atmarp_info(seq, n->dev, NEIGH2ENTRY(n), vcc);
+       }
++      return 0;
++}
++
++static struct seq_operations arp_seq_ops = {
++      .start  = arp_seq_start,
++      .next   = arp_seq_next,
++      .stop   = arp_seq_stop,
++      .show   = arp_seq_show,
++};
++
++static int arp_seq_open(struct inode *inode, struct file *file)
++{
++      struct arp_state *state;
++      struct seq_file *seq;
++      int rc = -EAGAIN;
++
+       if (!try_atm_clip_ops())
+-              return 0;
+-      count = pos;
+-      read_lock_bh(&clip_tbl_hook->lock);
+-      for (i = 0; i <= NEIGH_HASHMASK; i++)
+-              for (n = clip_tbl_hook->hash_buckets[i]; n; n = n->next) {
+-                      struct atmarp_entry *entry = NEIGH2ENTRY(n);
+-                      struct clip_vcc *vcc;
+-
+-                      if (!entry->vccs) {
+-                              if (--count) continue;
+-                              atmarp_info(n->dev,entry,NULL,buf);
+-                              read_unlock_bh(&clip_tbl_hook->lock);
+-                              module_put(atm_clip_ops->owner);
+-                              return strlen(buf);
+-                      }
+-                      for (vcc = entry->vccs; vcc;
+-                          vcc = vcc->next) {
+-                              if (--count) continue;
+-                              atmarp_info(n->dev,entry,vcc,buf);
+-                              read_unlock_bh(&clip_tbl_hook->lock);
+-                              module_put(atm_clip_ops->owner);
+-                              return strlen(buf);
+-                      }
+-              }
+-      read_unlock_bh(&clip_tbl_hook->lock);
++              goto out;
++
++      state = kmalloc(sizeof(*state), GFP_KERNEL);
++      if (!state) {
++              rc = -ENOMEM;
++              goto out_put;
++      }
++
++      rc = seq_open(file, &arp_seq_ops);
++      if (rc)
++              goto out_kfree;
++
++      seq = file->private_data;
++      seq->private = state;
++out:
++      return rc;
++
++out_put:
+       module_put(atm_clip_ops->owner);
+-      return 0;
++out_kfree:
++      kfree(state);
++      goto out;
+ }
+-#endif
+-#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+-static int atm_lec_info(loff_t pos,char *buf)
++static int arp_seq_release(struct inode *inode, struct file *file)
+ {
++      module_put(atm_clip_ops->owner);
++      return seq_release_private(inode, file);
++}
++
++static struct file_operations arp_seq_fops = {
++      .open           = arp_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = arp_seq_release,
++};
++
++#endif /* CONFIG_ATM_CLIP */
++
++#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
++
++struct lec_state {
+       unsigned long flags;
+-      struct lec_priv *priv;
++      struct lec_priv *locked;
+       struct lec_arp_table *entry;
+-      int i, count, d, e;
+       struct net_device *dev;
++      int itf;
++      int arp_table;
++      int misc_table;
++};
+-      if (!pos) {
+-              return sprintf(buf,"Itf  MAC          ATM destination"
+-                  "                          Status            Flags "
+-                  "VPI/VCI Recv VPI/VCI\n");
++static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,
++                        loff_t *l)
++{
++      struct lec_arp_table *e = state->entry;
++
++      if (!e)
++              e = tbl;
++      if (e == (void *)1) {
++              e = tbl;
++              --*l;
+       }
+-      if (!try_atm_lane_ops())
+-              return 0; /* the lane module is not there yet */
++      for (; e; e = e->next) {
++              if (--*l < 0)
++                      break;
++      }
++      state->entry = e;
++      return (*l < 0) ? state : NULL;
++}
+-      count = pos;
+-      for(d = 0; d < MAX_LEC_ITF; d++) {
+-              dev = atm_lane_ops->get_lec(d);
+-              if (!dev || !(priv = (struct lec_priv *) dev->priv))
+-                      continue;
+-              spin_lock_irqsave(&priv->lec_arp_lock, flags);
+-              for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+-                      for(entry = priv->lec_arp_tables[i]; entry; entry = entry->next) {
+-                              if (--count)
+-                                      continue;
+-                              e = sprintf(buf,"%s ", dev->name);
+-                              lec_info(entry, buf+e);
+-                              spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+-                              dev_put(dev);
+-                              module_put(atm_lane_ops->owner);
+-                              return strlen(buf);
+-                      }
+-              }
+-              for(entry = priv->lec_arp_empty_ones; entry; entry = entry->next) {
+-                      if (--count)
+-                              continue;
+-                      e = sprintf(buf,"%s ", dev->name);
+-                      lec_info(entry, buf+e);
+-                      spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+-                      dev_put(dev);
+-                      module_put(atm_lane_ops->owner);
+-                      return strlen(buf);
+-              }
+-              for(entry = priv->lec_no_forward; entry; entry=entry->next) {
+-                      if (--count)
+-                              continue;
+-                      e = sprintf(buf,"%s ", dev->name);
+-                      lec_info(entry, buf+e);
+-                      spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+-                      dev_put(dev);
+-                      module_put(atm_lane_ops->owner);
+-                      return strlen(buf);
+-              }
+-              for(entry = priv->mcast_fwds; entry; entry = entry->next) {
+-                      if (--count)
+-                              continue;
+-                      e = sprintf(buf,"%s ", dev->name);
+-                      lec_info(entry, buf+e);
+-                      spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+-                      dev_put(dev);
+-                      module_put(atm_lane_ops->owner);
+-                      return strlen(buf);
+-              }
+-              spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
++static void *lec_arp_walk(struct lec_state *state, loff_t *l,
++                            struct lec_priv *priv)
++{
++      void *v = NULL;
++      int p;
++
++      for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
++              v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);
++              if (v)
++                      break;
++      }
++      state->arp_table = p;
++      return v;
++}
++
++static void *lec_misc_walk(struct lec_state *state, loff_t *l,
++                         struct lec_priv *priv)
++{
++      struct lec_arp_table *lec_misc_tables[] = {
++              priv->lec_arp_empty_ones,
++              priv->lec_no_forward,
++              priv->mcast_fwds
++      };
++      void *v = NULL;
++      int q;
++
++      for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {
++              v = lec_tbl_walk(state, lec_misc_tables[q], l);
++              if (v)
++                      break;
++      }
++      state->misc_table = q;
++      return v;
++}
++
++static void *lec_priv_walk(struct lec_state *state, loff_t *l,
++                         struct lec_priv *priv)
++{
++      if (!state->locked) {
++              state->locked = priv;
++              spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
++      }
++      if (!lec_arp_walk(state, l, priv) &&
++          !lec_misc_walk(state, l, priv)) {
++              spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
++              state->locked = NULL;
++              /* Partial state reset for the next time we get called */
++              state->arp_table = state->misc_table = 0;
++      }
++      return state->locked;
++}
++
++static void *lec_itf_walk(struct lec_state *state, loff_t *l)
++{
++      struct net_device *dev;
++      void *v;
++
++      dev = state->dev ? state->dev : atm_lane_ops->get_lec(state->itf);
++      v = (dev && dev->priv) ? lec_priv_walk(state, l, dev->priv) : NULL;
++      if (!v && dev) {
+               dev_put(dev);
++              /* Partial state reset for the next time we get called */
++              dev = NULL;
++      }
++      state->dev = dev;
++      return v;
++}
++
++static void *lec_get_idx(struct lec_state *state, loff_t l)
++{
++      void *v = NULL;
++
++      for (; state->itf < MAX_LEC_ITF; state->itf++) {
++              v = lec_itf_walk(state, &l);
++              if (v)
++                      break;
++      }
++      return v; 
++}
++
++static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct lec_state *state = seq->private;
++
++      state->itf = 0;
++      state->dev = NULL;
++      state->locked = NULL;
++      state->arp_table = 0;
++      state->misc_table = 0;
++      state->entry = (void *)1;
++
++      return *pos ? lec_get_idx(state, *pos) : (void*)1;
++}
++
++static void lec_seq_stop(struct seq_file *seq, void *v)
++{
++      struct lec_state *state = seq->private;
++
++      if (state->dev) {
++              spin_unlock_irqrestore(&state->locked->lec_arp_lock,
++                                     state->flags);
++              dev_put(state->dev);
++      }
++}
++
++static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct lec_state *state = seq->private;
++
++      v = lec_get_idx(state, 1);
++      *pos += !!PTR_ERR(v);
++      return v;
++}
++
++static int lec_seq_show(struct seq_file *seq, void *v)
++{
++      static char lec_banner[] = "Itf  MAC          ATM destination" 
++              "                          Status            Flags "
++              "VPI/VCI Recv VPI/VCI\n";
++
++      if (v == (void *)1)
++              seq_puts(seq, lec_banner);
++      else {
++              struct lec_state *state = seq->private;
++              struct net_device *dev = state->dev; 
++
++              seq_printf(seq, "%s ", dev->name);
++              lec_info(seq, state->entry);
+       }
+-      module_put(atm_lane_ops->owner);
+       return 0;
+ }
+-#endif
++static struct seq_operations lec_seq_ops = {
++      .start  = lec_seq_start,
++      .next   = lec_seq_next,
++      .stop   = lec_seq_stop,
++      .show   = lec_seq_show,
++};
++
++static int lec_seq_open(struct inode *inode, struct file *file)
++{
++      struct lec_state *state;
++      struct seq_file *seq;
++      int rc = -EAGAIN;
++
++      if (!try_atm_lane_ops())
++              goto out;
++
++      state = kmalloc(sizeof(*state), GFP_KERNEL);
++      if (!state) {
++              rc = -ENOMEM;
++              goto out;
++      }
++
++      rc = seq_open(file, &lec_seq_ops);
++      if (rc)
++              goto out_kfree;
++      seq = file->private_data;
++      seq->private = state;
++out:
++      return rc;
++out_kfree:
++      kfree(state);
++      goto out;
++}
++
++static int lec_seq_release(struct inode *inode, struct file *file)
++{
++      module_put(atm_lane_ops->owner);
++      return seq_release_private(inode, file);
++}
++
++static struct file_operations lec_seq_fops = {
++      .open           = lec_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = lec_seq_release,
++};
++
++#endif /* CONFIG_ATM_LANE */
+ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
+     loff_t *pos)
+@@ -562,28 +888,6 @@
+ }
+-static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count,
+-    loff_t *pos)
+-{
+-      unsigned long page;
+-      int length;
+-      int (*info)(loff_t,char *);
+-      info = PDE(file->f_dentry->d_inode)->data;
+-
+-      if (count == 0) return 0;
+-      page = get_zeroed_page(GFP_KERNEL);
+-      if (!page) return -ENOMEM;
+-      length = (*info)(*pos,(char *) page);
+-      if (length > count) length = -EINVAL;
+-      if (length >= 0) {
+-              if (copy_to_user(buf,(char *) page,length)) length = -EFAULT;
+-              (*pos)++;
+-      }
+-      free_page(page);
+-      return length;
+-}
+-
+-
+ struct proc_dir_entry *atm_proc_root;
+ EXPORT_SYMBOL(atm_proc_root);
+@@ -604,19 +908,19 @@
+       dev->proc_name = kmalloc(strlen(dev->type) + digits + 2, GFP_KERNEL);
+       if (!dev->proc_name)
+-              goto fail1;
++              goto err_out;
+       sprintf(dev->proc_name,"%s:%d",dev->type, dev->number);
+       dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root);
+       if (!dev->proc_entry)
+-              goto fail0;
++              goto err_free_name;
+       dev->proc_entry->data = dev;
+-      dev->proc_entry->proc_fops = &proc_dev_atm_operations;
++      dev->proc_entry->proc_fops = &proc_atm_dev_ops;
+       dev->proc_entry->owner = THIS_MODULE;
+       return 0;
+-fail0:
++err_free_name:
+       kfree(dev->proc_name);
+-fail1:
++err_out:
+       return error;
+ }
+@@ -630,57 +934,65 @@
+       kfree(dev->proc_name);
+ }
++static struct atm_proc_entry {
++      char *name;
++      struct file_operations *proc_fops;
++      struct proc_dir_entry *dirent;
++} atm_proc_ents[] = {
++      { .name = "devices",    .proc_fops = &devices_seq_fops },
++      { .name = "pvc",        .proc_fops = &pvc_seq_fops },
++      { .name = "svc",        .proc_fops = &svc_seq_fops },
++      { .name = "vc",         .proc_fops = &vcc_seq_fops },
++#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
++      { .name = "arp",        .proc_fops = &arp_seq_fops },
++#endif
++#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
++      { .name = "lec",        .proc_fops = &lec_seq_fops },
++#endif
++      { .name = NULL,         .proc_fops = NULL }
++};
++
++static void atm_proc_dirs_remove(void)
++{
++      static struct atm_proc_entry *e;
+-#define CREATE_ENTRY(name) \
+-    name = create_proc_entry(#name,0,atm_proc_root); \
+-    if (!name) goto cleanup; \
+-    name->data = atm_##name##_info; \
+-    name->proc_fops = &proc_spec_atm_operations; \
+-    name->owner = THIS_MODULE
+-
+-static struct proc_dir_entry *devices = NULL, *pvc = NULL,
+-              *svc = NULL, *arp = NULL, *lec = NULL, *vc = NULL;
+-
+-static void atm_proc_cleanup(void)
+-{
+-      if (devices)
+-              remove_proc_entry("devices",atm_proc_root);
+-      if (pvc)
+-              remove_proc_entry("pvc",atm_proc_root);
+-      if (svc)
+-              remove_proc_entry("svc",atm_proc_root);
+-      if (arp)
+-              remove_proc_entry("arp",atm_proc_root);
+-      if (lec)
+-              remove_proc_entry("lec",atm_proc_root);
+-      if (vc)
+-              remove_proc_entry("vc",atm_proc_root);
+-      remove_proc_entry("net/atm",NULL);
++      for (e = atm_proc_ents; e->name; e++) {
++              if (e->dirent) 
++                      remove_proc_entry(e->name, atm_proc_root);
++      }
++      remove_proc_entry("net/atm", NULL);
+ }
+ int __init atm_proc_init(void)
+ {
++      static struct atm_proc_entry *e;
++      int ret;
++
+       atm_proc_root = proc_mkdir("net/atm",NULL);
+       if (!atm_proc_root)
+-              return -ENOMEM;
+-      CREATE_ENTRY(devices);
+-      CREATE_ENTRY(pvc);
+-      CREATE_ENTRY(svc);
+-      CREATE_ENTRY(vc);
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-      CREATE_ENTRY(arp);
+-#endif
+-#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+-      CREATE_ENTRY(lec);
+-#endif
+-      return 0;
+-
+-cleanup:
+-      atm_proc_cleanup();
+-      return -ENOMEM;
++              goto err_out;
++      for (e = atm_proc_ents; e->name; e++) {
++              struct proc_dir_entry *dirent;
++
++              dirent = create_proc_entry(e->name, S_IRUGO, atm_proc_root);
++              if (!dirent)
++                      goto err_out_remove;
++              dirent->proc_fops = e->proc_fops;
++              dirent->owner = THIS_MODULE;
++              e->dirent = dirent;
++      }
++      ret = 0;
++out:
++      return ret;
++
++err_out_remove:
++      atm_proc_dirs_remove();
++err_out:
++      ret = -ENOMEM;
++      goto out;
+ }
+-void atm_proc_exit(void)
++void __exit atm_proc_exit(void)
+ {
+-      atm_proc_cleanup();
++      atm_proc_dirs_remove();
+ }
+Index: linux-2.6.0-test5/net/atm/resources.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/resources.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/resources.c      2003-09-27 11:38:41.552211488 +0800
+@@ -30,7 +30,7 @@
+ {
+       struct atm_dev *dev;
+-      dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
++      dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return NULL;
+       memset(dev, 0, sizeof(*dev));
+@@ -395,6 +395,35 @@
+       return error;
+ }
++static __inline__ void *dev_get_idx(loff_t left)
++{
++      struct list_head *p;
++
++      list_for_each(p, &atm_devs) {
++              if (!--left)
++                      break;
++      }
++      return (p != &atm_devs) ? p : NULL;
++}
++
++void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      spin_lock(&atm_dev_lock);
++      return *pos ? dev_get_idx(*pos) : (void *) 1;
++}
++
++void atm_dev_seq_stop(struct seq_file *seq, void *v)
++{
++      spin_unlock(&atm_dev_lock);
++}
++ 
++void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      ++*pos;
++      v = (v == (void *)1) ? atm_devs.next : ((struct list_head *)v)->next;
++      return (v == &atm_devs) ? NULL : v;
++}
++
+ EXPORT_SYMBOL(atm_dev_register);
+ EXPORT_SYMBOL(atm_dev_deregister);
+Index: linux-2.6.0-test5/net/atm/resources.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/atm/resources.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/atm/resources.h      2003-09-27 11:38:41.553211336 +0800
+@@ -21,6 +21,11 @@
+ #include <linux/proc_fs.h>
++void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos);
++void atm_dev_seq_stop(struct seq_file *seq, void *v);
++void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
++
++
+ int atm_proc_dev_register(struct atm_dev *dev);
+ void atm_proc_dev_deregister(struct atm_dev *dev);
+Index: linux-2.6.0-test5/net/ax25/ax25_route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ax25/ax25_route.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ax25/ax25_route.c    2003-09-27 11:38:41.557210728 +0800
+@@ -281,8 +281,6 @@
+ #ifdef CONFIG_PROC_FS
+-#define AX25_PROC_START       ((void *)1)
+-
+ static void *ax25_rt_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       struct ax25_route *ax25_rt;
+@@ -290,7 +288,7 @@
+  
+       read_lock(&ax25_route_lock);
+       if (*pos == 0)
+-              return AX25_PROC_START;
++              return SEQ_START_TOKEN;
+       for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
+               if (i == *pos)
+@@ -304,7 +302,7 @@
+ static void *ax25_rt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       ++*pos;
+-      return (v == AX25_PROC_START) ? ax25_route_list : 
++      return (v == SEQ_START_TOKEN) ? ax25_route_list : 
+               ((struct ax25_route *) v)->next;
+ }
+@@ -315,7 +313,7 @@
+ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == AX25_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "callsign  dev  mode digipeaters\n");
+       else {
+               struct ax25_route *ax25_rt = v;
+Index: linux-2.6.0-test5/net/ax25/ax25_uid.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ax25/ax25_uid.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ax25/ax25_uid.c      2003-09-27 11:38:41.560210272 +0800
+@@ -144,8 +144,6 @@
+ #ifdef CONFIG_PROC_FS
+-#define AX25_PROC_START       ((void *)1)
+-
+ static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       struct ax25_uid_assoc *pt;
+@@ -153,7 +151,7 @@
+       read_lock(&ax25_uid_lock);
+       if (*pos == 0)
+-              return AX25_PROC_START;
++              return SEQ_START_TOKEN;
+       for (pt = ax25_uid_list; pt != NULL; pt = pt->next) {
+               if (i == *pos)
+@@ -166,7 +164,7 @@
+ static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       ++*pos;
+-      return (v == AX25_PROC_START) ? ax25_uid_list : 
++      return (v == SEQ_START_TOKEN) ? ax25_uid_list : 
+               ((struct ax25_uid_assoc *) v)->next;
+ }
+@@ -177,7 +175,7 @@
+ static int ax25_uid_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == AX25_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
+       else {
+               struct ax25_uid_assoc *pt = v;
+Index: linux-2.6.0-test5/net/bluetooth/af_bluetooth.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/af_bluetooth.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/af_bluetooth.c     2003-09-27 11:38:41.562209968 +0800
+@@ -27,7 +27,7 @@
+  *
+  * $Id: 2.6.0-test5-mm4.patch,v 1.1.4.1 2003/10/02 19:51:59 rread Exp $
+  */
+-#define VERSION "2.2"
++#define VERSION "2.3"
+ #include <linux/config.h>
+ #include <linux/module.h>
+@@ -130,7 +130,6 @@
+       }
+       sock_init_data(sock, sk);
+-      sk_set_owner(sk, THIS_MODULE);
+       INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
+       
+       sk->sk_zapped   = 0;
+@@ -273,39 +272,35 @@
+       return mask;
+ }
+-int bt_sock_w4_connect(struct sock *sk, int flags)
++int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
+ {
+       DECLARE_WAITQUEUE(wait, current);
+-      long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+       int err = 0;
+       BT_DBG("sk %p", sk);
+       add_wait_queue(sk->sk_sleep, &wait);
+-      while (sk->sk_state != BT_CONNECTED) {
++      while (sk->sk_state != state) {
+               set_current_state(TASK_INTERRUPTIBLE);
++
+               if (!timeo) {
+                       err = -EAGAIN;
+                       break;
+               }
++              if (signal_pending(current)) {
++                      err = sock_intr_errno(timeo);
++                      break;
++              }
++
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock(sk);
+-              err = 0;
+-              if (sk->sk_state == BT_CONNECTED)
+-                      break;
+-
+               if (sk->sk_err) {
+                       err = sock_error(sk);
+                       break;
+               }
+-
+-              if (signal_pending(current)) {
+-                      err = sock_intr_errno(timeo);
+-                      break;
+-              }
+       }
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(sk->sk_sleep, &wait);
+Index: linux-2.6.0-test5/net/bluetooth/bnep/bnep.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/bnep.h   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/bnep.h        2003-09-27 11:38:41.565209512 +0800
+@@ -168,11 +168,11 @@
+       u64    mc_filter;
+       
+       struct socket    *sock;
+-      struct net_device dev;
++      struct net_device *dev;
+       struct net_device_stats stats;
+ };
+-int bnep_net_init(struct net_device *dev);
++void bnep_net_setup(struct net_device *dev);
+ int bnep_sock_init(void);
+ int bnep_sock_cleanup(void);
+Index: linux-2.6.0-test5/net/bluetooth/bnep/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/core.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/core.c        2003-09-27 11:38:41.569208904 +0800
+@@ -180,7 +180,7 @@
+               s->mc_filter = 0;
+               /* Always send broadcast */
+-              set_bit(bnep_mc_hash(s->dev.broadcast), (ulong *) &s->mc_filter);
++              set_bit(bnep_mc_hash(s->dev->broadcast), (ulong *) &s->mc_filter);
+               /* Add address ranges to the multicast hash */
+               for (; n > 0; n--) {
+@@ -293,7 +293,7 @@
+ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
+ {
+-      struct net_device *dev = &s->dev;
++      struct net_device *dev = s->dev;
+       struct sk_buff *nskb;
+       u8 type;
+@@ -451,7 +451,7 @@
+ static int bnep_session(void *arg)
+ {
+       struct bnep_session *s = arg;
+-      struct net_device *dev = &s->dev;
++      struct net_device *dev = s->dev;
+       struct sock *sk = s->sock->sk;
+       struct sk_buff *skb;
+       wait_queue_t wait;
+@@ -501,7 +501,7 @@
+       __bnep_unlink_session(s);
+       up_write(&bnep_session_sem);
+-      kfree(s);
++      kfree(dev);
+       return 0;
+ }
+@@ -517,10 +517,13 @@
+       baswap((void *) dst, &bt_sk(sock->sk)->dst);
+       baswap((void *) src, &bt_sk(sock->sk)->src);
+-      s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
+-      if (!s) 
+-              return -ENOMEM;
+-      memset(s, 0, sizeof(struct bnep_session));
++      /* session struct allocated as private part of net_device */
++      dev = alloc_netdev(sizeof(struct bnep_session),
++                         (*req->device) ? req->device : "bnep%d",
++                         bnep_net_setup);
++      if (!dev) 
++              return ENOMEM;
++
+       down_write(&bnep_session_sem);
+@@ -530,20 +533,15 @@
+               goto failed;
+       }
+-      dev = &s->dev;
+-      
+-      if (*req->device)
+-              strcpy(dev->name, req->device);
+-      else
+-              strcpy(dev->name, "bnep%d");
++      s = dev->priv;
+-      memset(dev->broadcast, 0xff, ETH_ALEN);
+-      
+       /* This is rx header therefore addresses are swapped.
+        * ie eh.h_dest is our local address. */
+       memcpy(s->eh.h_dest,   &src, ETH_ALEN);
+       memcpy(s->eh.h_source, &dst, ETH_ALEN);
++      memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
++      s->dev = dev;
+       s->sock  = sock;
+       s->role  = req->role;
+       s->state = BT_CONNECTED;
+@@ -569,8 +567,6 @@
+       s->proto_filter[2].end   = htons(0x86DD);
+ #endif
+       
+-      dev->init = bnep_net_init;
+-      dev->priv = s;
+       err = register_netdev(dev);
+       if (err) {
+               goto failed;
+@@ -578,7 +574,7 @@
+       __bnep_link_session(s);
+       
+-      err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      err = kernel_thread(bnep_session, s, CLONE_KERNEL);
+       if (err < 0) {
+               /* Session thread start failed, gotta cleanup. */
+               unregister_netdev(dev);
+@@ -592,7 +588,7 @@
+ failed:
+       up_write(&bnep_session_sem);
+-      kfree(s);
++      kfree(dev);
+       return err;
+ }
+@@ -624,7 +620,7 @@
+ static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
+ {
+       memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
+-      strcpy(ci->device, s->dev.name);
++      strcpy(ci->device, s->dev->name);
+       ci->flags = s->flags;
+       ci->state = s->state;
+       ci->role  = s->role;
+Index: linux-2.6.0-test5/net/bluetooth/bnep/netdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/netdev.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/netdev.c      2003-09-27 11:38:41.572208448 +0800
+@@ -226,11 +226,10 @@
+       return 0;
+ }
+-int bnep_net_init(struct net_device *dev)
++void bnep_net_setup(struct net_device *dev)
+ {
+-      struct bnep_session *s = dev->priv;
+-      memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
++      memset(dev->broadcast, 0xff, ETH_ALEN);
+       dev->addr_len = ETH_ALEN;
+       ether_setup(dev);
+@@ -245,6 +244,4 @@
+       dev->watchdog_timeo  = HZ * 2;
+       dev->tx_timeout      = bnep_net_timeout;
+-
+-      return 0;
+ }
+Index: linux-2.6.0-test5/net/bluetooth/bnep/sock.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/bnep/sock.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/bnep/sock.c        2003-09-27 11:38:41.574208144 +0800
+@@ -175,6 +175,9 @@
+       if (!(sk = bt_sock_alloc(sock, PF_BLUETOOTH, 0, GFP_KERNEL)))
+               return -ENOMEM;
++
++      sk_set_owner(sk, THIS_MODULE);
++
+       sock->ops = &bnep_sock_ops;
+       sock->state  = SS_UNCONNECTED;
+@@ -186,6 +189,7 @@
+ static struct net_proto_family bnep_sock_family_ops = {
+       .family = PF_BLUETOOTH,
++      .owner  = THIS_MODULE,
+       .create = bnep_sock_create
+ };
+Index: linux-2.6.0-test5/net/bluetooth/hci_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/hci_core.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/hci_core.c 2003-09-27 11:38:41.583206776 +0800
+@@ -394,7 +394,7 @@
+ {
+       struct hci_inquiry_req ir;
+       struct hci_dev *hdev;
+-      int err = 0, do_inquiry = 0;
++      int err = 0, do_inquiry = 0, max_rsp;
+       long timeo;
+       __u8 *buf, *ptr;
+@@ -417,16 +417,19 @@
+       if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
+               goto done;
++      /* for unlimited number of responses we will use buffer with 255 entries */
++      max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
++
+       /* cache_dump can't sleep. Therefore we allocate temp buffer and then
+        * copy it to the user space.
+        */
+-      if (!(buf = kmalloc(sizeof(struct inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
++      if (!(buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL))) {
+               err = -ENOMEM;
+               goto done;
+       }
+       hci_dev_lock_bh(hdev);
+-      ir.num_rsp = inquiry_cache_dump(hdev, ir.num_rsp, buf);
++      ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
+       hci_dev_unlock_bh(hdev);
+       BT_DBG("num_rsp %d", ir.num_rsp);
+Index: linux-2.6.0-test5/net/bluetooth/hci_event.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/hci_event.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/hci_event.c        2003-09-27 11:38:41.589205864 +0800
+@@ -62,9 +62,22 @@
+ /* Command Complete OGF LINK_CTL  */
+ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+ {
++      __u8 status;
++
+       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+       switch (ocf) {
++      case OCF_INQUIRY_CANCEL:
++              status = *((__u8 *) skb->data);
++
++              if (status) {
++                      BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
++              } else {
++                      clear_bit(HCI_INQUIRY, &hdev->flags);
++                      hci_req_complete(hdev, status);
++              }
++              break;
++
+       default:
+               BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
+               break;
+Index: linux-2.6.0-test5/net/bluetooth/hci_sock.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/hci_sock.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/hci_sock.c 2003-09-27 11:38:41.593205256 +0800
+@@ -75,7 +75,7 @@
+               /* OGF_LINK_POLICY */
+               { 0x1200, 0x0, 0x0, 0x0      },
+               /* OGF_HOST_CTL */
+-              { 0x80100000, 0x2a, 0x0, 0x0 },
++              { 0x80100000, 0x202a, 0x0, 0x0 },
+               /* OGF_INFO_PARAM */
+               { 0x22a, 0x0, 0x0, 0x0       },
+               /* OGF_STATUS_PARAM */
+@@ -587,6 +587,8 @@
+       if (!sk)
+               return -ENOMEM;
++      sk_set_owner(sk, THIS_MODULE);
++
+       sock->state = SS_UNCONNECTED;
+       sk->sk_state   = BT_OPEN;
+Index: linux-2.6.0-test5/net/bluetooth/l2cap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/l2cap.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/l2cap.c    2003-09-27 11:38:41.606203280 +0800
+@@ -289,7 +289,7 @@
+                       struct l2cap_disconn_req req;
+                       sk->sk_state = BT_DISCONN;
+-                      l2cap_sock_set_timer(sk, HZ * 5);
++                      l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+                       req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+                       req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+@@ -314,11 +314,9 @@
+ static void l2cap_sock_close(struct sock *sk)
+ {
+       l2cap_sock_clear_timer(sk);
+-
+       lock_sock(sk);
+       __l2cap_sock_close(sk, ECONNRESET);
+       release_sock(sk);
+-
+       l2cap_sock_kill(sk);
+ }
+@@ -530,8 +528,8 @@
+               goto done;
+ wait:
+-      err = bt_sock_w4_connect(sk, flags);
+-
++      err = bt_sock_wait_state(sk, BT_CONNECTED,
++                      sock_sndtimeo(sk, flags & O_NONBLOCK));
+ done:
+       release_sock(sk);
+       return err;
+@@ -831,32 +829,39 @@
+ static int l2cap_sock_shutdown(struct socket *sock, int how)
+ {
+       struct sock *sk = sock->sk;
++      int err = 0;
+       BT_DBG("sock %p, sk %p", sock, sk);
+       if (!sk) return 0;
+-      l2cap_sock_clear_timer(sk);
+-
+       lock_sock(sk);
+-      sk->sk_shutdown = SHUTDOWN_MASK;
+-      __l2cap_sock_close(sk, ECONNRESET);
+-      release_sock(sk);
++      if (!sk->sk_shutdown) {
++              sk->sk_shutdown = SHUTDOWN_MASK;
++              l2cap_sock_clear_timer(sk);
++              __l2cap_sock_close(sk, 0);
+-      return 0;
++              if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
++                      err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
++      }
++      release_sock(sk);
++      return err;
+ }
+ static int l2cap_sock_release(struct socket *sock)
+ {
+       struct sock *sk = sock->sk;
++      int err;
+       BT_DBG("sock %p, sk %p", sock, sk);
+       if (!sk) return 0;
++      err = l2cap_sock_shutdown(sock, 2);
++
+       sock_orphan(sk);
+-      l2cap_sock_close(sk);
+-      return 0;
++      l2cap_sock_kill(sk);
++      return err;
+ }
+ /* ---- L2CAP channels ---- */
+@@ -980,9 +985,11 @@
+               hci_conn_put(conn->hcon);
+       }
+-      sk->sk_state = BT_CLOSED;
+-      sk->sk_err   = err;
++      sk->sk_state  = BT_CLOSED;
+       sk->sk_zapped = 1;
++      
++      if (err)
++              sk->sk_err = err;
+       if (parent)
+               parent->sk_data_ready(parent, 0);
+@@ -1518,18 +1525,35 @@
+       if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+               return -ENOENT;
+-      if (result) {
+-              struct l2cap_disconn_req req;
++      switch (result) {
++      case L2CAP_CONF_SUCCESS:
++              break;
+-              /* They didn't like our options. Well... we do not negotiate.
+-               * Close channel.
+-               */
++      case L2CAP_CONF_UNACCEPT:
++              if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
++                      char req[128];
++                      /* 
++                         It does not make sense to adjust L2CAP parameters 
++                         that are currently defined in the spec. We simply 
++                         resend config request that we sent earlier. It is
++                         stupid :) but it helps qualification testing
++                         which expects at least some response from us.
++                      */
++                      l2cap_send_req(conn, L2CAP_CONF_REQ,
++                              l2cap_build_conf_req(sk, req), req);
++                      goto done;
++              }
++
++      default: 
+               sk->sk_state = BT_DISCONN;
++              sk->sk_err   = ECONNRESET;
+               l2cap_sock_set_timer(sk, HZ * 5);
+-
+-              req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+-              req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
+-              l2cap_send_req(conn, L2CAP_DISCONN_REQ, sizeof(req), &req);
++              {
++                      struct l2cap_disconn_req req;
++                      req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
++                      req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
++                      l2cap_send_req(conn, L2CAP_DISCONN_REQ, sizeof(req), &req);
++              }
+               goto done;
+       }
+@@ -1590,7 +1614,7 @@
+       if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+               return 0;
+-      l2cap_chan_del(sk, ECONNABORTED);
++      l2cap_chan_del(sk, 0);
+       bh_unlock_sock(sk);
+       l2cap_sock_kill(sk);
+Index: linux-2.6.0-test5/net/bluetooth/rfcomm/core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/rfcomm/core.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/rfcomm/core.c      2003-09-27 11:38:41.617201608 +0800
+@@ -280,13 +280,13 @@
+ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
+ {
+       struct rfcomm_session *s;
+-      u8 dlci = __dlci(0, channel);
+       int err = 0;
++      u8 dlci;
+-      BT_DBG("dlc %p state %ld %s %s channel %d dlci %d", 
+-                      d, d->state, batostr(src), batostr(dst), channel, dlci);
++      BT_DBG("dlc %p state %ld %s %s channel %d", 
++                      d, d->state, batostr(src), batostr(dst), channel);
+-      if (dlci < 1 || dlci > 62)
++      if (channel < 1 || channel > 30)
+               return -EINVAL;
+       if (d->state != BT_OPEN && d->state != BT_CLOSED)
+@@ -299,6 +299,8 @@
+                       return err;
+       }
++      dlci = __dlci(!s->initiator, channel);
++
+       /* Check if DLCI already exists */
+       if (rfcomm_dlc_get(s, dlci))
+               return -EBUSY;
+@@ -715,7 +717,7 @@
+       hdr->len  = __len8(sizeof(*mcc) + 1);
+       mcc = (void *) ptr; ptr += sizeof(*mcc);
+-      mcc->type = __mcc_type(s->initiator, RFCOMM_NSC);
++      mcc->type = __mcc_type(cr, RFCOMM_NSC);
+       mcc->len  = __len8(1);
+       /* Type that we didn't like */
+@@ -741,7 +743,7 @@
+       hdr->len  = __len8(sizeof(*mcc) + sizeof(*pn));
+       mcc = (void *) ptr; ptr += sizeof(*mcc);
+-      mcc->type = __mcc_type(s->initiator, RFCOMM_PN);
++      mcc->type = __mcc_type(cr, RFCOMM_PN);
+       mcc->len  = __len8(sizeof(*pn));
+       pn = (void *) ptr; ptr += sizeof(*pn);
+@@ -850,7 +852,51 @@
+       msc = (void *) ptr; ptr += sizeof(*msc);
+       msc->dlci    = __addr(1, dlci);
+-      msc->v24_sig = v24_sig;
++      msc->v24_sig = v24_sig | 0x01;
++
++      *ptr = __fcs(buf); ptr++;
++
++      return rfcomm_send_frame(s, buf, ptr - buf);
++}
++
++static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
++{
++      struct rfcomm_hdr *hdr;
++      struct rfcomm_mcc *mcc;
++      u8 buf[16], *ptr = buf;
++
++      BT_DBG("%p cr %d", s, cr);
++
++      hdr = (void *) ptr; ptr += sizeof(*hdr);
++      hdr->addr = __addr(s->initiator, 0);
++      hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
++      hdr->len  = __len8(sizeof(*mcc));
++
++      mcc = (void *) ptr; ptr += sizeof(*mcc);
++      mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
++      mcc->len  = __len8(0);
++
++      *ptr = __fcs(buf); ptr++;
++
++      return rfcomm_send_frame(s, buf, ptr - buf);
++}
++
++static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
++{
++      struct rfcomm_hdr *hdr;
++      struct rfcomm_mcc *mcc;
++      u8 buf[16], *ptr = buf;
++
++      BT_DBG("%p cr %d", s, cr);
++
++      hdr = (void *) ptr; ptr += sizeof(*hdr);
++      hdr->addr = __addr(s->initiator, 0);
++      hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
++      hdr->len  = __len8(sizeof(*mcc));
++
++      mcc = (void *) ptr; ptr += sizeof(*mcc);
++      mcc->type = __mcc_type(cr, RFCOMM_FCON);
++      mcc->len  = __len8(0);
+       *ptr = __fcs(buf); ptr++;
+@@ -1085,6 +1131,8 @@
+               d->state = BT_CONNECTED;
+               d->state_change(d, 0);
+               rfcomm_dlc_unlock(d);
++
++              rfcomm_send_msc(s, 1, dlci, d->v24_sig);
+       } else {
+               rfcomm_send_dm(s, dlci);
+       }
+@@ -1207,6 +1255,14 @@
+       }
+       /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
+                                 no flow control lines, normal XON/XOFF chars */
++      if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
++              bit_rate = rpn->bit_rate;
++              if (bit_rate != RFCOMM_RPN_BR_115200) {
++                      BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
++                      bit_rate = RFCOMM_RPN_BR_115200;
++                      rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
++              }
++      }
+       if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
+               data_bits = __get_rpn_data_bits(rpn->line_settings);
+               if (data_bits != RFCOMM_RPN_DATA_8) {
+@@ -1232,22 +1288,25 @@
+               }
+       }
+       if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
+-              if (rpn->flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
+-                      BT_DBG("RPN flow ctrl mismatch 0x%x", rpn->flow_ctrl);
++              flow_ctrl = rpn->flow_ctrl;
++              if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
++                      BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
+                       flow_ctrl = RFCOMM_RPN_FLOW_NONE;
+                       rpn_mask ^= RFCOMM_RPN_PM_FLOW;
+               }
+       }
+       if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
+-              if (rpn->xon_char != RFCOMM_RPN_XON_CHAR) {
+-                      BT_DBG("RPN XON char mismatch 0x%x", rpn->xon_char);
++              xon_char = rpn->xon_char;
++              if (xon_char != RFCOMM_RPN_XON_CHAR) {
++                      BT_DBG("RPN XON char mismatch 0x%x", xon_char);
+                       xon_char = RFCOMM_RPN_XON_CHAR;
+                       rpn_mask ^= RFCOMM_RPN_PM_XON;
+               }
+       }
+       if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
+-              if (rpn->xoff_char != RFCOMM_RPN_XOFF_CHAR) {
+-                      BT_DBG("RPN XOFF char mismatch 0x%x", rpn->xoff_char);
++              xoff_char = rpn->xoff_char;
++              if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
++                      BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
+                       xoff_char = RFCOMM_RPN_XOFF_CHAR;
+                       rpn_mask ^= RFCOMM_RPN_PM_XOFF;
+               }
+@@ -1343,6 +1402,20 @@
+               rfcomm_recv_msc(s, cr, skb);
+               break;
++      case RFCOMM_FCOFF:
++              if (cr) {
++                      set_bit(RFCOMM_TX_THROTTLED, &s->flags);
++                      rfcomm_send_fcoff(s, 0);
++              }
++              break;
++
++      case RFCOMM_FCON:
++              if (cr) {
++                      clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
++                      rfcomm_send_fcon(s, 0);
++              }
++              break;
++
+       case RFCOMM_TEST:
+               if (cr)
+                       rfcomm_send_test(s, 0, skb->data, skb->len);
+@@ -1533,6 +1606,9 @@
+                       continue;
+               }
++              if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
++                      continue;
++
+               if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
+                               d->mscex == RFCOMM_MSCEX_OK)
+                       rfcomm_process_tx(d);
+@@ -1881,7 +1957,7 @@
+ {
+       l2cap_load();
+-      kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++      kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
+       BT_INFO("RFCOMM ver %s", VERSION);
+Index: linux-2.6.0-test5/net/bluetooth/rfcomm/sock.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/rfcomm/sock.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/rfcomm/sock.c      2003-09-27 11:38:41.623200696 +0800
+@@ -192,8 +192,10 @@
+       BT_DBG("parent %p", parent);
+       /* Close not yet accepted dlcs */
+-      while ((sk = bt_accept_dequeue(parent, NULL)))
++      while ((sk = bt_accept_dequeue(parent, NULL))) {
+               rfcomm_sock_close(sk);
++              rfcomm_sock_kill(sk);
++      }
+       parent->sk_state  = BT_CLOSED;
+       parent->sk_zapped = 1;
+@@ -215,15 +217,10 @@
+       sock_put(sk);
+ }
+-/* Close socket.
+- * Must be called on unlocked socket.
+- */
+-static void rfcomm_sock_close(struct sock *sk)
++static void __rfcomm_sock_close(struct sock *sk)
+ {
+       struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
+-      lock_sock(sk);
+-
+       BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
+       switch (sk->sk_state) {
+@@ -240,11 +237,17 @@
+       default:
+               sk->sk_zapped = 1;
+               break;
+-      };
++      }
++}
++/* Close socket.
++ * Must be called on unlocked socket.
++ */
++static void rfcomm_sock_close(struct sock *sk)
++{
++      lock_sock(sk);
++      __rfcomm_sock_close(sk);
+       release_sock(sk);
+-
+-      rfcomm_sock_kill(sk);
+ }
+ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
+@@ -374,7 +377,8 @@
+       err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
+       if (!err)
+-              err = bt_sock_w4_connect(sk, flags);
++              err = bt_sock_wait_state(sk, BT_CONNECTED,
++                              sock_sndtimeo(sk, flags & O_NONBLOCK));
+       release_sock(sk);
+       return err;
+@@ -558,9 +562,6 @@
+       int target, err = 0, copied = 0;
+       long timeo;
+-      if (sk->sk_state != BT_CONNECTED)
+-              return -EINVAL;
+-
+       if (flags & MSG_OOB)
+               return -EOPNOTSUPP;
+@@ -635,23 +636,6 @@
+       return copied ? : err;
+ }
+-static int rfcomm_sock_shutdown(struct socket *sock, int how)
+-{
+-      struct sock *sk = sock->sk;
+-
+-      BT_DBG("sock %p, sk %p", sock, sk);
+-
+-      if (!sk) return 0;
+-
+-      lock_sock(sk);
+-      sk->sk_shutdown = SHUTDOWN_MASK;
+-      if (sk->sk_state == BT_CONNECTED)
+-              rfcomm_dlc_close(rfcomm_pi(sk)->dlc, 0);
+-      release_sock(sk);
+-
+-      return 0;
+-}
+-
+ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+ {
+       struct sock *sk = sock->sk;
+@@ -710,19 +694,42 @@
+       return err;
+ }
++static int rfcomm_sock_shutdown(struct socket *sock, int how)
++{
++      struct sock *sk = sock->sk;
++      int err = 0;
++
++      BT_DBG("sock %p, sk %p", sock, sk);
++
++      if (!sk) return 0;
++
++      lock_sock(sk);
++      if (!sk->sk_shutdown) {
++              sk->sk_shutdown = SHUTDOWN_MASK;
++              __rfcomm_sock_close(sk);
++
++              if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
++                      err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
++      }
++      release_sock(sk);
++      return err;
++}
++
+ static int rfcomm_sock_release(struct socket *sock)
+ {
+       struct sock *sk = sock->sk;
++      int err;
+       BT_DBG("sock %p, sk %p", sock, sk);
+       if (!sk)
+               return 0;
+-      sock_orphan(sk);
+-      rfcomm_sock_close(sk);
++      err = rfcomm_sock_shutdown(sock, 2);
+-      return 0;
++      sock_orphan(sk);
++      rfcomm_sock_kill(sk);
++      return err;
+ }
+ /* ---- RFCOMM core layer callbacks ---- 
+Index: linux-2.6.0-test5/net/bluetooth/rfcomm/tty.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/rfcomm/tty.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/rfcomm/tty.c       2003-09-27 11:38:41.629199784 +0800
+@@ -668,40 +668,8 @@
+       return room;
+ }
+-static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
+-{
+-      u8 v24_sig, mask;
+-
+-      BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
+-
+-      if (cmd == TIOCMSET)
+-              v24_sig = 0;
+-      else
+-              rfcomm_dlc_get_modem_status(dlc, &v24_sig);
+-
+-      mask =  ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
+-              ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
+-              ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
+-              ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
+-              ((status & TIOCM_RI)  ? RFCOMM_V24_IC  : 0) |
+-              ((status & TIOCM_CD)  ? RFCOMM_V24_DV  : 0);
+-
+-      if (cmd == TIOCMBIC)
+-              v24_sig &= ~mask;
+-      else
+-              v24_sig |= mask;
+-
+-      rfcomm_dlc_set_modem_status(dlc, v24_sig);
+-      return 0;
+-}
+-
+ static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+-      struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
+-      struct rfcomm_dlc *dlc = dev->dlc;
+-      uint status;
+-      int err;
+-
+       BT_DBG("tty %p cmd 0x%02x", tty, cmd);
+       switch (cmd) {
+@@ -713,18 +681,6 @@
+               BT_DBG("TCSETS is not supported");
+               return -ENOIOCTLCMD;
+-      case TIOCMGET:
+-              BT_DBG("TIOCMGET");
+-
+-              return put_user(dev->modem_status, (unsigned int *)arg);
+-
+-      case TIOCMSET: /* Turns on and off the lines as specified by the mask */
+-      case TIOCMBIS: /* Turns on the lines as specified by the mask */
+-      case TIOCMBIC: /* Turns off the lines as specified by the mask */
+-              if ((err = get_user(status, (unsigned int *)arg)))
+-                      return err;
+-              return rfcomm_tty_set_modem_status(cmd, dlc, status);
+-
+       case TIOCMIWAIT:
+               BT_DBG("TIOCMIWAIT");
+               break;
+@@ -851,6 +807,48 @@
+       return 0;
+ }
++static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp)
++{
++      struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
++
++      BT_DBG("tty %p dev %p", tty, dev);
++
++      return dev->modem_status;
++}
++
++static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear)
++{
++      struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
++      struct rfcomm_dlc *dlc = dev->dlc;
++      u8 v24_sig;
++
++      BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
++
++      rfcomm_dlc_get_modem_status(dlc, &v24_sig);
++
++      if (set & TIOCM_DSR || set & TIOCM_DTR)
++              v24_sig |= RFCOMM_V24_RTC;
++      if (set & TIOCM_RTS || set & TIOCM_CTS)
++              v24_sig |= RFCOMM_V24_RTR;
++      if (set & TIOCM_RI)
++              v24_sig |= RFCOMM_V24_IC;
++      if (set & TIOCM_CD)
++              v24_sig |= RFCOMM_V24_DV;
++
++      if (clear & TIOCM_DSR || clear & TIOCM_DTR)
++              v24_sig &= ~RFCOMM_V24_RTC;
++      if (clear & TIOCM_RTS || clear & TIOCM_CTS)
++              v24_sig &= ~RFCOMM_V24_RTR;
++      if (clear & TIOCM_RI)
++              v24_sig &= ~RFCOMM_V24_IC;
++      if (clear & TIOCM_CD)
++              v24_sig &= ~RFCOMM_V24_DV;
++
++      rfcomm_dlc_set_modem_status(dlc, v24_sig);
++
++      return 0;
++}
++
+ /* ---- TTY structure ---- */
+ static struct tty_driver *rfcomm_tty_driver;
+@@ -870,6 +868,8 @@
+       .hangup                 = rfcomm_tty_hangup,
+       .wait_until_sent        = rfcomm_tty_wait_until_sent,
+       .read_proc              = rfcomm_tty_read_proc,
++      .tiocmget               = rfcomm_tty_tiocmget,
++      .tiocmset               = rfcomm_tty_tiocmset,
+ };
+ int rfcomm_init_ttys(void)
+@@ -878,18 +878,17 @@
+       if (!rfcomm_tty_driver)
+               return -1;
+-      rfcomm_tty_driver->owner        = THIS_MODULE,
+-      rfcomm_tty_driver->driver_name  = "rfcomm",
+-      rfcomm_tty_driver->devfs_name   = "bluetooth/rfcomm/",
+-      rfcomm_tty_driver->name         = "rfcomm",
+-      rfcomm_tty_driver->major        = RFCOMM_TTY_MAJOR,
+-      rfcomm_tty_driver->minor_start  = RFCOMM_TTY_MINOR,
+-      rfcomm_tty_driver->type         = TTY_DRIVER_TYPE_SERIAL,
+-      rfcomm_tty_driver->subtype      = SERIAL_TYPE_NORMAL,
+-      rfcomm_tty_driver->flags        = TTY_DRIVER_REAL_RAW,
+-      rfcomm_tty_driver->init_termios = tty_std_termios;
+-      rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+-      rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW;
++      rfcomm_tty_driver->owner        = THIS_MODULE;
++      rfcomm_tty_driver->driver_name  = "rfcomm";
++      rfcomm_tty_driver->devfs_name   = "bluetooth/rfcomm/";
++      rfcomm_tty_driver->name         = "rfcomm";
++      rfcomm_tty_driver->major        = RFCOMM_TTY_MAJOR;
++      rfcomm_tty_driver->minor_start  = RFCOMM_TTY_MINOR;
++      rfcomm_tty_driver->type         = TTY_DRIVER_TYPE_SERIAL;
++      rfcomm_tty_driver->subtype      = SERIAL_TYPE_NORMAL;
++      rfcomm_tty_driver->flags        = TTY_DRIVER_REAL_RAW;
++      rfcomm_tty_driver->init_termios = tty_std_termios;
++      rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
+       if (tty_register_driver(rfcomm_tty_driver)) {
+Index: linux-2.6.0-test5/net/bluetooth/sco.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/sco.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/sco.c      2003-09-27 11:38:41.636198720 +0800
+@@ -353,8 +353,10 @@
+       BT_DBG("parent %p", parent);
+       /* Close not yet accepted channels */
+-      while ((sk = bt_accept_dequeue(parent, NULL)))
++      while ((sk = bt_accept_dequeue(parent, NULL))) {
+               sco_sock_close(sk);
++              sco_sock_kill(sk);
++      }
+       parent->sk_state  = BT_CLOSED;
+       parent->sk_zapped = 1;
+@@ -523,7 +525,8 @@
+       if ((err = sco_connect(sk)))
+               goto done;
+-      err = bt_sock_w4_connect(sk, flags);
++      err = bt_sock_wait_state(sk, BT_CONNECTED, 
++                      sock_sndtimeo(sk, flags & O_NONBLOCK));
+ done:
+       release_sock(sk);
+@@ -727,16 +730,24 @@
+ static int sco_sock_release(struct socket *sock)
+ {
+       struct sock *sk = sock->sk;
++      int err = 0;
+       BT_DBG("sock %p, sk %p", sock, sk);
+       if (!sk)
+               return 0;
+-
+-      sock_orphan(sk);
++      
+       sco_sock_close(sk);
+-      return 0;
++      if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
++              lock_sock(sk);
++              err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
++              release_sock(sk);
++      }
++
++      sock_orphan(sk);
++      sco_sock_kill(sk);
++      return err;
+ }
+ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
+Index: linux-2.6.0-test5/net/bluetooth/syms.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bluetooth/syms.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bluetooth/syms.c     2003-09-27 11:38:41.637198568 +0800
+@@ -77,6 +77,6 @@
+ EXPORT_SYMBOL(bt_sock_poll);
+ EXPORT_SYMBOL(bt_accept_enqueue);
+ EXPORT_SYMBOL(bt_accept_dequeue);
+-EXPORT_SYMBOL(bt_sock_w4_connect);
++EXPORT_SYMBOL(bt_sock_wait_state);
+ EXPORT_SYMBOL(proc_bt);
+Index: linux-2.6.0-test5/net/bridge/br_forward.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/bridge/br_forward.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/bridge/br_forward.c  2003-09-27 11:38:41.639198264 +0800
+@@ -69,6 +69,7 @@
+       indev = skb->dev;
+       skb->dev = to->dev;
++      skb->ip_summed = CHECKSUM_NONE;
+       NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
+                       br_forward_finish);
+Index: linux-2.6.0-test5/net/core/dev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/core/dev.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/core/dev.c   2003-09-27 11:38:41.659195224 +0800
+@@ -183,6 +183,10 @@
+ extern int netdev_sysfs_init(void);
+ extern int netdev_register_sysfs(struct net_device *);
++extern int netdev_unregister_sysfs(struct net_device *);
++#ifdef CONFIG_KGDB
++extern int kgdb_net_interrupt(struct sk_buff *skb);
++#endif
+ /*******************************************************************************
+@@ -470,10 +474,10 @@
+  *    to be sure the name is not allocated or removed during the test the
+  *    caller must hold the rtnl semaphore.
+  *
+- *    This function primarily exists for back compatibility with older
++ *    This function exists only for back compatibility with older
+  *    drivers.
+  */
+-int dev_get(const char *name)
++int __dev_get(const char *name)
+ {
+       struct net_device *dev;
+@@ -698,7 +702,13 @@
+ void dev_load(const char *name)
+ {
+-      if (!dev_get(name) && capable(CAP_SYS_MODULE))
++      struct net_device *dev;  
++
++      read_lock(&dev_base_lock);
++      dev = __dev_get_by_name(name);
++      read_unlock(&dev_base_lock);
++
++      if (!dev && capable(CAP_SYS_MODULE))
+               request_module("%s", name);
+ }
+@@ -841,7 +851,11 @@
+        * engine, but this requires more changes in devices. */
+       smp_mb__after_clear_bit(); /* Commit netif_running(). */
+-      netif_poll_disable(dev);
++      while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
++              /* No hurry. */
++              current->state = TASK_INTERRUPTIBLE;
++              schedule_timeout(1);
++      }
+       /*
+        *      Call the device specific close. This cannot fail.
+@@ -1315,7 +1329,6 @@
+ }
+ #endif
+-
+ /**
+  *    netif_rx        -       post buffer to the network code
+  *    @skb: buffer to post
+@@ -1340,6 +1353,21 @@
+       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);
+@@ -1840,13 +1868,13 @@
+ void *dev_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&dev_base_lock);
+-      return *pos ? dev_get_idx(*pos - 1) : (void *)1;
++      return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN;
+ }
+ void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       ++*pos;
+-      return v == (void *)1 ? dev_base : ((struct net_device *)v)->next;
++      return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next;
+ }
+ void dev_seq_stop(struct seq_file *seq, void *v)
+@@ -1886,7 +1914,7 @@
+  */
+ static int dev_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "Inter-|   Receive                            "
+                             "                    |  Transmit\n"
+                             " face |bytes    packets errs drop fifo frame "
+@@ -1990,26 +2018,21 @@
+ static int __init dev_proc_init(void)
+ {
+-      struct proc_dir_entry *p;
+       int rc = -ENOMEM;
+-      p = create_proc_entry("dev", S_IRUGO, proc_net);
+-      if (!p)
++      if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
+               goto out;
+-      p->proc_fops = &dev_seq_fops;
+-      p = create_proc_entry("softnet_stat", S_IRUGO, proc_net);
+-      if (!p)
++      if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
+               goto out_dev;
+-      p->proc_fops = &softnet_seq_fops;
+       if (wireless_proc_init())
+               goto out_softnet;
+       rc = 0;
+ out:
+       return rc;
+ out_softnet:
+-      remove_proc_entry("softnet_stat", proc_net);
++      proc_net_remove("softnet_stat");
+ out_dev:
+-      remove_proc_entry("dev", proc_net);
++      proc_net_remove("dev");
+       goto out;
+ }
+ #else
+@@ -2755,7 +2778,6 @@
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(HZ / 4);
+-              current->state = TASK_RUNNING;
+               if (time_after(jiffies, warning_time + 10 * HZ)) {
+                       printk(KERN_EMERG "unregister_netdevice: "
+@@ -2819,7 +2841,7 @@
+                       break;
+               case NETREG_UNREGISTERING:
+-                      class_device_del(&dev->class_dev);
++                      netdev_unregister_sysfs(dev);
+                       dev->reg_state = NETREG_UNREGISTERED;
+                       netdev_wait_allrefs(dev);
+Index: linux-2.6.0-test5/net/core/net-sysfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/core/net-sysfs.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/core/net-sysfs.c     2003-09-27 11:38:41.662194768 +0800
+@@ -383,6 +383,21 @@
+ #endif
+ };
++void netdev_unregister_sysfs(struct net_device * net)
++{
++      struct class_device * class_dev = &(net->class_dev);
++
++      if (net->get_stats)
++              sysfs_remove_group(&class_dev->kobj, &netstat_group);
++
++#ifdef WIRELESS_EXT
++      if (net->get_wireless_stats)
++              sysfs_remove_group(&class_dev->kobj, &wireless_group);
++#endif
++      class_device_del(class_dev);
++
++}
++
+ /* Create sysfs entries for network device. */
+ int netdev_register_sysfs(struct net_device *net)
+ {
+@@ -411,9 +426,15 @@
+ #ifdef WIRELESS_EXT
+       if (net->get_wireless_stats &&
+           (ret = sysfs_create_group(&class_dev->kobj, &wireless_group)))
+-              goto out_unreg; 
+-#endif
++              goto out_cleanup;
++
++      return 0;
++out_cleanup:
++      if (net->get_stats)
++              sysfs_remove_group(&class_dev->kobj, &netstat_group);
++#else
+       return 0;
++#endif
+ out_unreg:
+       printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
+Index: linux-2.6.0-test5/net/core/wireless.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/core/wireless.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/core/wireless.c      2003-09-27 11:38:41.673193096 +0800
+@@ -458,7 +458,7 @@
+  */
+ static int wireless_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "Inter-| sta-|   Quality        |   Discarded "
+                               "packets               | Missed | WE\n"
+                               " face | tus | link level noise |  nwid  "
+@@ -495,15 +495,10 @@
+ int __init wireless_proc_init(void)
+ {
+-      struct proc_dir_entry *p;
+-      int rc = 0;
++      if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops))
++              return -ENOMEM;
+-      p = create_proc_entry("wireless", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &wireless_seq_fops;
+-      else
+-              rc = -ENOMEM;
+-      return rc;
++      return 0;
+ }
+ #endif        /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/decnet/af_decnet.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/decnet/af_decnet.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/decnet/af_decnet.c   2003-09-27 11:38:41.688190816 +0800
+@@ -2146,14 +2146,14 @@
+ static void *dn_socket_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+-      return *pos ? dn_socket_get_idx(seq, *pos - 1) : (void*)1;
++      return *pos ? dn_socket_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *dn_socket_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       void *rc;
+-      if (v == (void*)1) {
++      if (v == SEQ_START_TOKEN) {
+               rc = dn_socket_get_idx(seq, 0);
+               goto out;
+       }
+@@ -2169,7 +2169,7 @@
+ static void dn_socket_seq_stop(struct seq_file *seq, void *v)
+ {
+-      if (v && v != (void*)1)
++      if (v && v != SEQ_START_TOKEN)
+               read_unlock_bh(&dn_hash_lock);
+ }
+@@ -2269,7 +2269,7 @@
+ static int dn_socket_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void*)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Local                                              Remote\n");
+       } else {
+               dn_socket_format_entry(seq, v);
+Index: linux-2.6.0-test5/net/decnet/dn_dev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/decnet/dn_dev.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/decnet/dn_dev.c      2003-09-27 11:38:41.698189296 +0800
+@@ -1365,7 +1365,7 @@
+                       read_unlock(&dev_base_lock);
+               return dev;
+       }
+-      return (void*)1;
++      return SEQ_START_TOKEN;
+ }
+ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -1373,7 +1373,7 @@
+       struct net_device *dev = v;
+       loff_t one = 1;
+-      if (v == (void*)1) {
++      if (v == SEQ_START_TOKEN) {
+               dev = dn_dev_seq_start(seq, &one);
+       } else {
+               dev = dn_dev_get_next(seq, dev);
+@@ -1386,7 +1386,7 @@
+ static void dn_dev_seq_stop(struct seq_file *seq, void *v)
+ {
+-      if (v && v != (void*)1)
++      if (v && v != SEQ_START_TOKEN)
+               read_unlock(&dev_base_lock);
+ }
+@@ -1406,7 +1406,7 @@
+ static int dn_dev_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void*)1)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "Name     Flags T1   Timer1 T3   Timer3 BlkSize Pri State DevType    Router Peer\n");
+       else {
+               struct net_device *dev = v;
+Index: linux-2.6.0-test5/net/decnet/dn_neigh.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/decnet/dn_neigh.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/decnet/dn_neigh.c    2003-09-27 11:38:41.703188536 +0800
+@@ -604,7 +604,7 @@
+ static void *dn_neigh_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+-      return *pos ? dn_neigh_get_idx(seq, *pos - 1) : (void*)1;
++      return *pos ? dn_neigh_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *dn_neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -612,7 +612,7 @@
+       void *rc;
+-      if (v == (void*)1) {
++      if (v == SEQ_START_TOKEN) {
+               rc = dn_neigh_get_idx(seq, 0);
+               goto out;
+       }
+@@ -628,7 +628,7 @@
+ static void dn_neigh_seq_stop(struct seq_file *seq, void *v)
+ {
+-      if (v && v != (void*)1)
++      if (v && v != SEQ_START_TOKEN)
+               read_unlock_bh(&dn_neigh_table.lock);
+ }
+@@ -653,7 +653,7 @@
+ static int dn_neigh_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void*)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Addr    Flags State Use Blksize Dev\n");
+       } else {
+               dn_neigh_format_entry(seq, v);
+Index: linux-2.6.0-test5/net/ipv4/arp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/arp.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/arp.c   2003-09-27 11:38:41.712187168 +0800
+@@ -1275,7 +1275,7 @@
+ static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+-      return *pos ? arp_get_idx(seq, *pos - 1) : (void *)1;
++      return *pos ? arp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -1283,7 +1283,7 @@
+       void *rc;
+       struct arp_iter_state* state;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               rc = arp_get_idx(seq, 0);
+               goto out;
+       }
+@@ -1306,7 +1306,7 @@
+ {
+       struct arp_iter_state* state = seq->private;
+-      if (!state->is_pneigh && v != (void *)1)
++      if (!state->is_pneigh && v != SEQ_START_TOKEN)
+               read_unlock_bh(&arp_tbl.lock);
+ }
+@@ -1359,7 +1359,7 @@
+ static int arp_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "IP address       HW type     Flags       "
+                             "HW address            Mask     Device\n");
+       else {
+@@ -1416,14 +1416,9 @@
+ static int __init arp_proc_init(void)
+ {
+-      int rc = 0;
+-      struct proc_dir_entry *p = create_proc_entry("arp", S_IRUGO, proc_net);
+-
+-        if (p)
+-              p->proc_fops = &arp_seq_fops;
+-      else
+-              rc = -ENOMEM;
+-      return rc;
++      if (!proc_net_fops_create("arp", S_IRUGO, &arp_seq_fops))
++              return -ENOMEM;
++      return 0;
+ }
+ #else /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/ipv4/fib_hash.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/fib_hash.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/fib_hash.c      2003-09-27 11:38:41.720185952 +0800
+@@ -979,14 +979,14 @@
+       read_lock(&fib_hash_lock);
+       if (ip_fib_main_table)
+-              v = *pos ? fib_get_next(seq) : (void *)1;
++              v = *pos ? fib_get_next(seq) : SEQ_START_TOKEN;
+       return v;
+ }
+ static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       ++*pos;
+-      return v == (void *)1 ? fib_get_first(seq) : fib_get_next(seq);
++      return v == SEQ_START_TOKEN ? fib_get_first(seq) : fib_get_next(seq);
+ }
+ static void fib_seq_stop(struct seq_file *seq, void *v)
+@@ -1025,7 +1025,7 @@
+       struct fib_node *f;
+       struct fib_info *fi;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
+                          "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
+                          "\tWindow\tIRTT");
+@@ -1096,19 +1096,13 @@
+ int __init fib_proc_init(void)
+ {
+-      struct proc_dir_entry *p;
+-      int rc = 0;
+-
+-      p = create_proc_entry("route", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &fib_seq_fops;
+-      else
+-              rc = -ENOMEM;
+-      return rc;
++      if (!proc_net_fops_create("route", S_IRUGO, &fib_seq_fops))
++              return -ENOMEM;
++      return 0;
+ }
+ void __init fib_proc_exit(void)
+ {
+-      remove_proc_entry("route", proc_net);
++      proc_net_remove("route");
+ }
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/ipv4/icmp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/icmp.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/icmp.c  2003-09-27 11:38:41.728184736 +0800
+@@ -669,7 +669,7 @@
+                       printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
+                                           "type %u, code %u "
+                                           "error to a broadcast: %u.%u.%u.%u on %s\n",
+-                             NIPQUAD(iph->saddr),
++                             NIPQUAD(skb->nh.iph->saddr),
+                              icmph->type, icmph->code,
+                              NIPQUAD(iph->daddr),
+                              skb->dev->name);
+Index: linux-2.6.0-test5/net/ipv4/igmp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/igmp.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/igmp.c  2003-09-27 11:38:41.744182304 +0800
+@@ -280,8 +280,10 @@
+                                   .nl_u = { .ip4_u = {
+                                   .daddr = IGMPV3_ALL_MCR } },
+                                   .proto = IPPROTO_IGMP };
+-              if (ip_route_output_key(&rt, &fl))
++              if (ip_route_output_key(&rt, &fl)) {
++                      kfree_skb(skb);
+                       return 0;
++              }
+       }
+       if (rt->rt_src == 0) {
+               ip_rt_put(rt);
+@@ -2162,13 +2164,13 @@
+ static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&dev_base_lock);
+-      return *pos ? igmp_mc_get_idx(seq, *pos) : (void *)1;
++      return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct ip_mc_list *im;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               im = igmp_mc_get_first(seq);
+       else
+               im = igmp_mc_get_next(seq, v);
+@@ -2190,7 +2192,7 @@
+ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, 
+                          "Idx\tDevice    : Count Querier\tGroup    Users Timer\tReporter\n");
+       else {
+@@ -2337,13 +2339,13 @@
+ static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&dev_base_lock);
+-      return *pos ? igmp_mcf_get_idx(seq, *pos) : (void *)1;
++      return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct ip_sf_list *psf;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               psf = igmp_mcf_get_first(seq);
+       else
+               psf = igmp_mcf_get_next(seq, v);
+@@ -2372,7 +2374,7 @@
+       struct ip_sf_list *psf = (struct ip_sf_list *)v;
+       struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, 
+                          "%3s %6s "
+                          "%10s %10s %6s %6s\n", "Idx",
+@@ -2430,15 +2432,8 @@
+ int __init igmp_mc_proc_init(void)
+ {
+-      struct proc_dir_entry *p;
+-
+-      p = create_proc_entry("igmp", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &igmp_mc_seq_fops;
+-
+-      p = create_proc_entry("mcfilter", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &igmp_mcf_seq_fops;
++      proc_net_fops_create("igmp", S_IRUGO, &igmp_mc_seq_fops);
++      proc_net_fops_create("mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
+       return 0;
+ }
+ #endif
+Index: linux-2.6.0-test5/net/ipv4/ipconfig.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipconfig.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipconfig.c      2003-09-27 11:38:41.753180936 +0800
+@@ -50,6 +50,7 @@
+ #include <linux/route.h>
+ #include <linux/udp.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/major.h>
+ #include <linux/root_dev.h>
+ #include <net/arp.h>
+@@ -1092,43 +1093,45 @@
+ #ifdef CONFIG_PROC_FS
+-static int pnp_get_info(char *buffer, char **start,
+-                      off_t offset, int length)
++static int pnp_seq_show(struct seq_file *seq, void *v)
+ {
+-      int len;
+-       int i;
++      int i;
+       if (ic_proto_used & IC_PROTO)
+-          sprintf(buffer, "#PROTO: %s\n",
+-                  (ic_proto_used & IC_RARP) ? "RARP"
+-                  : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
++              seq_printf(seq, "#PROTO: %s\n",
++                         (ic_proto_used & IC_RARP) ? "RARP"
++                         : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
+       else
+-          strcpy(buffer, "#MANUAL\n");
+-      len = strlen(buffer);
++              seq_puts(seq, "#MANUAL\n");
+       if (ic_domain[0])
+-              len += sprintf(buffer + len,
+-                             "domain %s\n", ic_domain);
++              seq_printf(seq,
++                         "domain %s\n", ic_domain);
+       for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
+               if (ic_nameservers[i] != INADDR_NONE)
+-                      len += sprintf(buffer + len,
+-                                     "nameserver %u.%u.%u.%u\n",
+-                                     NIPQUAD(ic_nameservers[i]));
++                      seq_printf(seq,
++                                 "nameserver %u.%u.%u.%u\n",
++                                 NIPQUAD(ic_nameservers[i]));
+       }
+       if (ic_servaddr != INADDR_NONE)
+-              len += sprintf(buffer + len,
+-                             "bootserver %u.%u.%u.%u\n",
+-                             NIPQUAD(ic_servaddr));
+-
+-      if (offset > len)
+-              offset = len;
+-      *start = buffer + offset;
+-
+-      if (offset + length > len)
+-              length = len - offset;
+-      return length;
++              seq_printf(seq,
++                         "bootserver %u.%u.%u.%u\n",
++                         NIPQUAD(ic_servaddr));
++      return 0;
+ }
++static int pnp_seq_open(struct inode *indoe, struct file *file)
++{
++      return single_open(file, pnp_seq_show, NULL);
++}
++
++static struct file_operations pnp_seq_fops = {
++      .owner          = THIS_MODULE,
++      .open           = pnp_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = single_release,
++};
+ #endif /* CONFIG_PROC_FS */
+ /*
+@@ -1140,7 +1143,7 @@
+       unsigned long jiff;
+ #ifdef CONFIG_PROC_FS
+-      proc_net_create("pnp", 0, pnp_get_info);
++      proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
+ #endif /* CONFIG_PROC_FS */
+       if (!ic_enable)
+@@ -1153,7 +1156,7 @@
+       /* Give hardware a chance to settle */
+       jiff = jiffies + CONF_PRE_OPEN;
+       while (time_before(jiffies, jiff))
+-              ;
++              cpu_relax();
+       /* Setup all network devices */
+       if (ic_open_devs() < 0)
+@@ -1162,7 +1165,7 @@
+       /* Give drivers a chance to settle */
+       jiff = jiffies + CONF_POST_OPEN;
+       while (time_before(jiffies, jiff))
+-                      ;
++              cpu_relax();
+       /*
+        * If the config information is insufficient (e.g., our IP address or
+Index: linux-2.6.0-test5/net/ipv4/ip_input.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ip_input.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ip_input.c      2003-09-27 11:38:41.758180176 +0800
+@@ -201,6 +201,7 @@
+ #ifdef CONFIG_NETFILTER_DEBUG
+       nf_debug_ip_local_deliver(skb);
++      skb->nf_debug = 0;
+ #endif /*CONFIG_NETFILTER_DEBUG*/
+       __skb_pull(skb, ihl);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_app.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_app.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_app.c        2003-09-27 11:38:41.762179568 +0800
+@@ -35,6 +35,7 @@
+ #include <asm/system.h>
+ #include <linux/stat.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <net/ip_vs.h>
+@@ -213,18 +214,14 @@
+  */
+ void unregister_ip_vs_app(struct ip_vs_app *app)
+ {
+-      struct ip_vs_app *inc;
+-      struct list_head *l = &app->incs_list;
++      struct ip_vs_app *inc, *nxt;
+       down(&__ip_vs_app_mutex);
+-      while (l->next != l) {
+-              inc = list_entry(l->next, struct ip_vs_app, a_list);
++      list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) {
+               ip_vs_app_inc_release(inc);
+       }
+-      list_del(&app->a_list);
+-
+       up(&__ip_vs_app_mutex);
+       /* decrease the module use count */
+@@ -238,13 +235,11 @@
+  */
+ struct ip_vs_app *ip_vs_app_get_by_name(char *appname)
+ {
+-      struct list_head *p;
+       struct ip_vs_app *app, *a = NULL;
+       down(&__ip_vs_app_mutex);
+-      list_for_each (p, &ip_vs_app_list) {
+-              app = list_entry(p, struct ip_vs_app, a_list);
++      list_for_each_entry(ent, &ip_vs_app_list, a_list) {
+               if (strcmp(app->name, appname))
+                       continue;
+@@ -480,55 +475,99 @@
+ }
++#ifdef CONFIG_PROC_FS
+ /*
+  *    /proc/net/ip_vs_app entry function
+  */
+-static int
+-ip_vs_app_getinfo(char *buffer, char **start, off_t offset, int length)
++
++static struct ip_vs_app *ip_vs_app_idx(loff_t pos)
+ {
+-      off_t pos=0;
+-      int len=0;
+-      char temp[64];
+       struct ip_vs_app *app, *inc;
+-      struct list_head *e, *i;
+-      pos = 64;
+-      if (pos > offset) {
+-              len += sprintf(buffer+len, "%-63s\n",
+-                             "prot port    usecnt name");
++      list_for_each_entry(app, &ip_vs_app_list, a_list) {
++              list_for_each_entry(inc, &app->incs_list, a_list) {
++                      if (pos-- == 0)
++                              return inc;
++              }       
+       }
++      return NULL;
++}
++
++static void *ip_vs_app_seq_start(struct seq_file *seq, loff_t *pos)
++{
+       down(&__ip_vs_app_mutex);
+-      list_for_each (e, &ip_vs_app_list) {
+-              app = list_entry(e, struct ip_vs_app, a_list);
+-              list_for_each (i, &app->incs_list) {
+-                      inc = list_entry(i, struct ip_vs_app, a_list);
++      
++      return *pos ? ip_vs_app_idx(*pos - 1) : SEQ_START_TOKEN;
++}
++
++static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct ip_vs_app *inc, *app;
++      struct list_head *e;
++
++      ++*pos;
++      if (v == SEQ_START_TOKEN)
++              return ip_vs_app_idx(0);
++      
++      inc = v;
++      app = inc->app;
+-                      pos += 64;
+-                      if (pos <= offset)
+-                              continue;
+-                      sprintf(temp, "%-3s  %-7u %-6d %-17s",
+-                              ip_vs_proto_name(inc->protocol),
+-                              ntohs(inc->port),
+-                              atomic_read(&inc->usecnt),
+-                              inc->name);
+-                      len += sprintf(buffer+len, "%-63s\n", temp);
+-                      if (pos >= offset+length)
+-                              goto done;
++      if ((e = inc->a_list.next) != &app->incs_list)
++              return list_entry(e, struct ip_vs_app, a_list);
++
++      /* go on to next application */
++      for (e = app->a_list.next; e != &ip_vs_app_list; e = e->next) {
++              app = list_entry(e, struct ip_vs_app, a_list);
++              list_for_each_entry(inc, &app->incs_list, a_list) {
++                      return inc;
+               }
+       }
+-  done:
++      return NULL;
++}
++
++static void ip_vs_app_seq_stop(struct seq_file *seq, void *v)
++{
+       up(&__ip_vs_app_mutex);
++}
+-      *start = buffer+len-(pos-offset);       /* Start of wanted data */
+-      len = pos-offset;
+-      if (len > length)
+-              len = length;
+-      if (len < 0)
+-              len = 0;
+-      return len;
++static int ip_vs_app_seq_show(struct seq_file *seq, void *v)
++{
++      if (v == SEQ_START_TOKEN)
++              seq_puts(seq, "prot port    usecnt name\n");
++      else {
++              const struct ip_vs_app *inc = v;
++
++              seq_printf(seq, "%-3s  %-7u %-6d %-17s\n",
++                         ip_vs_proto_name(inc->protocol),
++                         ntohs(inc->port),
++                         atomic_read(&inc->usecnt),
++                         inc->name);
++      }
++      return 0;
+ }
++static struct seq_operations ip_vs_app_seq_ops = {
++      .start = ip_vs_app_seq_start,
++      .next  = ip_vs_app_seq_next,
++      .stop  = ip_vs_app_seq_stop,
++      .show  = ip_vs_app_seq_show,
++};
++
++static int ip_vs_app_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &ip_vs_app_seq_ops);
++}
++
++static struct file_operations ip_vs_app_fops = {
++      .owner   = THIS_MODULE,
++      .open    = ip_vs_app_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = seq_release,
++};
++#endif
++
+ /*
+  *    Replace a segment of data with a new segment
+@@ -577,7 +616,7 @@
+ int ip_vs_app_init(void)
+ {
+       /* we will replace it with proc_net_ipvs_create() soon */
+-      proc_net_create("ip_vs_app", 0, ip_vs_app_getinfo);
++      proc_net_fops_create("ip_vs_app", 0, &ip_vs_app_fops);
+       return 0;
+ }
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_conn.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_conn.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_conn.c       2003-09-27 11:38:41.769178504 +0800
+@@ -30,6 +30,7 @@
+ #include <linux/compiler.h>
+ #include <linux/vmalloc.h>
+ #include <linux/proc_fs.h>            /* for proc_net_* */
++#include <linux/seq_file.h>
+ #include <linux/jhash.h>
+ #include <linux/random.h>
+@@ -188,15 +189,12 @@
+ {
+       unsigned hash;
+       struct ip_vs_conn *cp;
+-      struct list_head *l,*e;
+       hash = ip_vs_conn_hashkey(protocol, s_addr, s_port);
+-      l = &ip_vs_conn_tab[hash];
+       ct_read_lock(hash);
+-      for (e=l->next; e!=l; e=e->next) {
+-              cp = list_entry(e, struct ip_vs_conn, c_list);
++      list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
+               if (s_addr==cp->caddr && s_port==cp->cport &&
+                   d_port==cp->vport && d_addr==cp->vaddr &&
+                   protocol==cp->protocol) {
+@@ -242,18 +240,15 @@
+ {
+       unsigned hash;
+       struct ip_vs_conn *cp, *ret=NULL;
+-      struct list_head *l,*e;
+       /*
+        *      Check for "full" addressed entries
+        */
+       hash = ip_vs_conn_hashkey(protocol, d_addr, d_port);
+-      l = &ip_vs_conn_tab[hash];
+       ct_read_lock(hash);
+-      for (e=l->next; e!=l; e=e->next) {
+-              cp = list_entry(e, struct ip_vs_conn, c_list);
++      list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
+               if (d_addr == cp->caddr && d_port == cp->cport &&
+                   s_port == cp->dport && s_addr == cp->daddr &&
+                   protocol == cp->protocol) {
+@@ -615,61 +610,112 @@
+ /*
+  *    /proc/net/ip_vs_conn entries
+  */
+-static int
+-ip_vs_conn_getinfo(char *buffer, char **start, off_t offset, int length)
++#ifdef CONFIG_PROC_FS
++
++static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
+ {
+-      off_t pos=0;
+-      int idx, len=0;
+-      char temp[70];
++      int idx;
+       struct ip_vs_conn *cp;
+-      struct list_head *l, *e;
+-
+-      pos = 128;
+-      if (pos > offset) {
+-              len += sprintf(buffer+len, "%-127s\n",
+-                             "Pro FromIP   FPrt ToIP     TPrt DestIP   DPrt State       Expires");
++      
++      for(idx = 0; idx < IP_VS_CONN_TAB_SIZE; idx++) {
++              ct_read_lock_bh(idx);
++              list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
++                      if (pos-- == 0) {
++                              seq->private = &ip_vs_conn_tab[idx];
++                              return cp;
++                      }
++              }
++              ct_read_unlock_bh(idx);
+       }
+-      for(idx = 0; idx < IP_VS_CONN_TAB_SIZE; idx++) {
+-              /*
+-               *      Lock is actually only need in next loop
+-               *      we are called from uspace: must stop bh.
+-               */
++      return NULL;
++}
++
++static void *ip_vs_conn_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      seq->private = NULL;
++      return *pos ? ip_vs_conn_array(seq, *pos - 1) :SEQ_START_TOKEN;
++}
++
++static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct ip_vs_conn *cp = v;
++      struct list_head *e, *l = seq->private;
++      int idx;
++
++      ++*pos;
++      if (v == SEQ_START_TOKEN) 
++              return ip_vs_conn_array(seq, 0);
++
++      /* more on same hash chain? */
++      if ((e = cp->c_list.next) != l)
++              return list_entry(e, struct ip_vs_conn, c_list);
++
++      idx = l - ip_vs_conn_tab;
++      ct_read_unlock_bh(idx);
++
++      while (++idx < IP_VS_CONN_TAB_SIZE) {
+               ct_read_lock_bh(idx);
++              list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
++                      seq->private = &ip_vs_conn_tab[idx];
++                      return cp;
++              }       
++              ct_read_unlock_bh(idx);
++      }
++      seq->private = NULL;
++      return NULL;
++}
+-              l = &ip_vs_conn_tab[idx];
+-              for (e=l->next; e!=l; e=e->next) {
+-                      cp = list_entry(e, struct ip_vs_conn, c_list);
+-                      pos += 128;
+-                      if (pos <= offset)
+-                              continue;
+-                      sprintf(temp,
+-                              "%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu",
++static void ip_vs_conn_seq_stop(struct seq_file *seq, void *v)
++{
++      struct list_head *l = seq->private;
++
++      if (l) 
++              ct_read_unlock(l - ip_vs_conn_tab);
++}
++
++static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
++{
++
++      if (v == SEQ_START_TOKEN)
++              seq_puts(seq,
++   "Pro FromIP   FPrt ToIP     TPrt DestIP   DPrt State       Expires\n");
++      else {
++              const struct ip_vs_conn *cp = v;
++
++              seq_printf(seq,
++                      "%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu\n",
+                               ip_vs_proto_name(cp->protocol),
+                               ntohl(cp->caddr), ntohs(cp->cport),
+                               ntohl(cp->vaddr), ntohs(cp->vport),
+                               ntohl(cp->daddr), ntohs(cp->dport),
+                               ip_vs_state_name(cp->protocol, cp->state),
+                               (cp->timer.expires-jiffies)/HZ);
+-                      len += sprintf(buffer+len, "%-127s\n", temp);
+-                      if (pos >= offset+length) {
+-                              ct_read_unlock_bh(idx);
+-                              goto done;
+-                      }
+-              }
+-              ct_read_unlock_bh(idx);
+       }
+-
+-  done:
+-      *start = buffer+len-(pos-offset);       /* Start of wanted data */
+-      len = pos-offset;
+-      if (len > length)
+-              len = length;
+-      if (len < 0)
+-              len = 0;
+-      return len;
++      return 0;
+ }
++static struct seq_operations ip_vs_conn_seq_ops = {
++      .start = ip_vs_conn_seq_start,
++      .next  = ip_vs_conn_seq_next,
++      .stop  = ip_vs_conn_seq_stop,
++      .show  = ip_vs_conn_seq_show,
++};
++
++static int ip_vs_conn_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &ip_vs_conn_seq_ops);
++}
++
++static struct file_operations ip_vs_conn_fops = {
++      .owner   = THIS_MODULE,
++      .open    = ip_vs_conn_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = seq_release,
++};
++#endif
++
+ /*
+  *      Randomly drop connection entries before running out of memory
+@@ -687,7 +733,7 @@
+       /* if the conn entry hasn't lasted for 60 seconds, don't drop it.
+          This will leave enough time for normal connection to get
+          through. */
+-      if (cp->timeout+jiffies-cp->timer.expires < 60*HZ)
++      if (time_before(cp->timeout + jiffies, cp->timer.expires + 60*HZ))
+               return 0;
+       /* Don't drop the entry if its number of incoming packets is not
+@@ -707,7 +753,6 @@
+ {
+       int idx;
+       struct ip_vs_conn *cp;
+-      struct list_head *l,*e;
+       struct ip_vs_conn *ct;
+       /*
+@@ -721,9 +766,7 @@
+                */
+               ct_write_lock(hash);
+-              l = &ip_vs_conn_tab[hash];
+-              for (e=l->next; e!=l; e=e->next) {
+-                      cp = list_entry(e, struct ip_vs_conn, c_list);
++              list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
+                       if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT))
+                               /* connection template */
+                               continue;
+@@ -775,7 +818,6 @@
+ {
+       int idx;
+       struct ip_vs_conn *cp;
+-      struct list_head *l,*e;
+       struct ip_vs_conn *ct;
+   flush_again:
+@@ -785,9 +827,7 @@
+                */
+               ct_write_lock_bh(idx);
+-              l = &ip_vs_conn_tab[idx];
+-              for (e=l->next; e!=l; e=e->next) {
+-                      cp = list_entry(e, struct ip_vs_conn, c_list);
++              list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
+                       atomic_inc(&cp->refcnt);
+                       ct_write_unlock(idx);
+@@ -848,7 +888,7 @@
+               __ip_vs_conntbl_lock_array[idx].l = RW_LOCK_UNLOCKED;
+       }
+-      proc_net_create("ip_vs_conn", 0, ip_vs_conn_getinfo);
++      proc_net_fops_create("ip_vs_conn", 0, &ip_vs_conn_fops);
+       /* calculate the random value for connection hash */
+       get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_ctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_ctl.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_ctl.c        2003-09-27 11:38:41.785176072 +0800
+@@ -31,6 +31,8 @@
+ #include <linux/proc_fs.h>
+ #include <linux/timer.h>
+ #include <linux/swap.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/netfilter.h>
+ #include <linux/netfilter_ipv4.h>
+@@ -46,7 +48,7 @@
+ static DECLARE_MUTEX(__ip_vs_mutex);
+ /* lock for service table */
+-rwlock_t __ip_vs_svc_lock = RW_LOCK_UNLOCKED;
++static rwlock_t __ip_vs_svc_lock = RW_LOCK_UNLOCKED;
+ /* lock for table with the real services */
+ static rwlock_t __ip_vs_rs_lock = RW_LOCK_UNLOCKED;
+@@ -361,14 +363,11 @@
+ {
+       unsigned hash;
+       struct ip_vs_service *svc;
+-      struct list_head *l,*e;
+       /* Check for "full" addressed entries */
+       hash = ip_vs_svc_hashkey(protocol, vaddr, vport);
+-      l = &ip_vs_svc_table[hash];
+-      for (e=l->next; e!=l; e=e->next) {
+-              svc = list_entry(e, struct ip_vs_service, s_list);
++      list_for_each_entry(svc, &ip_vs_svc_table[hash], s_list){
+               if ((svc->addr == vaddr)
+                   && (svc->port == vport)
+                   && (svc->protocol == protocol)) {
+@@ -389,14 +388,11 @@
+ {
+       unsigned hash;
+       struct ip_vs_service *svc;
+-      struct list_head *l,*e;
+       /* Check for fwmark addressed entries */
+       hash = ip_vs_svc_fwm_hashkey(fwmark);
+-      l = &ip_vs_svc_fwm_table[hash];
+-      for (e=l->next; e!=l; e=e->next) {
+-              svc = list_entry(e, struct ip_vs_service, f_list);
++      list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) {
+               if (svc->fwmark == fwmark) {
+                       /* HIT */
+                       atomic_inc(&svc->usecnt);
+@@ -533,7 +529,6 @@
+ {
+       unsigned hash;
+       struct ip_vs_dest *dest;
+-      struct list_head *l,*e;
+       /*
+        *      Check for "full" addressed entries
+@@ -541,11 +536,8 @@
+        */
+       hash = ip_vs_rs_hashkey(daddr, dport);
+-      l = &ip_vs_rtable[hash];
+-
+       read_lock(&__ip_vs_rs_lock);
+-      for (e=l->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, d_list);
++      list_for_each_entry(dest, &ip_vs_rtable[hash], d_list) {
+               if ((dest->addr == daddr)
+                   && (dest->port == dport)
+                   && ((dest->protocol == protocol) ||
+@@ -567,14 +559,11 @@
+ ip_vs_lookup_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ {
+       struct ip_vs_dest *dest;
+-      struct list_head *l, *e;
+       /*
+        * Find the destination for the given service
+        */
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if ((dest->addr == daddr) && (dest->port == dport)) {
+                       /* HIT */
+                       return dest;
+@@ -598,16 +587,12 @@
+ static struct ip_vs_dest *
+ ip_vs_trash_get_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
+ {
+-      struct ip_vs_dest *dest;
+-      struct list_head *l, *e;
++      struct ip_vs_dest *dest, *nxt;
+       /*
+        * Find the destination in trash
+        */
+-      l = &ip_vs_dest_trash;
+-
+-      for (e=l->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
+               IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, "
+                         "refcnt=%d\n",
+                         dest->vfwmark,
+@@ -632,7 +617,6 @@
+                                 "from trash\n",
+                                 dest->vfwmark,
+                                 NIPQUAD(dest->addr), ntohs(dest->port));
+-                      e = e->prev;
+                       list_del(&dest->n_list);
+                       ip_vs_dst_reset(dest);
+                       __ip_vs_unbind_svc(dest);
+@@ -655,13 +639,9 @@
+  */
+ static void ip_vs_trash_cleanup(void)
+ {
+-      struct ip_vs_dest *dest;
+-      struct list_head *l;
+-
+-      l = &ip_vs_dest_trash;
++      struct ip_vs_dest *dest, *nxt;
+-      while (l->next != l) {
+-              dest = list_entry(l->next, struct ip_vs_dest, n_list);
++      list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
+               list_del(&dest->n_list);
+               ip_vs_dst_reset(dest);
+               __ip_vs_unbind_svc(dest);
+@@ -1196,8 +1176,7 @@
+  */
+ static void __ip_vs_del_service(struct ip_vs_service *svc)
+ {
+-      struct list_head *l;
+-      struct ip_vs_dest *dest;
++      struct ip_vs_dest *dest, *nxt;
+       struct ip_vs_scheduler *old_sched;
+       ip_vs_num_services--;
+@@ -1218,9 +1197,7 @@
+       /*
+        *    Unlink the whole destination list
+        */
+-      l = &svc->destinations;
+-      while (l->next != l) {
+-              dest = list_entry(l->next, struct ip_vs_dest, n_list);
++      list_for_each_entry_safe(dest, nxt, &svc->destinations, n_list) {
+               __ip_vs_unlink_dest(svc, dest, 0);
+               __ip_vs_del_dest(dest);
+       }
+@@ -1277,16 +1254,13 @@
+ static int ip_vs_flush(void)
+ {
+       int idx;
+-      struct ip_vs_service *svc;
+-      struct list_head *l;
++      struct ip_vs_service *svc, *nxt;
+       /*
+        * Flush the service table hashed by <protocol,addr,port>
+        */
+       for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              l = &ip_vs_svc_table[idx];
+-              while (l->next != l) {
+-                      svc = list_entry(l->next,struct ip_vs_service,s_list);
++              list_for_each_entry_safe(svc, nxt, &ip_vs_svc_table[idx], s_list) {
+                       write_lock_bh(&__ip_vs_svc_lock);
+                       ip_vs_svc_unhash(svc);
+                       /*
+@@ -1302,9 +1276,8 @@
+        * Flush the service table hashed by fwmark
+        */
+       for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              l = &ip_vs_svc_fwm_table[idx];
+-              while (l->next != l) {
+-                      svc = list_entry(l->next,struct ip_vs_service,f_list);
++              list_for_each_entry_safe(svc, nxt, 
++                                       &ip_vs_svc_fwm_table[idx], f_list) {
+                       write_lock_bh(&__ip_vs_svc_lock);
+                       ip_vs_svc_unhash(svc);
+                       /*
+@@ -1334,12 +1307,10 @@
+ static int ip_vs_zero_service(struct ip_vs_service *svc)
+ {
+-      struct list_head *l;
+       struct ip_vs_dest *dest;
+       write_lock_bh(&__ip_vs_svc_lock);
+-      list_for_each (l, &svc->destinations) {
+-              dest = list_entry(l, struct ip_vs_dest, n_list);
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               ip_vs_zero_stats(&dest->stats);
+       }
+       ip_vs_zero_stats(&svc->stats);
+@@ -1350,19 +1321,16 @@
+ static int ip_vs_zero_all(void)
+ {
+       int idx;
+-      struct list_head *l;
+       struct ip_vs_service *svc;
+       for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              list_for_each (l, &ip_vs_svc_table[idx]) {
+-                      svc = list_entry(l, struct ip_vs_service, s_list);
++              list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
+                       ip_vs_zero_service(svc);
+               }
+       }
+       for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              list_for_each (l, &ip_vs_svc_fwm_table[idx]) {
+-                      svc = list_entry(l, struct ip_vs_service, f_list);
++              list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
+                       ip_vs_zero_service(svc);
+               }
+       }
+@@ -1507,207 +1475,253 @@
+        {0}}
+ };
++#ifdef CONFIG_PROC_FS
++
++struct ip_vs_iter {
++      struct list_head *table;
++      int bucket;
++};
+ /*
+  *    Write the contents of the VS rule table to a PROCfs file.
+  *    (It is kept just for backward compatibility)
+  */
+-static inline char *ip_vs_fwd_name(unsigned flags)
++static inline const char *ip_vs_fwd_name(unsigned flags)
+ {
+-      char *fwd;
+-
+       switch (flags & IP_VS_CONN_F_FWD_MASK) {
+       case IP_VS_CONN_F_LOCALNODE:
+-              fwd = "Local";
+-              break;
++              return "Local";
+       case IP_VS_CONN_F_TUNNEL:
+-              fwd = "Tunnel";
+-              break;
++              return "Tunnel";
+       case IP_VS_CONN_F_DROUTE:
+-              fwd = "Route";
+-              break;
++              return "Route";
+       default:
+-              fwd = "Masq";
++              return "Masq";
+       }
+-      return fwd;
+ }
+-static inline int sprintf_dest(char *str, struct ip_vs_dest *dest)
+-{
+-      return sprintf(str, "  -> %08X:%04X      %-7s %-6d %-10d %-10d",
+-                     ntohl(dest->addr), ntohs(dest->port),
+-                     ip_vs_fwd_name(atomic_read(&dest->conn_flags)),
+-                     atomic_read(&dest->weight),
+-                     atomic_read(&dest->activeconns),
+-                     atomic_read(&dest->inactconns));
+-}
+-static int ip_vs_get_info(char *buf, char **start, off_t offset, int length)
++/* Get the Nth entry in the two lists */
++static struct ip_vs_service *ip_vs_info_array(struct seq_file *seq, loff_t pos)
+ {
+-      int len=0;
+-      off_t pos=0;
+-      char temp[64], temp2[32];
++      struct ip_vs_iter *iter = seq->private;
+       int idx;
+       struct ip_vs_service *svc;
+-      struct ip_vs_dest *dest;
+-      struct list_head *l, *e, *p, *q;
+-      /*
+-       * Note: since the length of the buffer is usually the multiple
+-       * of 512, it is good to use fixed record of the divisor of 512,
+-       * so that records won't be truncated at buffer boundary.
+-       */
+-      pos = 192;
+-      if (pos > offset) {
+-              sprintf(temp,
+-                      "IP Virtual Server version %d.%d.%d (size=%d)",
+-                      NVERSION(IP_VS_VERSION_CODE), IP_VS_CONN_TAB_SIZE);
+-              len += sprintf(buf+len, "%-63s\n", temp);
+-              len += sprintf(buf+len, "%-63s\n",
+-                             "Prot LocalAddress:Port Scheduler Flags");
+-              len += sprintf(buf+len, "%-63s\n",
+-                             "  -> RemoteAddress:Port Forward Weight ActiveConn InActConn");
+-      }
+-
+-      read_lock_bh(&__ip_vs_svc_lock);
+-
+-      /* print the service table hashed by <protocol,addr,port> */
++      /* look in hash by protocol */
+       for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              l = &ip_vs_svc_table[idx];
+-              for (e=l->next; e!=l; e=e->next) {
+-                      svc = list_entry(e, struct ip_vs_service, s_list);
+-                      pos += 64;
+-                      if (pos > offset) {
+-                              if (svc->flags & IP_VS_SVC_F_PERSISTENT)
+-                                      sprintf(temp2, "persistent %d %08X",
+-                                              svc->timeout,
+-                                              ntohl(svc->netmask));
+-                              else
+-                                      temp2[0] = '\0';
+-
+-                              sprintf(temp, "%s  %08X:%04X %s %s",
+-                                      ip_vs_proto_name(svc->protocol),
+-                                      ntohl(svc->addr),
+-                                      ntohs(svc->port),
+-                                      svc->scheduler->name, temp2);
+-                              len += sprintf(buf+len, "%-63s\n", temp);
+-                              if (len >= length)
+-                                      goto done;
+-                      }
+-
+-                      p = &svc->destinations;
+-                      for (q=p->next; q!=p; q=q->next) {
+-                              dest = list_entry(q, struct ip_vs_dest, n_list);
+-                              pos += 64;
+-                              if (pos <= offset)
+-                                      continue;
+-                              sprintf_dest(temp, dest);
+-                              len += sprintf(buf+len, "%-63s\n", temp);
+-                              if (len >= length)
+-                                      goto done;
++              list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
++                      if (pos-- == 0){
++                              iter->table = ip_vs_svc_table;
++                              iter->bucket = idx;
++                              return svc;
+                       }
+               }
+       }
+-      /* print the service table hashed by fwmark */
++      /* keep looking in fwmark */
+       for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              l = &ip_vs_svc_fwm_table[idx];
+-              for (e=l->next; e!=l; e=e->next) {
+-                      svc = list_entry(e, struct ip_vs_service, f_list);
+-                      pos += 64;
+-                      if (pos > offset) {
+-                              if (svc->flags & IP_VS_SVC_F_PERSISTENT)
+-                                      sprintf(temp2, "persistent %d %08X",
+-                                              svc->timeout,
+-                                              ntohl(svc->netmask));
+-                              else
+-                                      temp2[0] = '\0';
+-
+-                              sprintf(temp, "FWM  %08X %s %s",
+-                                      svc->fwmark,
+-                                      svc->scheduler->name, temp2);
+-                              len += sprintf(buf+len, "%-63s\n", temp);
+-                              if (len >= length)
+-                                      goto done;
++              list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
++                      if (pos-- == 0) {
++                              iter->table = ip_vs_svc_fwm_table;
++                              iter->bucket = idx;
++                              return svc;
+                       }
++              }
++      }
++
++      return NULL;
++}
+-                      p = &svc->destinations;
+-                      for (q=p->next; q!=p; q=q->next) {
+-                              dest = list_entry(q, struct ip_vs_dest, n_list);
+-                              pos += 64;
+-                              if (pos <= offset)
+-                                      continue;
+-                              sprintf_dest(temp, dest);
+-                              len += sprintf(buf+len, "%-63s\n", temp);
+-                              if (len >= length)
+-                                      goto done;
++static void *ip_vs_info_seq_start(struct seq_file *seq, loff_t *pos)
++{
++
++      read_lock_bh(&__ip_vs_svc_lock);
++      return *pos ? ip_vs_info_array(seq, *pos - 1) : SEQ_START_TOKEN;
++}
++
++
++static void *ip_vs_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct list_head *e;
++      struct ip_vs_iter *iter;
++      struct ip_vs_service *svc;
++
++      ++*pos;
++      if (v == SEQ_START_TOKEN)
++              return ip_vs_info_array(seq,0);
++      
++      svc = v;
++      iter = seq->private;
++      
++      if (iter->table == ip_vs_svc_table) {
++              /* next service in table hashed by protocol */
++              if ((e = svc->s_list.next) != &ip_vs_svc_table[iter->bucket])
++                      return list_entry(e, struct ip_vs_service, s_list);
++
++
++              while (++iter->bucket < IP_VS_SVC_TAB_SIZE) {
++                      list_for_each_entry(svc,&ip_vs_svc_table[iter->bucket],
++                                          s_list) {
++                              return svc;
+                       }
+               }
++
++              iter->table = ip_vs_svc_fwm_table;
++              iter->bucket = -1;
++              goto scan_fwmark;
+       }
+-  done:
++      /* next service in hashed by fwmark */
++      if ((e = svc->f_list.next) != &ip_vs_svc_fwm_table[iter->bucket])
++              return list_entry(e, struct ip_vs_service, f_list);
++
++ scan_fwmark:
++      while (++iter->bucket < IP_VS_SVC_TAB_SIZE) {
++              list_for_each_entry(svc, &ip_vs_svc_fwm_table[iter->bucket],
++                                  f_list) 
++                      return svc;
++      }
++
++      return NULL;
++}
++
++static void ip_vs_info_seq_stop(struct seq_file *seq, void *v)
++{
+       read_unlock_bh(&__ip_vs_svc_lock);
++}
++
+-      *start = buf+len-(pos-offset);          /* Start of wanted data */
+-      len = pos-offset;
+-      if (len > length)
+-              len = length;
+-      if (len < 0)
+-              len = 0;
+-      return len;
++static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
++{
++      if (v == SEQ_START_TOKEN) {
++              seq_printf(seq,
++                      "IP Virtual Server version %d.%d.%d (size=%d)\n",
++                      NVERSION(IP_VS_VERSION_CODE), IP_VS_CONN_TAB_SIZE);
++              seq_puts(seq,
++                       "Prot LocalAddress:Port Scheduler Flags\n");
++              seq_puts(seq,
++                       "  -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n");
++      } else {
++              const struct ip_vs_service *svc = v;
++              const struct ip_vs_iter *iter = seq->private;
++              const struct ip_vs_dest *dest;
++
++              if (iter->table == ip_vs_svc_table) 
++                      seq_printf(seq, "%s  %08X:%04X %s ",
++                                 ip_vs_proto_name(svc->protocol),
++                                 ntohl(svc->addr),
++                                 ntohs(svc->port),
++                                 svc->scheduler->name);
++              else
++                      seq_printf(seq, "FWM  %08X %s ",
++                                 svc->fwmark, svc->scheduler->name);
++
++              if (svc->flags & IP_VS_SVC_F_PERSISTENT)
++                      seq_printf(seq, "persistent %d %08X\n",
++                              svc->timeout,
++                              ntohl(svc->netmask));
++              else
++                      seq_putc(seq, '\n');
++
++              list_for_each_entry(dest, &svc->destinations, n_list) {
++                      seq_printf(seq, 
++                                 "  -> %08X:%04X      %-7s %-6d %-10d %-10d\n",
++                                 ntohl(dest->addr), ntohs(dest->port),
++                                 ip_vs_fwd_name(atomic_read(&dest->conn_flags)),
++                                 atomic_read(&dest->weight),
++                                 atomic_read(&dest->activeconns),
++                                 atomic_read(&dest->inactconns));
++              }
++      }
++      return 0;
+ }
++static struct seq_operations ip_vs_info_seq_ops = {
++      .start = ip_vs_info_seq_start,
++      .next  = ip_vs_info_seq_next,
++      .stop  = ip_vs_info_seq_stop,
++      .show  = ip_vs_info_seq_show,
++};
++
++static int ip_vs_info_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++      struct ip_vs_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
++
++      if (!s)
++              goto out;
++
++      rc = seq_open(file, &ip_vs_info_seq_ops);
++      if (rc)
++              goto out_kfree;
++
++      seq          = file->private_data;
++      seq->private = s;
++      memset(s, 0, sizeof(*s));
++out:
++      return rc;
++out_kfree:
++      kfree(s);
++      goto out;
++}
++
++static struct file_operations ip_vs_info_fops = {
++      .owner   = THIS_MODULE,
++      .open    = ip_vs_info_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = seq_release_private,
++};
++
++#endif
+ struct ip_vs_stats ip_vs_stats;
+-static int
+-ip_vs_stats_get_info(char *buf, char **start, off_t offset, int length)
++#ifdef CONFIG_PROC_FS
++static int ip_vs_stats_show(struct seq_file *seq, void *v)
+ {
+-      int len=0;
+-      off_t pos=0;
+-      char temp[64];
+-
+-      pos += 320;
+-      if (pos > offset) {
+-              len += sprintf(buf+len, "%-63s\n%-63s\n",
+-/*                              01234567 01234567 01234567 0123456701234567 0123456701234567 */
+-                             "   Total Incoming Outgoing         Incoming         Outgoing",
+-                             "   Conns  Packets  Packets            Bytes            Bytes");
+-
+-              spin_lock_bh(&ip_vs_stats.lock);
+-              sprintf(temp, "%8X %8X %8X %8X%08X %8X%08X",
+-                      ip_vs_stats.conns,
+-                      ip_vs_stats.inpkts,
+-                      ip_vs_stats.outpkts,
+-                      (__u32)(ip_vs_stats.inbytes>>32),
+-                      (__u32)ip_vs_stats.inbytes,
+-                      (__u32)(ip_vs_stats.outbytes>>32),
+-                      (__u32)ip_vs_stats.outbytes);
+-              len += sprintf(buf+len, "%-62s\n\n", temp);
+-
+-              len += sprintf(buf+len, "%-63s\n",
+-/*                              01234567 01234567 01234567 0123456701234567 0123456701234567 */
+-                             " Conns/s   Pkts/s   Pkts/s          Bytes/s          Bytes/s");
+-              sprintf(temp, "%8X %8X %8X %16X %16X",
++
++/*               01234567 01234567 01234567 0123456701234567 0123456701234567 */
++      seq_puts(seq,
++               "   Total Incoming Outgoing         Incoming         Outgoing\n");
++      seq_printf(seq,            
++                 "   Conns  Packets  Packets            Bytes            Bytes\n");
++
++      spin_lock_bh(&ip_vs_stats.lock);
++      seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", ip_vs_stats.conns,
++                 ip_vs_stats.inpkts, ip_vs_stats.outpkts,
++                 ip_vs_stats.inbytes, ip_vs_stats.outbytes);
++
++/*                 01234567 01234567 01234567 0123456701234567 0123456701234567 */
++      seq_puts(seq,
++                 " Conns/s   Pkts/s   Pkts/s          Bytes/s          Bytes/s\n");
++      seq_printf(seq,"%8X %8X %8X %16X %16X\n",
+                       ip_vs_stats.cps,
+                       ip_vs_stats.inpps,
+                       ip_vs_stats.outpps,
+                       ip_vs_stats.inbps,
+                       ip_vs_stats.outbps);
+-              len += sprintf(buf+len, "%-63s\n", temp);
++      spin_unlock_bh(&ip_vs_stats.lock);
+-              spin_unlock_bh(&ip_vs_stats.lock);
+-      }
++      return 0;
++}
+-      *start = buf+len-(pos-offset);          /* Start of wanted data */
+-      len = pos-offset;
+-      if (len > length)
+-              len = length;
+-      if (len < 0)
+-              len = 0;
+-      return len;
++static int ip_vs_stats_seq_open(struct inode *inode, struct file *file)
++{
++      return single_open(file, ip_vs_stats_show, NULL);
+ }
++static struct file_operations ip_vs_stats_fops = {
++      .owner = THIS_MODULE,
++      .open = ip_vs_stats_seq_open,
++      .read = seq_read,
++      .llseek = seq_lseek,
++      .release = single_release,
++};
++
++#endif
+ /*
+  *    Set timeout values for tcp tcpfin udp in the timeout_table.
+@@ -1912,19 +1926,17 @@
+ static inline int
+ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
+-                          struct ip_vs_get_services *uptr)
++                          struct ip_vs_get_services __user *uptr)
+ {
+       int idx, count=0;
+       struct ip_vs_service *svc;
+-      struct list_head *l;
+       struct ip_vs_service_entry entry;
+       int ret = 0;
+       for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              list_for_each (l, &ip_vs_svc_table[idx]) {
++              list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
+                       if (count >= get->num_services)
+                               goto out;
+-                      svc = list_entry(l, struct ip_vs_service, s_list);
+                       ip_vs_copy_service(&entry, svc);
+                       if (copy_to_user(&uptr->entrytable[count],
+                                        &entry, sizeof(entry))) {
+@@ -1936,10 +1948,9 @@
+       }
+       for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+-              list_for_each (l, &ip_vs_svc_fwm_table[idx]) {
++              list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
+                       if (count >= get->num_services)
+                               goto out;
+-                      svc = list_entry(l, struct ip_vs_service, f_list);
+                       ip_vs_copy_service(&entry, svc);
+                       if (copy_to_user(&uptr->entrytable[count],
+                                        &entry, sizeof(entry))) {
+@@ -1955,7 +1966,7 @@
+ static inline int
+ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get,
+-                       struct ip_vs_get_dests *uptr)
++                       struct ip_vs_get_dests __user *uptr)
+ {
+       struct ip_vs_service *svc;
+       int ret = 0;
+@@ -1968,14 +1979,12 @@
+       if (svc) {
+               int count = 0;
+               struct ip_vs_dest *dest;
+-              struct list_head *l, *e;
+               struct ip_vs_dest_entry entry;
+-              l = &svc->destinations;
+-              for (e=l->next; e!=l; e=e->next) {
++              list_for_each_entry(dest, &svc->destinations, n_list) {
+                       if (count >= get->num_dests)
+                               break;
+-                      dest = list_entry(e, struct ip_vs_dest, n_list);
++
+                       entry.addr = dest->addr;
+                       entry.port = dest->port;
+                       entry.conn_flags = atomic_read(&dest->conn_flags);
+@@ -2034,7 +2043,7 @@
+ };
+ static int
+-do_ip_vs_get_ctl(struct sock *sk, int cmd, void *user, int *len)
++do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+ {
+       unsigned char arg[128];
+       int ret = 0;
+@@ -2195,8 +2204,8 @@
+               return ret;
+       }
+-      proc_net_create("ip_vs", 0, ip_vs_get_info);
+-      proc_net_create("ip_vs_stats", 0, ip_vs_stats_get_info);
++      proc_net_fops_create("ip_vs", 0, &ip_vs_info_fops);
++      proc_net_fops_create("ip_vs_stats",0, &ip_vs_stats_fops);
+       ipv4_vs_table.sysctl_header =
+               register_sysctl_table(ipv4_vs_table.root_dir, 0);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_lblc.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblc.c       2003-09-27 11:38:41.790175312 +0800
+@@ -246,15 +246,12 @@
+ {
+       unsigned hash;
+       struct ip_vs_lblc_entry *en;
+-      struct list_head *l,*e;
+       hash = ip_vs_lblc_hashkey(addr);
+-      l = &tbl->bucket[hash];
+       read_lock(&tbl->lock);
+-      for (e=l->next; e!=l; e=e->next) {
+-              en = list_entry(e, struct ip_vs_lblc_entry, list);
++      list_for_each_entry(en, &tbl->bucket[hash], list) {
+               if (en->addr == addr) {
+                       /* HIT */
+                       read_unlock(&tbl->lock);
+@@ -274,14 +271,11 @@
+ static void ip_vs_lblc_flush(struct ip_vs_lblc_table *tbl)
+ {
+       int i;
+-      struct list_head *l;
+-      struct ip_vs_lblc_entry *en;
++      struct ip_vs_lblc_entry *en, *nxt;
+       for (i=0; i<IP_VS_LBLC_TAB_SIZE; i++) {
+               write_lock(&tbl->lock);
+-              for (l=&tbl->bucket[i]; l->next!=l; ) {
+-                      en = list_entry(l->next,
+-                                      struct ip_vs_lblc_entry, list);
++              list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) {
+                       ip_vs_lblc_free(en);
+                       atomic_dec(&tbl->entries);
+               }
+@@ -294,21 +288,17 @@
+ {
+       unsigned long now = jiffies;
+       int i, j;
+-      struct list_head *l, *e;
+-      struct ip_vs_lblc_entry *en;
++      struct ip_vs_lblc_entry *en, *nxt;
+       for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
+               j = (j + 1) & IP_VS_LBLC_TAB_MASK;
+-              e = l = &tbl->bucket[j];
++
+               write_lock(&tbl->lock);
+-              while (e->next != l) {
+-                      en = list_entry(e->next,
+-                                      struct ip_vs_lblc_entry, list);
+-                      if ((now - en->lastuse) <
+-                          sysctl_ip_vs_lblc_expiration) {
+-                              e = e->next;
++              list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++                      if (time_before(now, 
++                                      en->lastuse + sysctl_ip_vs_lblc_expiration))
+                               continue;
+-                      }
++
+                       ip_vs_lblc_free(en);
+                       atomic_dec(&tbl->entries);
+               }
+@@ -335,8 +325,7 @@
+       unsigned long now = jiffies;
+       int goal;
+       int i, j;
+-      struct list_head *l, *e;
+-      struct ip_vs_lblc_entry *en;
++      struct ip_vs_lblc_entry *en, *nxt;
+       tbl = (struct ip_vs_lblc_table *)data;
+@@ -358,15 +347,12 @@
+       for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
+               j = (j + 1) & IP_VS_LBLC_TAB_MASK;
+-              e = l = &tbl->bucket[j];
++
+               write_lock(&tbl->lock);
+-              while (e->next != l) {
+-                      en = list_entry(e->next,
+-                                      struct ip_vs_lblc_entry, list);
+-                      if ((now - en->lastuse) < ENTRY_TIMEOUT) {
+-                              e = e->next;
++              list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++                      if (time_before(now, en->lastuse + ENTRY_TIMEOUT))
+                               continue;
+-                      }
++
+                       ip_vs_lblc_free(en);
+                       atomic_dec(&tbl->entries);
+                       goal--;
+@@ -452,7 +438,6 @@
+ static inline struct ip_vs_dest *
+ __ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-      register struct list_head *l, *e;
+       struct ip_vs_dest *dest, *least;
+       int loh, doh;
+@@ -473,10 +458,7 @@
+        * The server with weight=0 is quiesced and will not receive any
+        * new connection.
+        */
+-
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              least = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(least, &svc->destinations, n_list) {
+               if (least->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+               if (atomic_read(&least->weight) > 0) {
+@@ -491,9 +473,7 @@
+        *    Find the destination with the least load.
+        */
+   nextstage:
+-      for (e=e->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
+-
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+@@ -525,12 +505,9 @@
+ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
+ {
+       if (atomic_read(&dest->activeconns) > atomic_read(&dest->weight)) {
+-              register struct list_head *l, *e;
+               struct ip_vs_dest *d;
+-              l = &svc->destinations;
+-              for (e=l->next; e!=l; e=e->next) {
+-                      d = list_entry(e, struct ip_vs_dest, n_list);
++              list_for_each_entry(d, &svc->destinations, n_list) {
+                       if (atomic_read(&d->activeconns)*2
+                           < atomic_read(&d->weight)) {
+                               return 1;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblcr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_lblcr.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lblcr.c      2003-09-27 11:38:41.797174248 +0800
+@@ -432,15 +432,12 @@
+ {
+       unsigned hash;
+       struct ip_vs_lblcr_entry *en;
+-      struct list_head *l,*e;
+       hash = ip_vs_lblcr_hashkey(addr);
+-      l = &tbl->bucket[hash];
+       read_lock(&tbl->lock);
+-      for (e=l->next; e!=l; e=e->next) {
+-              en = list_entry(e, struct ip_vs_lblcr_entry, list);
++      list_for_each_entry(en, &tbl->bucket[hash], list) {
+               if (en->addr == addr) {
+                       /* HIT */
+                       read_unlock(&tbl->lock);
+@@ -460,14 +457,11 @@
+ static void ip_vs_lblcr_flush(struct ip_vs_lblcr_table *tbl)
+ {
+       int i;
+-      struct list_head *l;
+-      struct ip_vs_lblcr_entry *en;
++      struct ip_vs_lblcr_entry *en, *nxt;
+       for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+               write_lock(&tbl->lock);
+-              for (l=&tbl->bucket[i]; l->next!=l; ) {
+-                      en = list_entry(l->next,
+-                                      struct ip_vs_lblcr_entry, list);
++              list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) {
+                       ip_vs_lblcr_free(en);
+                       atomic_dec(&tbl->entries);
+               }
+@@ -480,21 +474,17 @@
+ {
+       unsigned long now = jiffies;
+       int i, j;
+-      struct list_head *l, *e;
+-      struct ip_vs_lblcr_entry *en;
++      struct ip_vs_lblcr_entry *en, *nxt;
+       for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+               j = (j + 1) & IP_VS_LBLCR_TAB_MASK;
+-              e = l = &tbl->bucket[j];
++
+               write_lock(&tbl->lock);
+-              while (e->next != l) {
+-                      en = list_entry(e->next,
+-                                      struct ip_vs_lblcr_entry, list);
+-                      if ((now - en->lastuse) <
+-                          sysctl_ip_vs_lblcr_expiration) {
+-                              e = e->next;
++              list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++                      if (time_after(en->lastuse+sysctl_ip_vs_lblcr_expiration,
++                                     now))
+                               continue;
+-                      }
++
+                       ip_vs_lblcr_free(en);
+                       atomic_dec(&tbl->entries);
+               }
+@@ -521,8 +511,7 @@
+       unsigned long now = jiffies;
+       int goal;
+       int i, j;
+-      struct list_head *l, *e;
+-      struct ip_vs_lblcr_entry *en;
++      struct ip_vs_lblcr_entry *en, *nxt;
+       tbl = (struct ip_vs_lblcr_table *)data;
+@@ -544,15 +533,12 @@
+       for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+               j = (j + 1) & IP_VS_LBLCR_TAB_MASK;
+-              e = l = &tbl->bucket[j];
++
+               write_lock(&tbl->lock);
+-              while (e->next != l) {
+-                      en = list_entry(e->next,
+-                                      struct ip_vs_lblcr_entry, list);
+-                      if ((now - en->lastuse) < ENTRY_TIMEOUT) {
+-                              e = e->next;
++              list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
++                      if (time_before(now, en->lastuse+ENTRY_TIMEOUT))
+                               continue;
+-                      }
++
+                       ip_vs_lblcr_free(en);
+                       atomic_dec(&tbl->entries);
+                       goal--;
+@@ -583,7 +569,6 @@
+       struct ip_vs_lblcr_table *tbl;
+       unsigned long now = jiffies;
+       int i;
+-      struct list_head *l, *e;
+       struct ip_vs_lblcr_entry *en;
+       tbl = lblcr_table_list;
+@@ -593,13 +578,11 @@
+       len += size;
+       for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) {
+-              l = &tbl->bucket[i];
+               read_lock_bh(&tbl->lock);
+-              for (e=l->next; e!=l; e=e->next) {
++              list_for_each_entry(en, &tbl->bucket[i], list) {
+                       char tbuf[16];
+                       struct ip_vs_dest_list *d;
+-                      en = list_entry(e, struct ip_vs_lblcr_entry, list);
+                       sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(en->addr));
+                       size = sprintf(buffer+len, "%8lu %-16s ",
+                                      now-en->lastuse, tbuf);
+@@ -708,7 +691,6 @@
+ static inline struct ip_vs_dest *
+ __ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-      register struct list_head *l, *e;
+       struct ip_vs_dest *dest, *least;
+       int loh, doh;
+@@ -729,10 +711,7 @@
+        * The server with weight=0 is quiesced and will not receive any
+        * new connection.
+        */
+-
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              least = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(least, &svc->destinations, n_list) {
+               if (least->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+@@ -748,8 +727,7 @@
+        *    Find the destination with the least load.
+        */
+   nextstage:
+-      for (e=e->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+@@ -781,12 +759,9 @@
+ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
+ {
+       if (atomic_read(&dest->activeconns) > atomic_read(&dest->weight)) {
+-              register struct list_head *l, *e;
+               struct ip_vs_dest *d;
+-              l = &svc->destinations;
+-              for (e=l->next; e!=l; e=e->next) {
+-                      d = list_entry(e, struct ip_vs_dest, n_list);
++              list_for_each_entry(d, &svc->destinations, n_list) {
+                       if (atomic_read(&d->activeconns)*2
+                           < atomic_read(&d->weight)) {
+                               return 1;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_lc.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_lc.c 2003-09-27 11:38:41.798174096 +0800
+@@ -65,7 +65,6 @@
+ static struct ip_vs_dest *
+ ip_vs_lc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-      struct list_head *l, *e;
+       struct ip_vs_dest *dest, *least;
+       unsigned int loh, doh;
+@@ -80,9 +79,7 @@
+        * served, but no new connection is assigned to the server.
+        */
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              least = list_entry (e, struct ip_vs_dest, n_list);
++      list_for_each_entry(least, &svc->destinations, n_list) {
+               if (least->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+               if (atomic_read(&least->weight) > 0) {
+@@ -96,8 +93,7 @@
+        *    Find the destination with the least load.
+        */
+   nextstage:
+-      for (e=e->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if ((dest->flags & IP_VS_DEST_F_OVERLOAD) ||
+                   atomic_read(&dest->weight) == 0)
+                       continue;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_nq.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_nq.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_nq.c 2003-09-27 11:38:41.801173640 +0800
+@@ -81,7 +81,6 @@
+ static struct ip_vs_dest *
+ ip_vs_nq_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-      register struct list_head *l, *e;
+       struct ip_vs_dest *dest, *least;
+       unsigned int loh, doh;
+@@ -100,9 +99,7 @@
+        * new connections.
+        */
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              least = list_entry(e, struct ip_vs_dest, n_list);
++      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);
+@@ -120,8 +117,7 @@
+        *    Find the destination with the least load.
+        */
+   nextstage:
+-      for (e=e->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_tcp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_proto_tcp.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_tcp.c  2003-09-27 11:38:41.805173032 +0800
+@@ -479,22 +479,19 @@
+ static int tcp_register_app(struct ip_vs_app *inc)
+ {
+       struct ip_vs_app *i;
+-      struct list_head *t, *p;
+       __u16 hash, port = inc->port;
+       int ret = 0;
+       hash = tcp_app_hashkey(port);
+-      t = &tcp_apps[hash];
+       spin_lock_bh(&tcp_app_lock);
+-      for (p = t->next; p != t; p = p->next) {
+-              i = list_entry(p, struct ip_vs_app, p_list);
++      list_for_each_entry(i, &tcp_apps[hash], p_list) {
+               if (i->port == port) {
+                       ret = -EEXIST;
+                       goto out;
+               }
+       }
+-      list_add(&inc->p_list, t);
++      list_add(&inc->p_list, &tcp_apps[hash]);
+       atomic_inc(&ip_vs_protocol_tcp.appcnt);
+   out:
+@@ -516,7 +513,6 @@
+ static int
+ tcp_app_conn_bind(struct ip_vs_conn *cp)
+ {
+-      struct list_head *t, *p;
+       int hash;
+       struct ip_vs_app *inc;
+       int result = 0;
+@@ -527,11 +523,9 @@
+       /* Lookup application incarnations and bind the right one */
+       hash = tcp_app_hashkey(cp->vport);
+-      t = &tcp_apps[hash];
+       spin_lock(&tcp_app_lock);
+-      for (p = t->next; p != t; p = p->next) {
+-              inc = list_entry(p, struct ip_vs_app, p_list);
++      list_for_each_entry(inc, &tcp_apps[hash], p_list) {
+               if (inc->port == cp->vport) {
+                       if (unlikely(!ip_vs_app_inc_get(inc)))
+                               break;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_udp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_proto_udp.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_proto_udp.c  2003-09-27 11:38:41.809172424 +0800
+@@ -245,22 +245,20 @@
+ static int udp_register_app(struct ip_vs_app *inc)
+ {
+       struct ip_vs_app *i;
+-      struct list_head *t, *p;
+       __u16 hash, port = inc->port;
+       int ret = 0;
+       hash = udp_app_hashkey(port);
+-      t = &udp_apps[hash];
++
+       spin_lock_bh(&udp_app_lock);
+-      for (p = t->next; p != t; p = p->next) {
+-              i = list_entry(p, struct ip_vs_app, p_list);
++      list_for_each_entry(i, &udp_apps[hash], p_list) {
+               if (i->port == port) {
+                       ret = -EEXIST;
+                       goto out;
+               }
+       }
+-      list_add(&inc->p_list, t);
++      list_add(&inc->p_list, &udp_apps[hash]);
+       atomic_inc(&ip_vs_protocol_udp.appcnt);
+   out:
+@@ -281,7 +279,6 @@
+ static int udp_app_conn_bind(struct ip_vs_conn *cp)
+ {
+-      struct list_head *t, *p;
+       int hash;
+       struct ip_vs_app *inc;
+       int result = 0;
+@@ -292,11 +289,9 @@
+       /* Lookup application incarnations and bind the right one */
+       hash = udp_app_hashkey(cp->vport);
+-      t = &udp_apps[hash];
+       spin_lock(&udp_app_lock);
+-      for (p = t->next; p != t; p = p->next) {
+-              inc = list_entry(p, struct ip_vs_app, p_list);
++      list_for_each_entry(inc, &udp_apps[hash], p_list) {
+               if (inc->port == cp->vport) {
+                       if (unlikely(!ip_vs_app_inc_get(inc)))
+                               break;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_rr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_rr.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_rr.c 2003-09-27 11:38:41.811172120 +0800
+@@ -57,7 +57,7 @@
+ static struct ip_vs_dest *
+ ip_vs_rr_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-      register struct list_head *p, *q;
++      struct list_head *p, *q;
+       struct ip_vs_dest *dest;
+       IP_VS_DBG(6, "ip_vs_rr_schedule(): Scheduling...\n");
+@@ -73,12 +73,12 @@
+                       continue;
+               }
+               
++      
+               dest = list_entry(q, struct ip_vs_dest, n_list);
+               if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
+                   atomic_read(&dest->weight) > 0)
+                       /* HIT */
+                       goto out;
+-              q = q->next;
+       } while (q != p);
+       write_unlock(&svc->sched_lock);
+       return NULL;
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sched.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_sched.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sched.c      2003-09-27 11:38:41.813171816 +0800
+@@ -106,18 +106,13 @@
+ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name)
+ {
+       struct ip_vs_scheduler *sched;
+-      struct list_head *l, *e;
+       IP_VS_DBG(2, "ip_vs_sched_getbyname(): sched_name \"%s\"\n",
+                 sched_name);
+-      l = &ip_vs_schedulers;
+-
+       read_lock_bh(&__ip_vs_sched_lock);
+-      for (e=l->next; e!=l; e=e->next) {
+-              sched = list_entry(e, struct ip_vs_scheduler, n_list);
+-
++      list_for_each_entry(sched, &ip_vs_schedulers, n_list) {
+               /*
+                * Test and get the modules atomically
+                */
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sed.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_sed.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sed.c        2003-09-27 11:38:41.816171360 +0800
+@@ -85,7 +85,6 @@
+ static struct ip_vs_dest *
+ ip_vs_sed_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-      register struct list_head *l, *e;
+       struct ip_vs_dest *dest, *least;
+       unsigned int loh, doh;
+@@ -104,9 +103,7 @@
+        * new connections.
+        */
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              least = list_entry(e, struct ip_vs_dest, n_list);
++      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_sed_dest_overhead(least);
+@@ -119,9 +116,7 @@
+        *    Find the destination with the least load.
+        */
+   nextstage:
+-      for (e=e->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
+-
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+               doh = ip_vs_sed_dest_overhead(dest);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sync.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_sync.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_sync.c       2003-09-27 11:38:41.822170448 +0800
+@@ -206,8 +206,8 @@
+       struct ip_vs_sync_buff *sb;
+       spin_lock_bh(&curr_sb_lock);
+-      if (curr_sb &&
+-          (jiffies - curr_sb->firstuse > time || time == 0)) {
++      if (curr_sb && (time == 0 ||
++                      time_before(jiffies - curr_sb->firstuse, time))) {
+               sb = curr_sb;
+               curr_sb = NULL;
+       } else
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wlc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_wlc.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wlc.c        2003-09-27 11:38:41.824170144 +0800
+@@ -73,7 +73,6 @@
+ static struct ip_vs_dest *
+ ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-      register struct list_head *l, *e;
+       struct ip_vs_dest *dest, *least;
+       unsigned int loh, doh;
+@@ -92,9 +91,7 @@
+        * new connections.
+        */
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              least = list_entry(e, struct ip_vs_dest, n_list);
++      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_wlc_dest_overhead(least);
+@@ -107,9 +104,7 @@
+        *    Find the destination with the least load.
+        */
+   nextstage:
+-      for (e=e->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
+-
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+                       continue;
+               doh = ip_vs_wlc_dest_overhead(dest);
+Index: linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wrr.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/ipvs/ip_vs_wrr.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/ipvs/ip_vs_wrr.c        2003-09-27 11:38:41.827169688 +0800
+@@ -56,25 +56,22 @@
+ static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc)
+ {
+-      register struct list_head *l, *e;
+       struct ip_vs_dest *dest;
+       int weight;
+       int g = 1;
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               weight = atomic_read(&dest->weight);
+               if (weight > 0) {
+                       g = weight;
+-                      break;
++                      goto search_gcd;
+               }
+       }
+-      if (e == l)
+-              return g;
+-      for (e=e->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      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);
+@@ -89,13 +86,10 @@
+  */
+ static int ip_vs_wrr_max_weight(struct ip_vs_service *svc)
+ {
+-      register struct list_head *l, *e;
+       struct ip_vs_dest *dest;
+       int weight = 0;
+-      l = &svc->destinations;
+-      for (e=l->next; e!=l; e=e->next) {
+-              dest = list_entry(e, struct ip_vs_dest, n_list);
++      list_for_each_entry(dest, &svc->destinations, n_list) {
+               if (atomic_read(&dest->weight) > weight)
+                       weight = atomic_read(&dest->weight);
+       }
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_amanda.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_amanda.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_amanda.c       2003-09-27 11:38:41.829169384 +0800
+@@ -101,7 +101,7 @@
+       struct ip_conntrack_expect *exp = expect;
+       struct ip_ct_amanda_expect *ct_amanda_info = &exp->help.exp_amanda_info;
+       struct ip_conntrack_tuple t = exp->tuple;
+-      int port;
++      u_int16_t port;
+       MUST_BE_LOCKED(&ip_amanda_lock);
+@@ -115,7 +115,7 @@
+          writable */
+       t.dst.ip = newip;
+-      for (port = ct_amanda_info->port + 10; port != 0; port++) {
++      for (port = ct_amanda_info->port; port != 0; port++) {
+               t.dst.u.tcp.port = htons(port);
+               if (ip_conntrack_change_expect(exp, &t) == 0)
+                       break;
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_irc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_irc.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_irc.c  2003-09-27 11:38:41.832168928 +0800
+@@ -99,7 +99,7 @@
+       struct ip_conntrack_tuple t;
+       struct iphdr *iph = (*pskb)->nh.iph;
+       struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
+-      int port;
++      u_int16_t port;
+       /* "4294967296 65635 " */
+       char buffer[18];
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_snmp_basic.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_snmp_basic.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_snmp_basic.c   2003-09-27 11:38:41.840167712 +0800
+@@ -51,9 +51,9 @@
+ #include <linux/netfilter_ipv4/ip_nat.h>
+ #include <linux/netfilter_ipv4/ip_nat_helper.h>
+ #include <linux/ip.h>
++#include <net/checksum.h>
+ #include <net/udp.h>
+ #include <asm/uaccess.h>
+-#include <asm/checksum.h>
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_tftp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ip_nat_tftp.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ip_nat_tftp.c 2003-09-27 11:38:41.842167408 +0800
+@@ -30,7 +30,7 @@
+ #include <linux/netfilter_ipv4/ip_nat_rule.h>
+ MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
+-MODULE_DESCRIPTION("tfpt NAT helper");
++MODULE_DESCRIPTION("tftp NAT helper");
+ MODULE_LICENSE("GPL");
+ #define MAX_PORTS 8
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ipt_MASQUERADE.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ipt_MASQUERADE.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ipt_MASQUERADE.c      2003-09-27 11:38:41.845166952 +0800
+@@ -130,57 +130,35 @@
+ }
+ static inline int
+-device_cmp(const struct ip_conntrack *i, void *ifindex)
++device_cmp(const struct ip_conntrack *i, void *_ina)
+ {
+-      int ret;
++      int ret = 0;
++      struct in_ifaddr *ina = _ina;
+       READ_LOCK(&masq_lock);
+-      ret = (i->nat.masq_index == (int)(long)ifindex);
++      /* If it's masquerading out this interface with a different address,
++         or we don't know the new address of this interface. */
++      if (i->nat.masq_index == ina->ifa_dev->dev->ifindex
++          && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address)
++              ret = 1;
+       READ_UNLOCK(&masq_lock);
+       return ret;
+ }
+-static int masq_device_event(struct notifier_block *this,
+-                           unsigned long event,
+-                           void *ptr)
+-{
+-      struct net_device *dev = ptr;
+-
+-      if (event == NETDEV_DOWN) {
+-              /* Device was downed.  Search entire table for
+-                 conntracks which were associated with that device,
+-                 and forget them. */
+-              IP_NF_ASSERT(dev->ifindex != 0);
+-
+-              ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+-      }
+-
+-      return NOTIFY_DONE;
+-}
+-
+ static int masq_inet_event(struct notifier_block *this,
+                          unsigned long event,
+                          void *ptr)
+ {
+-      struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+-
+-      if (event == NETDEV_DOWN) {
+-              /* IP address was deleted.  Search entire table for
+-                 conntracks which were associated with that device,
+-                 and forget them. */
+-              IP_NF_ASSERT(dev->ifindex != 0);
+-
+-              ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+-      }
++      /* For some configurations, interfaces often come back with
++       * the same address.  If not, clean up old conntrack
++       * entries. */
++      if (event == NETDEV_UP)
++              ip_ct_selective_cleanup(device_cmp, ptr);
+       return NOTIFY_DONE;
+ }
+-static struct notifier_block masq_dev_notifier = {
+-      .notifier_call  = masq_device_event,
+-};
+-
+ static struct notifier_block masq_inet_notifier = {
+       .notifier_call  = masq_inet_event,
+ };
+@@ -198,12 +176,9 @@
+       ret = ipt_register_target(&masquerade);
+-      if (ret == 0) {
+-              /* Register for device down reports */
+-              register_netdevice_notifier(&masq_dev_notifier);
++      if (ret == 0)
+               /* Register IP address change reports */
+               register_inetaddr_notifier(&masq_inet_notifier);
+-      }
+       return ret;
+ }
+@@ -211,7 +186,6 @@
+ static void __exit fini(void)
+ {
+       ipt_unregister_target(&masquerade);
+-      unregister_netdevice_notifier(&masq_dev_notifier);
+       unregister_inetaddr_notifier(&masq_inet_notifier);      
+ }
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ipt_physdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ipt_physdev.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ipt_physdev.c 2003-09-27 11:38:41.846166800 +0800
+@@ -23,7 +23,7 @@
+       int i;
+       static const char nulldevname[IFNAMSIZ];
+       const struct ipt_physdev_info *info = matchinfo;
+-      unsigned long ret;
++      unsigned int ret;
+       const char *indev, *outdev;
+       struct nf_bridge_info *nf_bridge;
+@@ -65,10 +65,10 @@
+       if (!(info->bitmask & IPT_PHYSDEV_OP_IN))
+               goto match_outdev;
+       indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
+-      for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+-              ret |= (((const unsigned long *)indev)[i]
+-                      ^ ((const unsigned long *)info->physindev)[i])
+-                      & ((const unsigned long *)info->in_mask)[i];
++      for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
++              ret |= (((const unsigned int *)indev)[i]
++                      ^ ((const unsigned int *)info->physindev)[i])
++                      & ((const unsigned int *)info->in_mask)[i];
+       }
+       if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN))
+@@ -79,10 +79,10 @@
+               return MATCH;
+       outdev = nf_bridge->physoutdev ?
+                nf_bridge->physoutdev->name : nulldevname;
+-      for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
+-              ret |= (((const unsigned long *)outdev)[i]
+-                      ^ ((const unsigned long *)info->physoutdev)[i])
+-                      & ((const unsigned long *)info->out_mask)[i];
++      for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
++              ret |= (((const unsigned int *)outdev)[i]
++                      ^ ((const unsigned int *)info->physoutdev)[i])
++                      & ((const unsigned int *)info->out_mask)[i];
+       }
+       return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT);
+Index: linux-2.6.0-test5/net/ipv4/netfilter/ipt_REJECT.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/netfilter/ipt_REJECT.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/netfilter/ipt_REJECT.c  2003-09-27 11:38:41.851166040 +0800
+@@ -84,45 +84,34 @@
+ static void send_reset(struct sk_buff *oldskb, int local)
+ {
+       struct sk_buff *nskb;
+-      struct tcphdr *otcph, *tcph;
++      struct tcphdr otcph, *tcph;
+       struct rtable *rt;
+-      unsigned int otcplen;
+       u_int16_t tmp_port;
+       u_int32_t tmp_addr;
+       int needs_ack;
+       int hh_len;
+-      /* IP header checks: fragment, too short. */
+-      if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
+-          || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
++      /* IP header checks: fragment. */
++      if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
+               return;
+-      otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
+-      otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
+-
+       if (skb_copy_bits(oldskb, oldskb->nh.iph->ihl*4,
+-                        otcph, sizeof(*otcph)) < 0)
+-              return;
++                        &otcph, sizeof(otcph)) < 0)
++              return;
+       /* No RST for RST. */
+-      if (otcph->rst)
+-              return;
+-
+-      /* Check checksum. */
+-      if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
+-                       oldskb->nh.iph->daddr,
+-                       csum_partial((char *)otcph, otcplen, 0)) != 0)
++      if (otcph.rst)
+               return;
++      /* FIXME: Check checksum --RR */
+       if ((rt = route_reverse(oldskb, local)) == NULL)
+               return;
+       hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
+-      /* Copy skb (even if skb is about to be dropped, we can't just
+-           clone it because there may be other things, such as tcpdump,
+-           interested in it). We also need to expand headroom in case
+-         hh_len of incoming interface < hh_len of outgoing interface */
++      /* We need a linear, writeable skb.  We also need to expand
++         headroom in case hh_len of incoming interface < hh_len of
++         outgoing interface */
+       nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
+                              GFP_ATOMIC);
+       if (!nskb) {
+@@ -163,12 +152,13 @@
+       if (tcph->ack) {
+               needs_ack = 0;
+-              tcph->seq = otcph->ack_seq;
++              tcph->seq = otcph.ack_seq;
+               tcph->ack_seq = 0;
+       } else {
+               needs_ack = 1;
+-              tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
+-                                    + otcplen - (otcph->doff<<2));
++              tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
++                                    + oldskb->len - oldskb->nh.iph->ihl*4
++                                    - (otcph.doff<<2));
+               tcph->seq = 0;
+       }
+Index: linux-2.6.0-test5/net/ipv4/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/proc.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/proc.c  2003-09-27 11:38:41.853165736 +0800
+@@ -238,28 +238,21 @@
+ int __init ip_misc_proc_init(void)
+ {
+       int rc = 0;
+-      struct proc_dir_entry *p;
+-      p = create_proc_entry("netstat", S_IRUGO, proc_net);
+-      if (!p)
++      if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops))
+               goto out_netstat;
+-      p->proc_fops = &netstat_seq_fops;
+-      p = create_proc_entry("snmp", S_IRUGO, proc_net);
+-      if (!p)
++      if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops))
+               goto out_snmp;
+-      p->proc_fops = &snmp_seq_fops;
+-      p = create_proc_entry("sockstat", S_IRUGO, proc_net);
+-      if (!p)
++      if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
+               goto out_sockstat;
+-      p->proc_fops = &sockstat_seq_fops;
+ out:
+       return rc;
+ out_sockstat:
+-      remove_proc_entry("snmp", proc_net);
++      proc_net_remove("snmp");
+ out_snmp:
+-      remove_proc_entry("netstat", proc_net);
++      proc_net_remove("netstat");
+ out_netstat:
+       rc = -ENOMEM;
+       goto out;
+Index: linux-2.6.0-test5/net/ipv4/raw.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/raw.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/raw.c   2003-09-27 11:38:41.859164824 +0800
+@@ -736,14 +736,14 @@
+ static void *raw_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&raw_v4_lock);
+-      return *pos ? raw_get_idx(seq, *pos) : (void *)1;
++      return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct sock *sk;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               sk = raw_get_first(seq);
+       else
+               sk = raw_get_next(seq, v);
+@@ -778,7 +778,7 @@
+ {
+       char tmpbuf[129];
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "%-127s\n",
+                              "  sl  local_address rem_address   st tx_queue "
+                              "rx_queue tr tm->when retrnsmt   uid  timeout "
+@@ -831,19 +831,13 @@
+ int __init raw_proc_init(void)
+ {
+-      struct proc_dir_entry *p;
+-      int rc = 0;
+-
+-      p = create_proc_entry("raw", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &raw_seq_fops;
+-      else
+-              rc = -ENOMEM;
+-      return rc;
++      if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops))
++              return -ENOMEM;
++      return 0;
+ }
+ void __init raw_proc_exit(void)
+ {
+-      remove_proc_entry("raw", proc_net);
++      proc_net_remove("raw");
+ }
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/ipv4/route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/route.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/route.c 2003-09-27 11:38:41.877162088 +0800
+@@ -259,14 +259,14 @@
+ static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+-      return *pos ? rt_cache_get_idx(seq, *pos) : (void *)1;
++      return *pos ? rt_cache_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct rtable *r = NULL;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               r = rt_cache_get_first(seq);
+       else
+               r = rt_cache_get_next(seq, v);
+@@ -276,13 +276,13 @@
+ static void rt_cache_seq_stop(struct seq_file *seq, void *v)
+ {
+-      if (v && v != (void *)1)
++      if (v && v != SEQ_START_TOKEN)
+               rcu_read_unlock();
+ }
+ static int rt_cache_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "%-127s\n",
+                          "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
+                          "Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
+Index: linux-2.6.0-test5/net/ipv4/tcp_diag.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/tcp_diag.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/tcp_diag.c      2003-09-27 11:38:41.882161328 +0800
+@@ -213,7 +213,7 @@
+                                 int dif);
+ #endif
+-static int tcpdiag_get_exact(struct sk_buff *in_skb, struct nlmsghdr *nlh)
++static int tcpdiag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh)
+ {
+       int err;
+       struct sock *sk;
+@@ -272,7 +272,7 @@
+       return err;
+ }
+-int bitstring_match(u32 *a1, u32 *a2, int bits)
++static int bitstring_match(const u32 *a1, const u32 *a2, int bits)
+ {
+       int words = bits >> 5;
+@@ -299,12 +299,12 @@
+ }
+-int tcpdiag_bc_run(char *bc, int len, struct sock *sk)
++static int tcpdiag_bc_run(const void *bc, int len, struct sock *sk)
+ {
+       while (len > 0) {
+               int yes = 1;
+               struct inet_opt *inet = inet_sk(sk);
+-              struct tcpdiag_bc_op *op = (struct tcpdiag_bc_op*)bc;
++              const struct tcpdiag_bc_op *op = bc;
+               switch (op->code) {
+               case TCPDIAG_BC_NOP:
+@@ -385,10 +385,10 @@
+       return (len == 0);
+ }
+-int valid_cc(char *bc, int len, int cc)
++static int valid_cc(const void *bc, int len, int cc)
+ {
+       while (len >= 0) {
+-              struct tcpdiag_bc_op *op = (struct tcpdiag_bc_op*)bc;
++              const struct tcpdiag_bc_op *op = bc;
+               if (cc > len)
+                       return 0;
+@@ -402,9 +402,9 @@
+       return 0;
+ }
+-int tcpdiag_bc_audit(char *bytecode, int bytecode_len)
++static int tcpdiag_bc_audit(const void *bytecode, int bytecode_len)
+ {
+-      char *bc = bytecode;
++      const unsigned char *bc = bytecode;
+       int  len = bytecode_len;
+       while (len > 0) {
+@@ -442,7 +442,7 @@
+ }
+-int tcpdiag_dump(struct sk_buff *skb, struct netlink_callback *cb)
++static int tcpdiag_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ {
+       int i, num;
+       int s_i, s_num;
+Index: linux-2.6.0-test5/net/ipv4/tcp_ipv4.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/tcp_ipv4.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/tcp_ipv4.c      2003-09-27 11:38:41.900158592 +0800
+@@ -2351,7 +2351,7 @@
+ static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+-      return *pos ? tcp_get_idx(seq, *pos - 1) : (void *)1;
++      return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -2359,7 +2359,7 @@
+       void *rc = NULL;
+       struct tcp_iter_state* st;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               rc = tcp_get_idx(seq, 0);
+               goto out;
+       }
+@@ -2397,7 +2397,7 @@
+                       read_unlock_bh(&tp->syn_wait_lock);
+               }
+       case TCP_SEQ_STATE_LISTENING:
+-              if (v != (void *)1)
++              if (v != SEQ_START_TOKEN)
+                       tcp_listen_unlock();
+               break;
+       case TCP_SEQ_STATE_TIME_WAIT:
+@@ -2413,11 +2413,15 @@
+ {
+       struct tcp_seq_afinfo *afinfo = PDE(inode)->data;
+       struct seq_file *seq;
+-      int rc = -ENOMEM;
+-      struct tcp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
++      struct tcp_iter_state *s;
++      int rc;
++      if (unlikely(afinfo == NULL))
++              return -EINVAL;
++
++      s = kmalloc(sizeof(*s), GFP_KERNEL);
+       if (!s)
+-              goto out;
++              return -ENOMEM;
+       memset(s, 0, sizeof(*s));
+       s->family               = afinfo->family;
+       s->seq_ops.start        = tcp_seq_start;
+@@ -2450,11 +2454,10 @@
+       afinfo->seq_fops->llseek        = seq_lseek;
+       afinfo->seq_fops->release       = seq_release_private;
+       
+-      p = create_proc_entry(afinfo->name, S_IRUGO, proc_net);
+-      if (p) {
++      p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
++      if (p)
+               p->data = afinfo;
+-              p->proc_fops = afinfo->seq_fops;
+-      } else
++      else
+               rc = -ENOMEM;
+       return rc;
+ }
+@@ -2463,7 +2466,7 @@
+ {
+       if (!afinfo)
+               return;
+-      remove_proc_entry(afinfo->name, proc_net);
++      proc_net_remove(afinfo->name);
+       memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); 
+ }
+@@ -2559,7 +2562,7 @@
+       struct tcp_iter_state* st;
+       char tmpbuf[TMPSZ + 1];
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, "%-*s\n", TMPSZ - 1,
+                          "  sl  local_address rem_address   st tx_queue "
+                          "rx_queue tr tm->when retrnsmt   uid  timeout "
+Index: linux-2.6.0-test5/net/ipv4/udp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv4/udp.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv4/udp.c   2003-09-27 11:38:41.910157072 +0800
+@@ -384,6 +384,7 @@
+       struct udp_opt *up = udp_sk(sk);
+       if (up->pending) {
++              up->len = 0;
+               up->pending = 0;
+               ip_flush_pending_frames(sk);
+       }
+@@ -1460,11 +1461,10 @@
+       afinfo->seq_fops->llseek        = seq_lseek;
+       afinfo->seq_fops->release       = seq_release_private;
+-      p = create_proc_entry(afinfo->name, S_IRUGO, proc_net);
+-      if (p) {
++      p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
++      if (p)
+               p->data = afinfo;
+-              p->proc_fops = afinfo->seq_fops;
+-      } else
++      else
+               rc = -ENOMEM;
+       return rc;
+ }
+@@ -1473,7 +1473,7 @@
+ {
+       if (!afinfo)
+               return;
+-      remove_proc_entry(afinfo->name, proc_net);
++      proc_net_remove(afinfo->name);
+       memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
+ }
+@@ -1497,7 +1497,7 @@
+ static int udp4_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "%-127s\n",
+                          "  sl  local_address rem_address   st tx_queue "
+                          "rx_queue tr tm->when retrnsmt   uid  timeout "
+Index: linux-2.6.0-test5/net/ipv6/addrconf.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/addrconf.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/addrconf.c      2003-09-27 11:38:41.929154184 +0800
+@@ -2149,59 +2149,65 @@
+       int bucket;
+ };
+-static inline struct inet6_ifaddr *if6_get_bucket(struct seq_file *seq, loff_t *pos)
++static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
+ {
+-      int i;
+       struct inet6_ifaddr *ifa = NULL;
+-      loff_t l = *pos;
+       struct if6_iter_state *state = seq->private;
+-      for (; state->bucket < IN6_ADDR_HSIZE; ++state->bucket)
+-              for (i = 0, ifa = inet6_addr_lst[state->bucket]; ifa; ++i, ifa=ifa->lst_next) {
+-                      if (l--)
+-                              continue;
+-                      *pos = i;
+-                      goto out;
+-              }
+-out:
++      for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
++              ifa = inet6_addr_lst[state->bucket];
++              if (ifa)
++                      break;
++      }
+       return ifa;
+ }
++static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa)
++{
++      struct if6_iter_state *state = seq->private;
++
++      ifa = ifa->lst_next;
++try_again:
++      if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) {
++              ifa = inet6_addr_lst[state->bucket];
++              goto try_again;
++      }
++      return ifa;
++}
++
++static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
++{
++      struct inet6_ifaddr *ifa = if6_get_first(seq);
++
++      if (ifa)
++              while(pos && (ifa = if6_get_next(seq, ifa)) != NULL)
++                      --pos;
++      return pos ? NULL : ifa;
++}
++
+ static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock_bh(&addrconf_hash_lock);
+-      return *pos ? if6_get_bucket(seq, pos) : (void *)1;
++      return if6_get_idx(seq, *pos);
+ }
+ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct inet6_ifaddr *ifa;
+-      struct if6_iter_state *state;
+-
+-      if (v == (void *)1) {
+-              ifa = if6_get_bucket(seq, pos);
+-              goto out;
+-      }
+-
+-      state = seq->private;
+-      ifa = v;
+-      ifa = ifa->lst_next;
+-      if (ifa)
+-              goto out;
+-
+-      if (++state->bucket >= IN6_ADDR_HSIZE)
+-              goto out;
+-
+-      *pos = 0;
+-      ifa = if6_get_bucket(seq, pos);
+-out:
++      ifa = if6_get_next(seq, v);
+       ++*pos;
+       return ifa;
+ }
+-static inline void if6_iface_seq_show(struct seq_file *seq, struct inet6_ifaddr *ifp)
++static void if6_seq_stop(struct seq_file *seq, void *v)
++{
++      read_unlock_bh(&addrconf_hash_lock);
++}
++
++static int if6_seq_show(struct seq_file *seq, void *v)
+ {
++      struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
+       seq_printf(seq,
+                  "%04x%04x%04x%04x%04x%04x%04x%04x %02x %02x %02x %02x %8s\n",
+                  NIP6(ifp->addr),
+@@ -2210,22 +2216,9 @@
+                  ifp->scope,
+                  ifp->flags,
+                  ifp->idev->dev->name);
+-}
+-
+-static int if6_seq_show(struct seq_file *seq, void *v)
+-{
+-      if (v == (void *)1)
+-              return 0;
+-      else
+-              if6_iface_seq_show(seq, v);
+       return 0;
+ }
+-static void if6_seq_stop(struct seq_file *seq, void *v)
+-{
+-      read_unlock_bh(&addrconf_hash_lock);
+-}
+-
+ static struct seq_operations if6_seq_ops = {
+       .start  = if6_seq_start,
+       .next   = if6_seq_next,
+@@ -2266,16 +2259,11 @@
+ int __init if6_proc_init(void)
+ {
+-      struct proc_dir_entry *p;
+-      int rc = 0;
+-
+-      p = create_proc_entry("if_inet6", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &if6_fops;
+-      else
+-              rc = -ENOMEM;
+-      return rc;
++      if (!proc_net_fops_create("if_inet6", S_IRUGO, &if6_fops))
++              return -ENOMEM;
++      return 0;
+ }
++
+ void if6_proc_exit(void)
+ {
+       proc_net_remove("if_inet6");
+@@ -2529,7 +2517,109 @@
+       netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFADDR, GFP_ATOMIC);
+ }
++static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
++                              __s32 *array, int bytes)
++{
++      memset(array, 0, bytes);
++      array[DEVCONF_FORWARDING] = cnf->forwarding;
++      array[DEVCONF_HOPLIMIT] = cnf->hop_limit;
++      array[DEVCONF_MTU6] = cnf->mtu6;
++      array[DEVCONF_ACCEPT_RA] = cnf->accept_ra;
++      array[DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects;
++      array[DEVCONF_AUTOCONF] = cnf->autoconf;
++      array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
++      array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
++      array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval;
++      array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay;
++#ifdef CONFIG_IPV6_PRIVACY
++      array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
++      array[DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
++      array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft;
++      array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
++      array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
++#endif
++}
++
++static int inet6_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
++                          struct inet6_dev *idev,
++                          int type, u32 pid, u32 seq)
++{
++      __s32                   *array = NULL;
++      struct ifinfomsg        *r;
++      struct nlmsghdr         *nlh;
++      unsigned char           *b = skb->tail;
++      struct rtattr           *subattr;
++
++      nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r));
++      if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
++      r = NLMSG_DATA(nlh);
++      r->ifi_family = AF_INET6;
++      r->ifi_type = dev->type;
++      r->ifi_index = dev->ifindex;
++      r->ifi_flags = dev->flags;
++      r->ifi_change = 0;
++      if (!netif_running(dev) || !netif_carrier_ok(dev))
++              r->ifi_flags &= ~IFF_RUNNING;
++      else
++              r->ifi_flags |= IFF_RUNNING;
++
++      RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name);
++
++      subattr = (struct rtattr*)skb->tail;
++
++      RTA_PUT(skb, IFLA_PROTINFO, 0, NULL);
++
++      /* return the device flags */
++      RTA_PUT(skb, IFLA_INET6_FLAGS, sizeof(__u32), &idev->if_flags);
++
++      /* return the device sysctl params */
++      if ((array = kmalloc(DEVCONF_MAX * sizeof(*array), GFP_ATOMIC)) == NULL)
++              goto rtattr_failure;
++      ipv6_store_devconf(&idev->cnf, array, DEVCONF_MAX * sizeof(*array));
++      RTA_PUT(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(*array), array);
++
++      /* XXX - Statistics/MC not implemented */
++      subattr->rta_len = skb->tail - (u8*)subattr;
++
++      nlh->nlmsg_len = skb->tail - b;
++      kfree(array);
++      return skb->len;
++
++nlmsg_failure:
++rtattr_failure:
++      if (array)
++              kfree(array);
++      skb_trim(skb, b - skb->data);
++      return -1;
++}
++
++static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
++{
++      int idx, err;
++      int s_idx = cb->args[0];
++      struct net_device *dev;
++      struct inet6_dev *idev;
++
++      read_lock(&dev_base_lock);
++      for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
++              if (idx < s_idx)
++                      continue;
++              if ((idev = in6_dev_get(dev)) == NULL)
++                      continue;
++              err = inet6_fill_ifinfo(skb, dev, idev, RTM_NEWLINK,
++                              NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq);
++              in6_dev_put(idev);
++              if (err <= 0)
++                      break;
++      }
++      read_unlock(&dev_base_lock);
++      cb->args[0] = idx;
++
++      return skb->len;
++}
++
+ static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
++      [RTM_GETLINK - RTM_BASE] = { .dumpit    = inet6_dump_ifinfo, },
+       [RTM_NEWADDR - RTM_BASE] = { .doit      = inet6_rtm_newaddr, },
+       [RTM_DELADDR - RTM_BASE] = { .doit      = inet6_rtm_deladdr, },
+       [RTM_GETADDR - RTM_BASE] = { .dumpit    = inet6_dump_ifaddr, },
+Index: linux-2.6.0-test5/net/ipv6/anycast.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/anycast.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/anycast.c       2003-09-27 11:38:41.934153424 +0800
+@@ -505,7 +505,7 @@
+ static void *ac6_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&dev_base_lock);
+-      return *pos ? ac6_get_idx(seq, *pos) : ac6_get_first(seq);
++      return ac6_get_idx(seq, *pos);
+ }
+ static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -581,11 +581,9 @@
+ int __init ac6_proc_init(void)
+ {
+-      struct proc_dir_entry *p;
++      if (!proc_net_fops_create("anycast6", S_IRUGO, &ac6_seq_fops))
++              return -ENOMEM;
+-      p = create_proc_entry("anycast6", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &ac6_seq_fops;
+       return 0;
+ }
+Index: linux-2.6.0-test5/net/ipv6/ip6_flowlabel.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/ip6_flowlabel.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/ip6_flowlabel.c 2003-09-27 11:38:41.938152816 +0800
+@@ -603,14 +603,14 @@
+ static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock_bh(&ip6_fl_lock);
+-      return *pos ? ip6fl_get_idx(seq, *pos) : (void *)1;
++      return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *ip6fl_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct ip6_flowlabel *fl;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               fl = ip6fl_get_first(seq);
+       else
+               fl = ip6fl_get_next(seq, v);
+@@ -644,7 +644,7 @@
+ static int ip6fl_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "Label S Owner  Users  Linger Expires  "
+                               "Dst                              Opt\n");
+       else
+@@ -695,12 +695,7 @@
+ void ip6_flowlabel_init()
+ {
+ #ifdef CONFIG_PROC_FS
+-      struct proc_dir_entry *p;
+-#endif
+-#ifdef CONFIG_PROC_FS
+-      p = create_proc_entry("ip6_flowlabel", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &ip6fl_seq_fops;
++      proc_net_fops_create("ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
+ #endif
+ }
+Index: linux-2.6.0-test5/net/ipv6/mcast.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/mcast.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/mcast.c 2003-09-27 11:38:41.954150384 +0800
+@@ -2119,7 +2119,7 @@
+ static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&dev_base_lock);
+-      return *pos ? igmp6_mc_get_idx(seq, *pos) : igmp6_mc_get_first(seq);
++      return igmp6_mc_get_idx(seq, *pos);
+ }
+ static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -2278,13 +2278,13 @@
+ static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&dev_base_lock);
+-      return *pos ? igmp6_mcf_get_idx(seq, *pos) : (void *)1;
++      return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct ip6_sf_list *psf;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               psf = igmp6_mcf_get_first(seq);
+       else
+               psf = igmp6_mcf_get_next(seq, v);
+@@ -2313,7 +2313,7 @@
+       struct ip6_sf_list *psf = (struct ip6_sf_list *)v;
+       struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, 
+                          "%3s %6s "
+                          "%32s %32s %6s %6s\n", "Idx",
+@@ -2378,9 +2378,6 @@
+       struct ipv6_pinfo *np;
+       struct sock *sk;
+       int err;
+-#ifdef CONFIG_PROC_FS
+-      struct proc_dir_entry *p;
+-#endif
+       err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket);
+       if (err < 0) {
+@@ -2399,12 +2396,8 @@
+       np->hop_limit = 1;
+ #ifdef CONFIG_PROC_FS
+-      p = create_proc_entry("igmp6", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &igmp6_mc_seq_fops;
+-      p = create_proc_entry("mcfilter6", S_IRUGO, proc_net);
+-      if (p)
+-              p->proc_fops = &igmp6_mcf_seq_fops;
++      proc_net_fops_create("igmp6", S_IRUGO, &igmp6_mc_seq_fops);
++      proc_net_fops_create("mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops);
+ #endif
+       return 0;
+@@ -2414,6 +2407,7 @@
+ {
+       sock_release(igmp6_socket);
+       igmp6_socket = NULL; /* for safety */
++
+ #ifdef CONFIG_PROC_FS
+       proc_net_remove("mcfilter6");
+       proc_net_remove("igmp6");
+Index: linux-2.6.0-test5/net/ipv6/ndisc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/ndisc.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/ndisc.c 2003-09-27 11:38:41.965148712 +0800
+@@ -1044,6 +1044,17 @@
+               in6_dev->if_flags |= IF_RA_RCVD;
+       }
++      /*
++       * Remember the managed/otherconf flags from most recently
++       * received RA message (RFC 2462) -- yoshfuji
++       */
++      in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
++                              IF_RA_OTHERCONF)) |
++                              (ra_msg->icmph.icmp6_addrconf_managed ?
++                                      IF_RA_MANAGED : 0) |
++                              (ra_msg->icmph.icmp6_addrconf_other ?
++                                      IF_RA_OTHERCONF : 0);
++
+       lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
+       rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
+Index: linux-2.6.0-test5/net/ipv6/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/proc.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/proc.c  2003-09-27 11:38:41.967148408 +0800
+@@ -32,7 +32,6 @@
+ #ifdef CONFIG_PROC_FS
+ static struct proc_dir_entry *proc_net_devsnmp6;
+-#endif
+ static int fold_prot_inuse(struct proto *proto)
+ {
+@@ -58,7 +57,6 @@
+       return 0;
+ }
+-
+ struct snmp6_item
+ {
+       char *name;
+@@ -221,9 +219,7 @@
+ int snmp6_register_dev(struct inet6_dev *idev)
+ {
+       int err = -ENOMEM;
+-#ifdef CONFIG_PROC_FS
+       struct proc_dir_entry *p;
+-#endif
+       if (!idev || !idev->dev)
+               return -EINVAL;
+@@ -232,7 +228,6 @@
+                          __alignof__(struct icmpv6_mib)) < 0)
+               goto err_icmp;
+-#ifdef CONFIG_PROC_FS
+       if (!proc_net_devsnmp6) {
+               err = -ENOENT;
+               goto err_proc;
+@@ -244,27 +239,22 @@
+       p->proc_fops = &snmp6_seq_fops;
+       idev->stats.proc_dir_entry = p;
+-#endif
+       return 0;
+-#ifdef CONFIG_PROC_FS
+ err_proc:
+       snmp6_mib_free((void **)idev->stats.icmpv6);
+-#endif
+ err_icmp:
+       return err;
+ }
+ int snmp6_unregister_dev(struct inet6_dev *idev)
+ {
+-#ifdef CONFIG_PROC_FS
+       if (!proc_net_devsnmp6)
+               return -ENOENT;
+       if (!idev || !idev->stats.proc_dir_entry)
+               return -EINVAL;
+       remove_proc_entry(idev->stats.proc_dir_entry->name,
+                         proc_net_devsnmp6);
+-#endif
+       snmp6_mib_free((void **)idev->stats.icmpv6);
+       return 0;
+@@ -273,21 +263,16 @@
+ int __init ipv6_misc_proc_init(void)
+ {
+       int rc = 0;
+-      struct proc_dir_entry *p;
+-      p = create_proc_entry("snmp6", S_IRUGO, proc_net);
+-      if (!p)
++      if (!proc_net_fops_create("snmp6", S_IRUGO, &snmp6_seq_fops))
+               goto proc_snmp6_fail;
+-      else
+-              p->proc_fops = &snmp6_seq_fops;
++
+       proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net);
+       if (!proc_net_devsnmp6)
+               goto proc_dev_snmp6_fail;
+-      p = create_proc_entry("sockstat6", S_IRUGO, proc_net);
+-      if (!p)
++
++      if (!proc_net_fops_create("sockstat6", S_IRUGO, &sockstat6_seq_fops))
+               goto proc_sockstat6_fail;
+-      else
+-              p->proc_fops = &sockstat6_seq_fops;
+ out:
+       return rc;
+@@ -307,3 +292,31 @@
+       proc_net_remove("snmp6");
+ }
++#else /* CONFIG_PROC_FS */
++
++
++int snmp6_register_dev(struct inet6_dev *idev)
++{
++      int err = -ENOMEM;
++
++      if (!idev || !idev->dev)
++              return -EINVAL;
++
++      if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
++                         __alignof__(struct icmpv6_mib)) < 0)
++              goto err_icmp;
++
++      return 0;
++
++err_icmp:
++      return err;
++}
++
++int snmp6_unregister_dev(struct inet6_dev *idev)
++{
++      snmp6_mib_free((void **)idev->stats.icmpv6);
++      return 0;
++}
++
++#endif
++
+Index: linux-2.6.0-test5/net/ipv6/raw.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/raw.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/raw.c   2003-09-27 11:38:41.975147192 +0800
+@@ -961,14 +961,14 @@
+ static void *raw6_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&raw_v6_lock);
+-      return *pos ? raw6_get_idx(seq, *pos) : (void *)1;
++      return *pos ? raw6_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *raw6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+       struct sock *sk;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               sk = raw6_get_first(seq);
+       else
+               sk = raw6_get_next(seq, v);
+@@ -1010,7 +1010,7 @@
+ static int raw6_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq,
+                          "  sl  "
+                          "local_address                         "
+@@ -1059,12 +1059,8 @@
+ int __init raw6_proc_init(void)
+ {
+-      struct proc_dir_entry *p = create_proc_entry("raw6", S_IRUGO, proc_net);
+-
+-      if (!p)
++      if (!proc_net_fops_create("raw6", S_IRUGO, &raw6_seq_fops))
+               return -ENOMEM;
+-      p->proc_fops = &raw6_seq_fops;
+-
+       return 0;
+ }
+Index: linux-2.6.0-test5/net/ipv6/tcp_ipv6.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/tcp_ipv6.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/tcp_ipv6.c      2003-09-27 11:38:41.989145064 +0800
+@@ -2023,11 +2023,12 @@
+                  atomic_read(&tw->tw_refcnt), tw);
+ }
++#ifdef CONFIG_PROC_FS
+ static int tcp6_seq_show(struct seq_file *seq, void *v)
+ {
+       struct tcp_iter_state *st;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_printf(seq,
+                          "  sl  "
+                          "local_address                         "
+@@ -2072,6 +2073,7 @@
+ {
+       tcp_proc_unregister(&tcp6_seq_afinfo);
+ }
++#endif
+ struct proto tcpv6_prot = {
+       .name           =       "TCPv6",
+Index: linux-2.6.0-test5/net/ipv6/udp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipv6/udp.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipv6/udp.c   2003-09-27 11:38:41.996144000 +0800
+@@ -704,6 +704,7 @@
+       struct udp_opt *up = udp_sk(sk);
+       if (up->pending) {
++              up->len = 0;
+               up->pending = 0;
+               ip6_flush_pending_frames(sk);
+         }
+@@ -1113,7 +1114,7 @@
+ static int udp6_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               seq_printf(seq,
+                          "  sl  "
+                          "local_address                         "
+Index: linux-2.6.0-test5/net/ipx/ipx_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/ipx/ipx_proc.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/ipx/ipx_proc.c       2003-09-27 11:38:42.000143392 +0800
+@@ -39,7 +39,7 @@
+       loff_t l = *pos;
+       spin_lock_bh(&ipx_interfaces_lock);
+-      return l ? ipx_get_interface_idx(--l) : (void *)1;
++      return l ? ipx_get_interface_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -47,7 +47,7 @@
+       struct ipx_interface *i;
+       ++*pos;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               i = ipx_interfaces_head();
+       else
+               i = ipx_interfaces_next(v);
+@@ -63,7 +63,7 @@
+ {
+       struct ipx_interface *i;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Network    Node_Address   Primary  Device     "
+                             "Frame_Type");
+ #ifdef IPX_REFCNT_DEBUG
+@@ -123,7 +123,7 @@
+ {
+       loff_t l = *pos;
+       read_lock_bh(&ipx_routes_lock);
+-      return l ? ipx_get_route_idx(--l) : (void *)1;
++      return l ? ipx_get_route_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -131,7 +131,7 @@
+       struct ipx_route *r;
+       ++*pos;
+-      if (v == (void *)1)
++      if (v == SEQ_START_TOKEN)
+               r = ipx_routes_head();
+       else
+               r = ipx_routes_next(v);
+@@ -147,7 +147,7 @@
+ {
+       struct ipx_route *rt;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Network    Router_Net   Router_Node\n");
+               goto out;
+       }
+@@ -195,7 +195,7 @@
+       loff_t l = *pos;
+       spin_lock_bh(&ipx_interfaces_lock);
+-      return l ? ipx_get_socket_idx(--l) : (void *)1;
++      return l ? ipx_get_socket_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -205,7 +205,7 @@
+       struct ipx_opt *ipxs;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               sk = NULL;
+               i = ipx_interfaces_head();
+               if (!i)
+@@ -245,7 +245,7 @@
+       struct sock *s;
+       struct ipx_opt *ipxs;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+ #ifdef CONFIG_IPX_INTERN
+               seq_puts(seq, "Local_Address               "
+                             "Remote_Address              Tx_Queue  "
+Index: linux-2.6.0-test5/net/irda/discovery.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/discovery.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/discovery.c     2003-09-27 11:38:42.004142784 +0800
+@@ -32,6 +32,7 @@
+ #include <linux/string.h>
+ #include <linux/socket.h>
++#include <linux/seq_file.h>
+ #include <net/irda/irda.h>
+ #include <net/irda/irlmp.h>
+@@ -349,70 +350,131 @@
+       return 0;
+ }
+-/*
+- * Function proc_discovery_read (buf, start, offset, len, unused)
+- *
+- *    Print discovery information in /proc file system
+- *
+- */
+-int discovery_proc_read(char *buf, char **start, off_t offset, int length, 
+-                      int unused)
+-{
+-      discovery_t *discovery;
++#ifdef CONFIG_PROC_FS
++struct discovery_iter_state {
+       unsigned long flags;
+-      hashbin_t *cachelog = irlmp->cachelog;
+-      int             len = 0;
++};
+-      if (!irlmp)
+-              return len;
++static inline discovery_t *discovery_seq_idx(loff_t pos)
+-      len = sprintf(buf, "IrLMP: Discovery log:\n\n");        
+-      
+-      spin_lock_irqsave(&cachelog->hb_spinlock, flags);
++{
++      discovery_t *discovery;
+-      discovery = (discovery_t *) hashbin_get_first(cachelog);
+-      while (( discovery != NULL) && (len < length)) {
+-              len += sprintf(buf+len, "nickname: %s,", discovery->data.info);
++      for (discovery = (discovery_t *) hashbin_get_first(irlmp->cachelog); 
++           discovery != NULL;
++           discovery = (discovery_t *) hashbin_get_next(irlmp->cachelog)) {
++              if (pos-- == 0)
++                      break;
++      }
+               
+-              len += sprintf(buf+len, " hint: 0x%02x%02x", 
+-                             discovery->data.hints[0], 
+-                             discovery->data.hints[1]);
++      return discovery;
++}
++
++static void *discovery_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct discovery_iter_state *iter = seq->private;
++
++      spin_lock_irqsave(&irlmp->cachelog->hb_spinlock, iter->flags);
++        return *pos ? discovery_seq_idx(*pos - 1) : SEQ_START_TOKEN;
++}
++
++static void *discovery_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      ++*pos;
++      return (v == SEQ_START_TOKEN) 
++              ? (void *) hashbin_get_first(irlmp->cachelog)
++              : (void *) hashbin_get_next(irlmp->cachelog);
++}
++
++static void discovery_seq_stop(struct seq_file *seq, void *v)
++{
++      struct discovery_iter_state *iter = seq->private;
++      spin_unlock_irqrestore(&irlmp->cachelog->hb_spinlock, iter->flags);
++}
++
++static int discovery_seq_show(struct seq_file *seq, void *v)
++{
++      if (v == SEQ_START_TOKEN)
++              seq_puts(seq, "IrLMP: Discovery log:\n\n");
++      else {
++              const discovery_t *discovery = v;
++
++              seq_printf(seq, "nickname: %s, hint: 0x%02x%02x", 
++                         discovery->data.info,
++                         discovery->data.hints[0], 
++                         discovery->data.hints[1]);
+ #if 0
+               if ( discovery->data.hints[0] & HINT_PNP)
+-                      len += sprintf( buf+len, "PnP Compatible ");
++                      seq_puts(seq, "PnP Compatible ");
+               if ( discovery->data.hints[0] & HINT_PDA)
+-                      len += sprintf( buf+len, "PDA/Palmtop ");
++                      seq_puts(seq, "PDA/Palmtop ");
+               if ( discovery->data.hints[0] & HINT_COMPUTER)
+-                      len += sprintf( buf+len, "Computer ");
++                      seq_puts(seq, "Computer ");
+               if ( discovery->data.hints[0] & HINT_PRINTER)
+-                      len += sprintf( buf+len, "Printer ");
++                      seq_puts(seq, "Printer ");
+               if ( discovery->data.hints[0] & HINT_MODEM)
+-                      len += sprintf( buf+len, "Modem ");
++                      seq_puts(seq, "Modem ");
+               if ( discovery->data.hints[0] & HINT_FAX)
+-                      len += sprintf( buf+len, "Fax ");
++                      seq_puts(seq, "Fax ");
+               if ( discovery->data.hints[0] & HINT_LAN)
+-                      len += sprintf( buf+len, "LAN Access ");
++                      seq_puts(seq, "LAN Access ");
+               
+               if ( discovery->data.hints[1] & HINT_TELEPHONY)
+-                      len += sprintf( buf+len, "Telephony ");
++                      seq_puts(seq, "Telephony ");
+               if ( discovery->data.hints[1] & HINT_FILE_SERVER)
+-                      len += sprintf( buf+len, "File Server ");       
++                      seq_puts(seq, "File Server ");       
+               if ( discovery->data.hints[1] & HINT_COMM)
+-                      len += sprintf( buf+len, "IrCOMM ");
++                      seq_puts(seq, "IrCOMM ");
+               if ( discovery->data.hints[1] & HINT_OBEX)
+-                      len += sprintf( buf+len, "IrOBEX ");
++                      seq_puts(seq, "IrOBEX ");
+ #endif                
+-              len += sprintf(buf+len, ", saddr: 0x%08x", 
+-                             discovery->data.saddr);
+-
+-              len += sprintf(buf+len, ", daddr: 0x%08x\n", 
++              seq_printf(seq,", saddr: 0x%08x, daddr: 0x%08x\n\n",
++                             discovery->data.saddr,
+                              discovery->data.daddr);
+               
+-              len += sprintf(buf+len, "\n");
+-              
+-              discovery = (discovery_t *) hashbin_get_next(cachelog);
++              seq_putc(seq, '\n');
+       }
+-      spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
++      return 0;
++}
+-      return len;
++static struct seq_operations discovery_seq_ops = {
++      .start  = discovery_seq_start,
++      .next   = discovery_seq_next,
++      .stop   = discovery_seq_stop,
++      .show   = discovery_seq_show,
++};
++
++static int discovery_seq_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++      struct discovery_iter_state *s;
++       
++      ASSERT(irlmp != NULL, return -EINVAL;);
++
++      s = kmalloc(sizeof(*s), GFP_KERNEL);
++      if (!s)
++              goto out;
++
++      rc = seq_open(file, &discovery_seq_ops);
++      if (rc)
++              goto out_kfree;
++
++      seq          = file->private_data;
++      seq->private = s;
++      memset(s, 0, sizeof(*s));
++out:
++      return rc;
++out_kfree:
++      kfree(s);
++      goto out;
+ }
++
++struct file_operations discovery_seq_fops = {
++      .owner          = THIS_MODULE,
++      .open           = discovery_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release_private,
++};
++#endif
+Index: linux-2.6.0-test5/net/irda/ircomm/ircomm_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/ircomm/ircomm_core.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/ircomm/ircomm_core.c    2003-09-27 11:38:42.009142024 +0800
+@@ -33,6 +33,7 @@
+ #include <linux/module.h>
+ #include <linux/sched.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/init.h>
+ #include <net/irda/irda.h>
+@@ -53,9 +54,16 @@
+                                     struct sk_buff *skb, int clen);
+ #ifdef CONFIG_PROC_FS
+-static int ircomm_proc_read(char *buf, char **start, off_t offset, int len);
+-
+ extern struct proc_dir_entry *proc_irda;
++static int ircomm_seq_open(struct inode *, struct file *);
++
++static struct file_operations ircomm_proc_fops = {
++      .owner          = THIS_MODULE,
++      .open           = ircomm_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release_private,
++};
+ #endif /* CONFIG_PROC_FS */
+ hashbin_t *ircomm = NULL;
+@@ -69,7 +77,11 @@
+       }
+       
+ #ifdef CONFIG_PROC_FS
+-      create_proc_info_entry("ircomm", 0, proc_irda, ircomm_proc_read);
++      { struct proc_dir_entry *ent;
++      ent = create_proc_entry("ircomm", 0, proc_irda);
++      if (ent) 
++              ent->proc_fops = &ircomm_proc_fops;
++      }
+ #endif /* CONFIG_PROC_FS */
+       
+       MESSAGE("IrCOMM protocol (Dag Brattli)\n");
+@@ -496,49 +508,98 @@
+ EXPORT_SYMBOL(ircomm_flow_request);
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function ircomm_proc_read (buf, start, offset, len, unused)
+- *
+- *    
+- *
+- */
+-int ircomm_proc_read(char *buf, char **start, off_t offset, int len)
+-{     
+-      struct ircomm_cb *self;
++struct ircomm_iter_state {
+       unsigned long flags;
+-      
+-      len = 0;
++};
++
++static void *ircomm_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct ircomm_iter_state *iter = seq->private;
++      struct ircomm_cb *self;
++      loff_t off = 0;
++
++      spin_lock_irqsave(&ircomm->hb_spinlock, iter->flags);
++
++      for (self = (struct ircomm_cb *) hashbin_get_first(ircomm);
++           self != NULL;
++           self = (struct ircomm_cb *) hashbin_get_next(ircomm)) {
++              if (off++ == *pos)
++                      break;
++              
++      }
++      return self;
++}
++
++static void *ircomm_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      ++*pos;
+-      spin_lock_irqsave(&ircomm->hb_spinlock, flags);
++      return (void *) hashbin_get_next(ircomm);
++}
++
++static void ircomm_seq_stop(struct seq_file *seq, void *v)
++{
++      struct ircomm_iter_state *iter = seq->private;
++      spin_unlock_irqrestore(&ircomm->hb_spinlock, iter->flags);
++}
+-      self = (struct ircomm_cb *) hashbin_get_first(ircomm);
+-      while (self != NULL) {
+-              ASSERT(self->magic == IRCOMM_MAGIC, break;);
+-
+-              if(self->line < 0x10)
+-                      len += sprintf(buf+len, "ircomm%d", self->line);
+-              else
+-                      len += sprintf(buf+len, "irlpt%d", self->line - 0x10);
+-              len += sprintf(buf+len, " state: %s, ",
+-                             ircomm_state[ self->state]);
+-              len += sprintf(buf+len, 
+-                             "slsap_sel: %#02x, dlsap_sel: %#02x, mode:",
+-                             self->slsap_sel, self->dlsap_sel); 
+-              if(self->service_type & IRCOMM_3_WIRE_RAW)
+-                      len += sprintf(buf+len, " 3-wire-raw");
+-              if(self->service_type & IRCOMM_3_WIRE)
+-                      len += sprintf(buf+len, " 3-wire");
+-              if(self->service_type & IRCOMM_9_WIRE)
+-                      len += sprintf(buf+len, " 9-wire");
+-              if(self->service_type & IRCOMM_CENTRONICS)
+-                      len += sprintf(buf+len, " Centronics");
+-              len += sprintf(buf+len, "\n");
+-
+-              self = (struct ircomm_cb *) hashbin_get_next(ircomm);
+-      } 
+-      spin_unlock_irqrestore(&ircomm->hb_spinlock, flags);
++static int ircomm_seq_show(struct seq_file *seq, void *v)
++{     
++      const struct ircomm_cb *self = v;
++
++      ASSERT(self->magic == IRCOMM_MAGIC, return -EINVAL; );
++
++      if(self->line < 0x10)
++              seq_printf(seq, "ircomm%d", self->line);
++      else
++              seq_printf(seq, "irlpt%d", self->line - 0x10);
++
++      seq_printf(seq,
++                 " state: %s, slsap_sel: %#02x, dlsap_sel: %#02x, mode:",
++                 ircomm_state[ self->state],
++                 self->slsap_sel, self->dlsap_sel); 
++
++      if(self->service_type & IRCOMM_3_WIRE_RAW)
++              seq_printf(seq, " 3-wire-raw");
++      if(self->service_type & IRCOMM_3_WIRE)
++              seq_printf(seq, " 3-wire");
++      if(self->service_type & IRCOMM_9_WIRE)
++              seq_printf(seq, " 9-wire");
++      if(self->service_type & IRCOMM_CENTRONICS)
++              seq_printf(seq, " Centronics");
++      seq_putc(seq, '\n');
++
++      return 0;
++}
++
++static struct seq_operations ircomm_seq_ops = {
++      .start  = ircomm_seq_start,
++      .next   = ircomm_seq_next,
++      .stop   = ircomm_seq_stop,
++      .show   = ircomm_seq_show,
++};
++
++static int ircomm_seq_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++      struct ircomm_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
++       
++      if (!s)
++              goto out;
+-      return len;
++      rc = seq_open(file, &ircomm_seq_ops);
++      if (rc)
++              goto out_kfree;
++
++      seq          = file->private_data;
++      seq->private = s;
++      memset(s, 0, sizeof(*s));
++out:
++      return rc;
++out_kfree:
++      kfree(s);
++      goto out;
+ }
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/irda/iriap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/iriap.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/iriap.c 2003-09-27 11:38:42.017140808 +0800
+@@ -29,6 +29,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/string.h>
+ #include <linux/init.h>
++#include <linux/seq_file.h>
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+@@ -970,35 +971,67 @@
+ #ifdef CONFIG_PROC_FS
+-static char *ias_value_types[] = {
++static const char *ias_value_types[] = {
+       "IAS_MISSING",
+       "IAS_INTEGER",
+       "IAS_OCT_SEQ",
+       "IAS_STRING"
+ };
+-int irias_proc_read(char *buf, char **start, off_t offset, int len)
++struct irias_iter_state {
++      unsigned long flags;
++};
++
++static inline struct ias_object *irias_seq_idx(loff_t pos) 
+ {
+       struct ias_object *obj;
+-      struct ias_attrib *attrib;
+-      unsigned long flags;
+-      ASSERT( irias_objects != NULL, return 0;);
++      for (obj = (struct ias_object *) hashbin_get_first(irias_objects);
++           obj; obj = (struct ias_object *) hashbin_get_next(irias_objects)) {
++              if (pos-- == 0)
++                      break;
++      }
++              
++      return obj;
++}
+-      len = 0;
++static void *irias_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct irias_iter_state *iter = seq->private;
+-      len += sprintf(buf+len, "LM-IAS Objects:\n");
++      spin_lock_irqsave(&irias_objects->hb_spinlock, iter->flags);
+-      spin_lock_irqsave(&irias_objects->hb_spinlock, flags);
++      return *pos ? irias_seq_idx(*pos - 1) : SEQ_START_TOKEN;
++}
++
++static void *irias_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      ++*pos;
++
++      return (v == SEQ_START_TOKEN) 
++              ? (void *) hashbin_get_first(irias_objects)
++              : (void *) hashbin_get_next(irias_objects);
++}
+-      /* List all irias_objects */
+-      obj = (struct ias_object *) hashbin_get_first(irias_objects);
+-      while ( obj != NULL) {
+-              ASSERT(obj->magic == IAS_OBJECT_MAGIC, return 0;);
++static void irias_seq_stop(struct seq_file *seq, void *v)
++{
++      struct irias_iter_state *iter = seq->private;
+-              len += sprintf(buf+len, "name: %s, ", obj->name);
+-              len += sprintf(buf+len, "id=%d", obj->id);
+-              len += sprintf(buf+len, "\n");
++      spin_unlock_irqrestore(&irias_objects->hb_spinlock, iter->flags);
++}
++
++static int irias_seq_show(struct seq_file *seq, void *v)
++{
++      if (v == SEQ_START_TOKEN)
++              seq_puts(seq, "LM-IAS Objects:\n");
++      else {
++              struct ias_object *obj = v;
++              struct ias_attrib *attrib;
++
++              ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -EINVAL;);
++
++              seq_printf(seq, "name: %s, id=%d\n",
++                         obj->name, obj->id);
+               /* Careful for priority inversions here !
+                * All other uses of attrib spinlock are independent of
+@@ -1006,48 +1039,83 @@
+               spin_lock(&obj->attribs->hb_spinlock);
+               /* List all attributes for this object */
+-              attrib = (struct ias_attrib *)
+-                      hashbin_get_first(obj->attribs);
+-              while (attrib != NULL) {
+-                      ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return 0;);
+-
+-                      len += sprintf(buf+len, " - Attribute name: \"%s\", ",
+-                                     attrib->name);
+-                      len += sprintf(buf+len, "value[%s]: ",
+-                                     ias_value_types[attrib->value->type]);
++              for (attrib = (struct ias_attrib *) hashbin_get_first(obj->attribs);
++                   attrib != NULL;
++                   attrib = (struct ias_attrib *) hashbin_get_next(obj->attribs)) {
++                   
++                      ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, break; );
++
++                      seq_printf(seq, " - Attribute name: \"%s\", ",
++                                 attrib->name);
++                      seq_printf(seq, "value[%s]: ",
++                                 ias_value_types[attrib->value->type]);
+                       switch (attrib->value->type) {
+                       case IAS_INTEGER:
+-                              len += sprintf(buf+len, "%d\n",
+-                                             attrib->value->t.integer);
++                              seq_printf(seq, "%d\n",
++                                         attrib->value->t.integer);
+                               break;
+                       case IAS_STRING:
+-                              len += sprintf(buf+len, "\"%s\"\n",
+-                                             attrib->value->t.string);
++                              seq_printf(seq, "\"%s\"\n",
++                                         attrib->value->t.string);
+                               break;
+                       case IAS_OCT_SEQ:
+-                              len += sprintf(buf+len, "octet sequence (%d bytes)\n", attrib->value->len);
++                              seq_printf(seq, "octet sequence (%d bytes)\n", 
++                                         attrib->value->len);
+                               break;
+                       case IAS_MISSING:
+-                              len += sprintf(buf+len, "missing\n");
++                              seq_puts(seq, "missing\n");
+                               break;
+                       default:
+-                              IRDA_DEBUG(0, "%s(), Unknown value type!\n",
+-                                         __FUNCTION__);
+-                              return -1;
++                              seq_printf(seq, "type %d?\n", 
++                                         attrib->value->type);
+                       }
+-                      len += sprintf(buf+len, "\n");
++                      seq_putc(seq, '\n');
+-                      attrib = (struct ias_attrib *)
+-                              hashbin_get_next(obj->attribs);
+               }
+               spin_unlock(&obj->attribs->hb_spinlock);
+-
+-              obj = (struct ias_object *) hashbin_get_next(irias_objects);
+       }
+-      spin_unlock_irqrestore(&irias_objects->hb_spinlock, flags);
+-      return len;
++      return 0;
++}
++
++static struct seq_operations irias_seq_ops = {
++      .start  = irias_seq_start,
++      .next   = irias_seq_next,
++      .stop   = irias_seq_stop,
++      .show   = irias_seq_show,
++};
++
++static int irias_seq_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++      struct irias_iter_state *s;
++
++      ASSERT( irias_objects != NULL, return -EINVAL;);
++      s = kmalloc(sizeof(*s), GFP_KERNEL);
++      if (!s)
++              goto out;
++
++      rc = seq_open(file, &irias_seq_ops);
++      if (rc)
++              goto out_kfree;
++      seq          = file->private_data;
++      seq->private = s;
++      memset(s, 0, sizeof(*s));
++out:
++      return rc;
++out_kfree:
++      kfree(s);
++      goto out;
+ }
++struct file_operations irias_seq_fops = {
++      .owner          = THIS_MODULE,
++      .open           = irias_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release_private,
++};
++
+ #endif /* PROC_FS */
+Index: linux-2.6.0-test5/net/irda/irlan/irlan_common.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlan/irlan_common.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlan/irlan_common.c    2003-09-27 11:38:42.025139592 +0800
+@@ -1068,7 +1068,6 @@
+ }
+ #ifdef CONFIG_PROC_FS
+-#define IRLAN_PROC_START_TOKEN        ((void *)1)
+ /*
+  * Start of reading /proc entries.
+@@ -1083,7 +1082,7 @@
+       rcu_read_lock();
+       if (*pos == 0)
+-              return IRLAN_PROC_START_TOKEN;
++              return SEQ_START_TOKEN;
+       list_for_each_entry(self, &irlans, dev_list) {
+               if (*pos == i) 
+@@ -1099,7 +1098,7 @@
+       struct list_head *nxt;
+       ++*pos;
+-      if (v == IRLAN_PROC_START_TOKEN) 
++      if (v == SEQ_START_TOKEN) 
+               nxt = irlans.next;
+       else
+               nxt = ((struct irlan_cb *)v)->dev_list.next;
+@@ -1120,7 +1119,7 @@
+  */
+ static int irlan_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == IRLAN_PROC_START_TOKEN)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "IrLAN instances:\n");
+       else {
+               struct irlan_cb *self = v;
+Index: linux-2.6.0-test5/net/irda/irlap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlap.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlap.c 2003-09-27 11:38:42.035138072 +0800
+@@ -37,6 +37,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/init.h>
+ #include <linux/random.h>
++#include <linux/seq_file.h>
+ #include <net/irda/irda.h>
+ #include <net/irda/irda_device.h>
+@@ -72,11 +73,6 @@
+ };
+ #endif        /* CONFIG_IRDA_DEBUG */
+-#ifdef CONFIG_PROC_FS
+-int irlap_proc_read(char *, char **, off_t, int);
+-
+-#endif /* CONFIG_PROC_FS */
+-
+ int __init irlap_init(void)
+ {
+       /* Check if the compiler did its job properly.
+@@ -1096,100 +1092,163 @@
+ }
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function irlap_proc_read (buf, start, offset, len, unused)
+- *
+- *    Give some info to the /proc file system
+- *
+- */
+-int irlap_proc_read(char *buf, char **start, off_t offset, int len)
++struct irlap_iter_state {
++      int id;
++      unsigned long flags;
++};
++
++static void *irlap_seq_start(struct seq_file *seq, loff_t *pos)
+ {
++      struct irlap_iter_state *iter = seq->private;
+       struct irlap_cb *self;
+-      unsigned long flags;
+-      int i = 0;
+-      spin_lock_irqsave(&irlap->hb_spinlock, flags);
++      /* Protect our access to the tsap list */
++      spin_lock_irqsave(&irlap->hb_spinlock, iter->flags);
++      iter->id = 0;
++
++      for (self = (struct irlap_cb *) hashbin_get_first(irlap); 
++           self; self = (struct irlap_cb *) hashbin_get_next(irlap)) {
++              if (iter->id == *pos)
++                      break;
++              ++iter->id;
++      }
++              
++      return self;
++}
++
++static void *irlap_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct irlap_iter_state *iter = seq->private;
++
++      ++*pos;
++      ++iter->id;
++      return (void *) hashbin_get_next(irlap);
++}
+-      len = 0;
++static void irlap_seq_stop(struct seq_file *seq, void *v)
++{
++      struct irlap_iter_state *iter = seq->private;
++      spin_unlock_irqrestore(&irlap->hb_spinlock, iter->flags);
++}
+-      self = (struct irlap_cb *) hashbin_get_first(irlap);
+-      while (self != NULL) {
+-              ASSERT(self != NULL, break;);
+-              ASSERT(self->magic == LAP_MAGIC, break;);
++static int irlap_seq_show(struct seq_file *seq, void *v)
++{
++      const struct irlap_iter_state *iter = seq->private;
++      const struct irlap_cb *self = v;
++      
++      ASSERT(self->magic == LAP_MAGIC, return -EINVAL;);
+-              len += sprintf(buf+len, "irlap%d ", i++);
+-              len += sprintf(buf+len, "state: %s\n",
+-                             irlap_state[self->state]);
++      seq_printf(seq, "irlap%d ", iter->id);
++      seq_printf(seq, "state: %s\n",
++                 irlap_state[self->state]);
+-              len += sprintf(buf+len, "  device name: %s, ",
+-                             (self->netdev) ? self->netdev->name : "bug");
+-              len += sprintf(buf+len, "hardware name: %s\n", self->hw_name);
++      seq_printf(seq, "  device name: %s, ",
++                 (self->netdev) ? self->netdev->name : "bug");
++      seq_printf(seq, "hardware name: %s\n", self->hw_name);
+-              len += sprintf(buf+len, "  caddr: %#02x, ", self->caddr);
+-              len += sprintf(buf+len, "saddr: %#08x, ", self->saddr);
+-              len += sprintf(buf+len, "daddr: %#08x\n", self->daddr);
++      seq_printf(seq, "  caddr: %#02x, ", self->caddr);
++      seq_printf(seq, "saddr: %#08x, ", self->saddr);
++      seq_printf(seq, "daddr: %#08x\n", self->daddr);
+-              len += sprintf(buf+len, "  win size: %d, ",
+-                             self->window_size);
+-              len += sprintf(buf+len, "win: %d, ", self->window);
++      seq_printf(seq, "  win size: %d, ",
++                 self->window_size);
++      seq_printf(seq, "win: %d, ", self->window);
+ #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
+-              len += sprintf(buf+len, "line capacity: %d, ",
+-                             self->line_capacity);
+-              len += sprintf(buf+len, "bytes left: %d\n", self->bytes_left);
++      seq_printf(seq, "line capacity: %d, ",
++                 self->line_capacity);
++      seq_printf(seq, "bytes left: %d\n", self->bytes_left);
+ #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
+-              len += sprintf(buf+len, "  tx queue len: %d ",
+-                             skb_queue_len(&self->txq));
+-              len += sprintf(buf+len, "win queue len: %d ",
+-                             skb_queue_len(&self->wx_list));
+-              len += sprintf(buf+len, "rbusy: %s", self->remote_busy ?
+-                             "TRUE" : "FALSE");
+-              len += sprintf(buf+len, " mbusy: %s\n", self->media_busy ?
+-                             "TRUE" : "FALSE");
+-
+-              len += sprintf(buf+len, "  retrans: %d ", self->retry_count);
+-              len += sprintf(buf+len, "vs: %d ", self->vs);
+-              len += sprintf(buf+len, "vr: %d ", self->vr);
+-              len += sprintf(buf+len, "va: %d\n", self->va);
+-
+-              len += sprintf(buf+len, "  qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
+-
+-              len += sprintf(buf+len, "  tx\t%d\t",
+-                             self->qos_tx.baud_rate.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_tx.max_turn_time.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_tx.data_size.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_tx.window_size.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_tx.additional_bofs.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_tx.min_turn_time.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_tx.link_disc_time.value);
+-              len += sprintf(buf+len, "\n");
+-
+-              len += sprintf(buf+len, "  rx\t%d\t",
+-                             self->qos_rx.baud_rate.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_rx.max_turn_time.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_rx.data_size.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_rx.window_size.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_rx.additional_bofs.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_rx.min_turn_time.value);
+-              len += sprintf(buf+len, "%d\t",
+-                             self->qos_rx.link_disc_time.value);
+-              len += sprintf(buf+len, "\n");
++      seq_printf(seq, "  tx queue len: %d ",
++                 skb_queue_len(&self->txq));
++      seq_printf(seq, "win queue len: %d ",
++                 skb_queue_len(&self->wx_list));
++      seq_printf(seq, "rbusy: %s", self->remote_busy ?
++                 "TRUE" : "FALSE");
++      seq_printf(seq, " mbusy: %s\n", self->media_busy ?
++                 "TRUE" : "FALSE");
++
++      seq_printf(seq, "  retrans: %d ", self->retry_count);
++      seq_printf(seq, "vs: %d ", self->vs);
++      seq_printf(seq, "vr: %d ", self->vr);
++      seq_printf(seq, "va: %d\n", self->va);
++
++      seq_printf(seq, "  qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
++
++      seq_printf(seq, "  tx\t%d\t",
++                 self->qos_tx.baud_rate.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_tx.max_turn_time.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_tx.data_size.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_tx.window_size.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_tx.additional_bofs.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_tx.min_turn_time.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_tx.link_disc_time.value);
++      seq_printf(seq, "\n");
++
++      seq_printf(seq, "  rx\t%d\t",
++                 self->qos_rx.baud_rate.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_rx.max_turn_time.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_rx.data_size.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_rx.window_size.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_rx.additional_bofs.value);
++      seq_printf(seq, "%d\t",
++                 self->qos_rx.min_turn_time.value);
++      seq_printf(seq, "%d\n",
++                 self->qos_rx.link_disc_time.value);
++
++      return 0;
++}
++
++static struct seq_operations irlap_seq_ops = {
++      .start  = irlap_seq_start,
++      .next   = irlap_seq_next,
++      .stop   = irlap_seq_stop,
++      .show   = irlap_seq_show,
++};
++
++static int irlap_seq_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++      struct irlap_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
++       
++      if (!s)
++              goto out;
+-              self = (struct irlap_cb *) hashbin_get_next(irlap);
++      if (irlap == NULL) {
++              rc = -EINVAL;
++              goto out_kfree;
+       }
+-      spin_unlock_irqrestore(&irlap->hb_spinlock, flags);
+-      return len;
+-}
++      rc = seq_open(file, &irlap_seq_ops);
++      if (rc)
++              goto out_kfree;
++
++      seq          = file->private_data;
++      seq->private = s;
++      memset(s, 0, sizeof(*s));
++out:
++      return rc;
++out_kfree:
++      kfree(s);
++      goto out;
++}
++
++struct file_operations irlap_seq_fops = {
++      .owner          = THIS_MODULE,
++      .open           = irlap_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release_private,
++};
+ #endif /* CONFIG_PROC_FS */
+Index: linux-2.6.0-test5/net/irda/irlap_frame.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlap_frame.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlap_frame.c   2003-09-27 11:38:42.044136704 +0800
+@@ -159,9 +159,9 @@
+ {
+       struct snrm_frame *frame;
+-      frame = (struct snrm_frame *) skb->data;
++      if (pskb_may_pull(skb,sizeof(struct snrm_frame))) {
++              frame = (struct snrm_frame *) skb->data;
+-      if (skb->len >= sizeof(struct snrm_frame)) {
+               /* Copy the new connection address ignoring the C/R bit */
+               info->caddr = frame->ncaddr & 0xFE;
+@@ -402,6 +402,11 @@
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
++      if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
++              ERROR("%s: frame to short!\n", __FUNCTION__);
++              return;
++      }
++              
+       xid = (struct xid_frame *) skb->data;
+       info->daddr = le32_to_cpu(xid->saddr);
+@@ -469,6 +474,11 @@
+       __u8 *discovery_info;
+       char *text;
++      if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
++              ERROR("%s: frame to short!\n", __FUNCTION__);
++              return;
++      }
++      
+       xid = (struct xid_frame *) skb->data;
+       info->daddr = le32_to_cpu(xid->saddr);
+@@ -507,7 +517,8 @@
+        */
+       if (info->s == 0xff) {
+               /* Check if things are sane at this point... */
+-              if((discovery_info == NULL) || (skb->len < 3)) {
++              if((discovery_info == NULL) || 
++                 !pskb_may_pull(skb, 3)) {
+                       ERROR("%s: discovery frame to short!\n", __FUNCTION__);
+                       return;
+               }
+@@ -1150,6 +1161,11 @@
+       ASSERT(skb != NULL, return;);
+       ASSERT(info != NULL, return;);
++      if (!pskb_may_pull(skb, 4)) {
++              ERROR("%s: frame to short!\n", __FUNCTION__);
++              return;
++      }
++
+       frame = skb->data;
+       info->nr = frame[2] >> 5;          /* Next to receive */
+@@ -1234,6 +1250,10 @@
+       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
++      if (!pskb_may_pull(skb, sizeof(*frame))) {
++              ERROR("%s: frame to short!\n", __FUNCTION__);
++              return;
++      }
+       frame = (struct test_frame *) skb->data;
+       /* Broadcast frames must carry saddr and daddr fields */
+@@ -1302,15 +1322,9 @@
+               dev_kfree_skb(skb);
+               return -1;
+       }
+-      if (skb_is_nonlinear(skb))
+-              if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+-                      ERROR("%s: can't linearize skb!\n", __FUNCTION__);
+-                      dev_kfree_skb(skb);
+-                      return -1;
+-              }
+       /* Check if frame is large enough for parsing */
+-      if (skb->len < 2) {
++      if (!pskb_may_pull(skb, 2)) {
+               ERROR("%s: frame to short!\n", __FUNCTION__);
+               dev_kfree_skb(skb);
+               return -1;
+Index: linux-2.6.0-test5/net/irda/irlmp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irlmp.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irlmp.c 2003-09-27 11:38:42.058134576 +0800
+@@ -33,6 +33,7 @@
+ #include <linux/init.h>
+ #include <linux/kmod.h>
+ #include <linux/random.h>
++#include <linux/seq_file.h>
+ #include <net/irda/irda.h>
+ #include <net/irda/timer.h>
+@@ -63,9 +64,6 @@
+ };
+ __u8 *irlmp_hint_to_service(__u8 *hint);
+-#ifdef CONFIG_PROC_FS
+-int irlmp_proc_read(char *buf, char **start, off_t offst, int len);
+-#endif
+ /*
+  * Function irlmp_init (void)
+@@ -1780,81 +1778,190 @@
+ }
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function irlmp_proc_read (buf, start, offset, len, unused)
+- *
+- *    Give some info to the /proc file system
+- *
+- */
+-int irlmp_proc_read(char *buf, char **start, off_t offset, int len)
+-{
+-      struct lsap_cb *self;
+-      struct lap_cb *lap;
++
++struct irlmp_iter_state {
+       unsigned long flags;
++      hashbin_t *hashbin;
++};
+-      ASSERT(irlmp != NULL, return 0;);
++#define LSAP_START_TOKEN      ((void *)1)
++#define LINK_START_TOKEN      ((void *)2)
+-      len = 0;
++static void *irlmp_seq_hb_idx(struct irlmp_iter_state *iter,
++                             hashbin_t *bin, loff_t *off)
++{
++      void *element;
+-      len += sprintf( buf+len, "Unconnected LSAPs:\n");
+-      spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
+-      self = (struct lsap_cb *) hashbin_get_first( irlmp->unconnected_lsaps);
+-      while (self != NULL) {
+-              ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
+-              len += sprintf(buf+len, "lsap state: %s, ",
+-                             irlsap_state[ self->lsap_state]);
+-              len += sprintf(buf+len,
+-                             "slsap_sel: %#02x, dlsap_sel: %#02x, ",
+-                             self->slsap_sel, self->dlsap_sel);
+-              len += sprintf(buf+len, "(%s)", self->notify.name);
+-              len += sprintf(buf+len, "\n");
++      spin_lock_irqsave(&bin->hb_spinlock, iter->flags);
++      for (element = hashbin_get_first(bin);
++           element != NULL; 
++           element = hashbin_get_next(bin)) {
++              if (!off || *off-- == 0) {
++                      /* NB: hashbin left locked */
++                      iter->hashbin = bin;
++                      return element;
++              }
++      }
++      spin_unlock_irqrestore(&bin->hb_spinlock, iter->flags);
++      return NULL;
++}
++
++
++static void *irlmp_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct irlmp_iter_state *iter = seq->private;
++      void *v;
++      loff_t off = *pos;
++
++      iter->hashbin = NULL;
++      if (off-- == 0)
++              return LSAP_START_TOKEN;
++
++      v = irlmp_seq_hb_idx(iter, irlmp->unconnected_lsaps, &off);
++      if (v)
++              return v;
+-              self = (struct lsap_cb *) hashbin_get_next(
+-                      irlmp->unconnected_lsaps);
++      if (off-- == 0)
++              return LINK_START_TOKEN;
++
++      return irlmp_seq_hb_idx(iter, irlmp->links, &off);
++}
++
++static void *irlmp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct irlmp_iter_state *iter = seq->private;
++
++      ++*pos;
++
++      if (v == LSAP_START_TOKEN) {
++              v = irlmp_seq_hb_idx(iter, irlmp->unconnected_lsaps, NULL);
++              return v ? v : LINK_START_TOKEN;
+       }
+-      spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
+-      len += sprintf(buf+len, "\nRegistred Link Layers:\n");
+-      spin_lock_irqsave(&irlmp->links->hb_spinlock, flags);
+-      lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
+-      while (lap != NULL) {
+-              len += sprintf(buf+len, "lap state: %s, ",
+-                             irlmp_state[lap->lap_state]);
++      if (v == LINK_START_TOKEN) 
++              return irlmp_seq_hb_idx(iter, irlmp->links, NULL);
++
++      ASSERT( iter->hashbin != NULL, return NULL; );
++
++      v = hashbin_get_next(iter->hashbin);
++      if (v)
++              return v;
++
++      spin_unlock_irqrestore(&iter->hashbin->hb_spinlock, iter->flags);
++
++      if (iter->hashbin == irlmp->unconnected_lsaps) {
++              iter->hashbin = NULL;
++              return LINK_START_TOKEN;
++      }
++      return NULL;
++}
++
++static void irlmp_seq_stop(struct seq_file *seq, void *v)
++{
++      struct irlmp_iter_state *iter = seq->private;
++      
++      if (iter->hashbin)
++              spin_unlock_irqrestore(&iter->hashbin->hb_spinlock, iter->flags);
++              
++}
++
++static int irlmp_seq_show(struct seq_file *seq, void *v)
++{
++      const struct irlmp_iter_state *iter = seq->private;
++      struct lsap_cb *self = v;
++
++      if (v == LSAP_START_TOKEN)
++              seq_puts(seq, "Unconnected LSAPs:\n");
++      else if (v == LINK_START_TOKEN)
++              seq_puts(seq, "\nRegistered Link Layers:\n");
++      else if (iter->hashbin == irlmp->unconnected_lsaps) {
++              self = v;
++              ASSERT(self->magic == LMP_LSAP_MAGIC, return -EINVAL; );
++              seq_printf(seq, "lsap state: %s, ",
++                         irlsap_state[ self->lsap_state]);
++              seq_printf(seq,
++                         "slsap_sel: %#02x, dlsap_sel: %#02x, ",
++                         self->slsap_sel, self->dlsap_sel);
++              seq_printf(seq, "(%s)", self->notify.name);
++              seq_printf(seq, "\n");
++      } else if (iter->hashbin == irlmp->links) {
++              struct lap_cb *lap = v;
+-              len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
+-                             lap->saddr, lap->daddr);
+-              len += sprintf(buf+len, "num lsaps: %d",
+-                             HASHBIN_GET_SIZE(lap->lsaps));
+-              len += sprintf(buf+len, "\n");
++              seq_printf(seq, "lap state: %s, ",
++                         irlmp_state[lap->lap_state]);
++
++              seq_printf(seq, "saddr: %#08x, daddr: %#08x, ",
++                         lap->saddr, lap->daddr);
++              seq_printf(seq, "num lsaps: %d",
++                         HASHBIN_GET_SIZE(lap->lsaps));
++              seq_printf(seq, "\n");
+               /* Careful for priority inversions here !
+                * All other uses of attrib spinlock are independent of
+                * the object spinlock, so we are safe. Jean II */
+               spin_lock(&lap->lsaps->hb_spinlock);
+-              len += sprintf(buf+len, "\n  Connected LSAPs:\n");
+-              self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
+-              while (self != NULL) {
++              seq_printf(seq, "\n  Connected LSAPs:\n");
++              for (self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
++                   self != NULL;
++                   self = (struct lsap_cb *)hashbin_get_next(lap->lsaps)) {
+                       ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
+-                      len += sprintf(buf+len, "  lsap state: %s, ",
+-                                     irlsap_state[ self->lsap_state]);
+-                      len += sprintf(buf+len,
+-                                     "slsap_sel: %#02x, dlsap_sel: %#02x, ",
+-                                     self->slsap_sel, self->dlsap_sel);
+-                      len += sprintf(buf+len, "(%s)", self->notify.name);
+-                      len += sprintf(buf+len, "\n");
++                      seq_printf(seq, "  lsap state: %s, ",
++                                 irlsap_state[ self->lsap_state]);
++                      seq_printf(seq,
++                                 "slsap_sel: %#02x, dlsap_sel: %#02x, ",
++                                 self->slsap_sel, self->dlsap_sel);
++                      seq_printf(seq, "(%s)", self->notify.name);
++                      seq_putc(seq, '\n');
+-                      self = (struct lsap_cb *) hashbin_get_next(
+-                              lap->lsaps);
+               }
+               spin_unlock(&lap->lsaps->hb_spinlock);
+-              len += sprintf(buf+len, "\n");
+-
+-              lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
+-      }
+-      spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
++              seq_putc(seq, '\n');
++      } else
++              return -EINVAL;
+-      return len;
++      return 0;
+ }
++static struct seq_operations irlmp_seq_ops = {
++      .start  = irlmp_seq_start,
++      .next   = irlmp_seq_next,
++      .stop   = irlmp_seq_stop,
++      .show   = irlmp_seq_show,
++};
++
++static int irlmp_seq_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++      struct irlmp_iter_state *s;
++
++      ASSERT(irlmp != NULL, return -EINVAL;);
++
++      s = kmalloc(sizeof(*s), GFP_KERNEL);
++      if (!s)
++              goto out;
++
++      rc = seq_open(file, &irlmp_seq_ops);
++      if (rc)
++              goto out_kfree;
++
++      seq          = file->private_data;
++      seq->private = s;
++      memset(s, 0, sizeof(*s));
++out:
++      return rc;
++out_kfree:
++      kfree(s);
++      goto out;
++}
++
++struct file_operations irlmp_seq_fops = {
++      .owner          = THIS_MODULE,
++      .open           = irlmp_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release_private,
++};
++
+ #endif /* PROC_FS */
+Index: linux-2.6.0-test5/net/irda/irproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irproc.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irproc.c        2003-09-27 11:38:42.060134272 +0800
+@@ -25,6 +25,7 @@
+ #include <linux/miscdevice.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -32,25 +33,25 @@
+ #include <net/irda/irlap.h>
+ #include <net/irda/irlmp.h>
+-extern int irlap_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int irlmp_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int irttp_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int irias_proc_read(char *buf, char **start, off_t offset, int len);
+-extern int discovery_proc_read(char *buf, char **start, off_t offset, int len);
++extern struct file_operations discovery_seq_fops;
++extern struct file_operations irlap_seq_fops;
++extern struct file_operations irlmp_seq_fops;
++extern struct file_operations irttp_seq_fops;
++extern struct file_operations irias_seq_fops;
+ struct irda_entry {
+-      char *name;
+-      int (*fn)(char*, char**, off_t, int);
++      const char *name;
++      struct file_operations *fops;
+ };
+ struct proc_dir_entry *proc_irda;
+  
+-static struct irda_entry dir[] = {
+-      {"discovery",   discovery_proc_read},
+-      {"irttp",       irttp_proc_read},
+-      {"irlmp",       irlmp_proc_read},
+-      {"irlap",       irlap_proc_read},
+-      {"irias",       irias_proc_read},
++static struct irda_entry irda_dirs[] = {
++      {"discovery",   &discovery_seq_fops},
++      {"irttp",       &irttp_seq_fops},
++      {"irlmp",       &irlmp_seq_fops},
++      {"irlap",       &irlap_seq_fops},
++      {"irias",       &irias_seq_fops},
+ };
+ /*
+@@ -64,15 +65,15 @@
+       int i;
+       struct proc_dir_entry *d;
+-      proc_irda = proc_mkdir("net/irda", NULL);
++      proc_irda = proc_mkdir("irda", proc_net);
+       if (proc_irda == NULL)
+               return;
+       proc_irda->owner = THIS_MODULE;
+-      for (i=0; i<ARRAY_SIZE(dir); i++) {
+-              d = create_proc_info_entry(dir[i].name,0,proc_irda,dir[i].fn);
+-              if (d)
+-                      d->owner = THIS_MODULE;
++      for (i=0; i<ARRAY_SIZE(irda_dirs); i++) {
++              d = create_proc_entry(irda_dirs[i].name, 0, proc_irda);
++              if (d) 
++                      d->proc_fops = irda_dirs[i].fops;
+       }
+ }
+@@ -87,10 +88,10 @@
+       int i;
+         if (proc_irda) {
+-                for (i=0; i<ARRAY_SIZE(dir); i++)
+-                        remove_proc_entry(dir[i].name, proc_irda);
++                for (i=0; i<ARRAY_SIZE(irda_dirs); i++)
++                        remove_proc_entry(irda_dirs[i].name, proc_irda);
+-                remove_proc_entry("net/irda", NULL);
++                remove_proc_entry("irda", proc_net);
+                 proc_irda = NULL;
+         }
+ }
+Index: linux-2.6.0-test5/net/irda/irttp.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/irda/irttp.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/irda/irttp.c 2003-09-27 11:38:42.074132144 +0800
+@@ -27,6 +27,7 @@
+ #include <linux/config.h>
+ #include <linux/skbuff.h>
+ #include <linux/init.h>
++#include <linux/seq_file.h>
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+@@ -1767,71 +1768,127 @@
+ }
+ #ifdef CONFIG_PROC_FS
+-/*
+- * Function irttp_proc_read (buf, start, offset, len, unused)
+- *
+- *    Give some info to the /proc file system
+- */
+-int irttp_proc_read(char *buf, char **start, off_t offset, int len)
+-{
+-      struct tsap_cb *self;
++struct irttp_iter_state {
++      int id;
+       unsigned long flags;
+-      int i = 0;
+-
+-      ASSERT(irttp != NULL, return 0;);
++};
+-      len = 0;
++static void *irttp_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct irttp_iter_state *iter = seq->private;
++      struct tsap_cb *self;
+       /* Protect our access to the tsap list */
+-      spin_lock_irqsave(&irttp->tsaps->hb_spinlock, flags);
++      spin_lock_irqsave(&irttp->tsaps->hb_spinlock, iter->flags);
++      iter->id = 0;
+-      self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps);
+-      while (self != NULL) {
+-              if (!self || self->magic != TTP_TSAP_MAGIC)
++      for (self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps); 
++           self != NULL;
++           self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps)) {
++              if (iter->id == *pos)
+                       break;
++              ++iter->id;
++      }
++              
++      return self;
++}
++
++static void *irttp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++{
++      struct irttp_iter_state *iter = seq->private;
+-              len += sprintf(buf+len, "TSAP %d, ", i++);
+-              len += sprintf(buf+len, "stsap_sel: %02x, ",
+-                             self->stsap_sel);
+-              len += sprintf(buf+len, "dtsap_sel: %02x\n",
+-                             self->dtsap_sel);
+-              len += sprintf(buf+len, "  connected: %s, ",
+-                             self->connected? "TRUE":"FALSE");
+-              len += sprintf(buf+len, "avail credit: %d, ",
+-                             self->avail_credit);
+-              len += sprintf(buf+len, "remote credit: %d, ",
+-                             self->remote_credit);
+-              len += sprintf(buf+len, "send credit: %d\n",
+-                             self->send_credit);
+-              len += sprintf(buf+len, "  tx packets: %ld, ",
+-                             self->stats.tx_packets);
+-              len += sprintf(buf+len, "rx packets: %ld, ",
+-                             self->stats.rx_packets);
+-              len += sprintf(buf+len, "tx_queue len: %d ",
+-                             skb_queue_len(&self->tx_queue));
+-              len += sprintf(buf+len, "rx_queue len: %d\n",
+-                             skb_queue_len(&self->rx_queue));
+-              len += sprintf(buf+len, "  tx_sdu_busy: %s, ",
+-                             self->tx_sdu_busy? "TRUE":"FALSE");
+-              len += sprintf(buf+len, "rx_sdu_busy: %s\n",
+-                             self->rx_sdu_busy? "TRUE":"FALSE");
+-              len += sprintf(buf+len, "  max_seg_size: %d, ",
+-                             self->max_seg_size);
+-              len += sprintf(buf+len, "tx_max_sdu_size: %d, ",
+-                             self->tx_max_sdu_size);
+-              len += sprintf(buf+len, "rx_max_sdu_size: %d\n",
+-                             self->rx_max_sdu_size);
++      ++*pos;
++      ++iter->id;
++      return (void *) hashbin_get_next(irttp->tsaps);
++}
+-              len += sprintf(buf+len, "  Used by (%s)\n",
+-                              self->notify.name);
++static void irttp_seq_stop(struct seq_file *seq, void *v)
++{
++      struct irttp_iter_state *iter = seq->private;
++      spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, iter->flags);
++}
+-              len += sprintf(buf+len, "\n");
++static int irttp_seq_show(struct seq_file *seq, void *v)
++{
++      const struct irttp_iter_state *iter = seq->private;
++      const struct tsap_cb *self = v;
+-              self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps);
+-      }
+-      spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
++      seq_printf(seq, "TSAP %d, ", iter->id);
++      seq_printf(seq, "stsap_sel: %02x, ",
++                 self->stsap_sel);
++      seq_printf(seq, "dtsap_sel: %02x\n",
++                 self->dtsap_sel);
++      seq_printf(seq, "  connected: %s, ",
++                 self->connected? "TRUE":"FALSE");
++      seq_printf(seq, "avail credit: %d, ",
++                 self->avail_credit);
++      seq_printf(seq, "remote credit: %d, ",
++                 self->remote_credit);
++      seq_printf(seq, "send credit: %d\n",
++                 self->send_credit);
++      seq_printf(seq, "  tx packets: %ld, ",
++                 self->stats.tx_packets);
++      seq_printf(seq, "rx packets: %ld, ",
++                 self->stats.rx_packets);
++      seq_printf(seq, "tx_queue len: %d ",
++                 skb_queue_len(&self->tx_queue));
++      seq_printf(seq, "rx_queue len: %d\n",
++                 skb_queue_len(&self->rx_queue));
++      seq_printf(seq, "  tx_sdu_busy: %s, ",
++                 self->tx_sdu_busy? "TRUE":"FALSE");
++      seq_printf(seq, "rx_sdu_busy: %s\n",
++                 self->rx_sdu_busy? "TRUE":"FALSE");
++      seq_printf(seq, "  max_seg_size: %d, ",
++                 self->max_seg_size);
++      seq_printf(seq, "tx_max_sdu_size: %d, ",
++                 self->tx_max_sdu_size);
++      seq_printf(seq, "rx_max_sdu_size: %d\n",
++                 self->rx_max_sdu_size);
+-      return len;
++      seq_printf(seq, "  Used by (%s)\n\n",
++                 self->notify.name);
++      return 0;
+ }
++static struct seq_operations irttp_seq_ops = {
++      .start  = irttp_seq_start,
++      .next   = irttp_seq_next,
++      .stop   = irttp_seq_stop,
++      .show   = irttp_seq_show,
++};
++
++static int irttp_seq_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      int rc = -ENOMEM;
++      struct irttp_iter_state *s;
++       
++      ASSERT(irttp != NULL, return -EINVAL;);
++
++      s = kmalloc(sizeof(*s), GFP_KERNEL);
++      if (!s)
++              goto out;
++
++      rc = seq_open(file, &irttp_seq_ops);
++      if (rc)
++              goto out_kfree;
++
++      seq          = file->private_data;
++      seq->private = s;
++      memset(s, 0, sizeof(*s));
++out:
++      return rc;
++out_kfree:
++      kfree(s);
++      goto out;
++}
++
++struct file_operations irttp_seq_fops = {
++      .owner          = THIS_MODULE,
++      .open           = irttp_seq_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release_private,
++};
++
+ #endif /* PROC_FS */
+Index: linux-2.6.0-test5/net/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/net/Kconfig 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/Kconfig      2003-09-27 11:38:42.083130776 +0800
+@@ -370,24 +370,11 @@
+ config VLAN_8021Q
+       tristate "802.1Q VLAN Support"
+-config LLC
+-      tristate "ANSI/IEEE 802.2 - aka LLC (IPX, Appletalk, Token Ring)"
+-      help
+-        This is a Logical Link Layer protocol used for Appletalk, IPX,
+-        Token Ring devices, the linux-sna.org project and in the future by
+-        NetBEUI. It originally came from Procom Inc. that released the code
+-        for 2.0.36 and was heavily modified to work with 2.{4,5}.
+-        Select this if you want to have support for those protocols or if
+-        you want to have the sockets interface for LLC.
+-        
+-
+-config LLC_UI
+-      bool "LLC sockets interface"
+-      depends on LLC
++source "net/llc/Kconfig"
+ config IPX
+       tristate "The IPX protocol"
+-      depends on LLC
++      select LLC
+       ---help---
+         This is support for the Novell networking protocol, IPX, commonly
+         used for local networks of Windows machines.  You need it if you
+@@ -424,7 +411,7 @@
+ config ATALK
+       tristate "Appletalk protocol support"
+-      depends on LLC
++      select LLC
+       ---help---
+         AppleTalk is the protocol that Apple computers can use to communicate
+         on a network.  If your Linux box is connected to such a network and you
+@@ -479,9 +466,8 @@
+         using the X.21 protocol (not yet supported by Linux) or one can do
+         X.25 over a standard telephone line using an ordinary modem (say Y
+         to "X.25 async driver" below) or over Ethernet using an ordinary
+-        Ethernet card and either the 802.2 LLC protocol (say Y to "802.2
+-        LLC" below) or LAPB over Ethernet (say Y to "LAPB Data Link Driver"
+-        and "LAPB over Ethernet driver" below).
++        Ethernet card and the LAPB over Ethernet (say Y to "LAPB Data Link
++        Driver" and "LAPB over Ethernet driver" below).
+         If you want to compile this driver as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want),
+Index: linux-2.6.0-test5/net/llc/af_llc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/af_llc.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/af_llc.c 2003-09-27 11:38:42.090129712 +0800
+@@ -24,13 +24,13 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/tcp.h>
++#include <linux/rtnetlink.h>
++#include <linux/init.h>
++#include <net/llc.h>
+ #include <net/llc_sap.h>
+ #include <net/llc_pdu.h>
+ #include <net/llc_conn.h>
+-#include <net/llc_mac.h>
+-#include <net/llc_main.h>
+-#include <linux/rtnetlink.h>
+-#include <linux/init.h>
++#include <net/llc_proc.h>
+ /* remember: uninitialized global data is zeroed because its in .bss */
+ static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
+@@ -182,10 +182,12 @@
+       if (!llc_send_disc(sk))
+               llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
+       if (!sk->sk_zapped)
+-              llc_sap_unassign_sock(llc->sap, sk);
++              llc_sap_remove_socket(llc->sap, sk);
+       release_sock(sk);
+-      if (llc->sap && hlist_empty(&llc->sap->sk_list.list))
++      if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) {
++              llc_release_sockets(llc->sap);
+               llc_sap_close(llc->sap);
++      }
+       sock_put(sk);
+       llc_sk_free(sk);
+ out:
+@@ -303,7 +305,7 @@
+       memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
+       memcpy(&llc->addr, addr, sizeof(llc->addr));
+       /* assign new connection to its SAP */
+-      llc_sap_assign_sock(sap, sk);
++      llc_sap_add_socket(sap, sk);
+       rc = sk->sk_zapped = 0;
+ out:
+       return rc;
+@@ -1042,14 +1044,38 @@
+       .sendpage    = sock_no_sendpage,
+ };
+-int __init llc_ui_init(void)
++extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
++extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
++
++static int __init llc2_init(void)
+ {
++      int rc;
++
++      llc_build_offset_table();
++      llc_station_init();
+       llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
+-      sock_register(&llc_ui_family_ops);
+-      return 0;
++      rc = llc_proc_init();
++      if (!rc) {
++              sock_register(&llc_ui_family_ops);
++              llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
++              llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
++      }
++      return rc;
+ }
+-void __exit llc_ui_exit(void)
++static void __exit llc2_exit(void)
+ {
++      llc_station_exit();
++      llc_remove_pack(LLC_DEST_SAP);
++      llc_remove_pack(LLC_DEST_CONN);
+       sock_unregister(PF_LLC);
++      llc_proc_exit();
+ }
++
++module_init(llc2_init);
++module_exit(llc2_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
++MODULE_DESCRIPTION("IEEE 802.2 PF_LLC support");
++MODULE_ALIAS_NETPROTO(PF_LLC);
+Index: linux-2.6.0-test5/net/llc/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/Kconfig     2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/Kconfig  2003-09-27 11:38:42.091129560 +0800
+@@ -0,0 +1,10 @@
++config LLC
++      tristate
++      depends on NET
++
++config LLC2
++      tristate "ANSI/IEEE 802.2 LLC type 2 Support"
++      select LLC
++      help
++        This is a Logical Link Layer type 2, connection oriented support. 
++        Select this if you want to have support for PF_LLC sockets.
+Index: linux-2.6.0-test5/net/llc/llc_c_ac.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_c_ac.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_c_ac.c       2003-09-27 11:38:42.102127888 +0800
+@@ -21,12 +21,13 @@
+ #include <net/llc_conn.h>
+ #include <net/llc_sap.h>
+ #include <net/sock.h>
+-#include <net/llc_main.h>
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_st.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_mac.h>
++#include <net/llc.h>
++
++#include "llc_output.h"
+ static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);
+ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
+@@ -52,7 +53,7 @@
+ int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOTCONN;
+       u8 dsap;
+       struct llc_sap *sap;
+@@ -97,28 +98,24 @@
+ {
+       struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+       u8 reason = 0;
+-      int rc = 1;
++      int rc = 0;
+       if (ev->type == LLC_CONN_EV_TYPE_PDU) {
+               struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+               if (LLC_PDU_IS_RSP(pdu) &&
+                   LLC_PDU_TYPE_IS_U(pdu) &&
+-                  LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM) {
++                  LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)
+                       reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
+-                      rc = 0;
+-              } else if (LLC_PDU_IS_CMD(pdu) &&
++              else if (LLC_PDU_IS_CMD(pdu) &&
+                          LLC_PDU_TYPE_IS_U(pdu) &&
+-                         LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC) {
++                         LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)
+                       reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
+-                      rc = 0;
+-              }
+-      } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) {
++      } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
+               reason = LLC_DISC_REASON_ACK_TMR_EXP;
+-              rc = 0;
+-      } else {
++      else {
+               reason = 0;
+-              rc = 1;
++              rc = -EINVAL;
+       }
+       if (!rc) {
+               ev->reason   = reason;
+@@ -217,29 +214,33 @@
+ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+-              u8 p_bit = 1;
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_CMD);
+-              llc_pdu_init_as_disc_cmd(nskb, p_bit);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
+-              llc_conn_send_pdu(sk, nskb);
+-      }
+-      llc_conn_ac_set_p_flag_1(sk, skb);
+-      return rc;
++              llc_pdu_init_as_disc_cmd(nskb, 1);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
++              llc_conn_send_pdu(sk, nskb);
++              llc_conn_ac_set_p_flag_1(sk, skb);
++      }
++out:
++      return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -252,16 +253,21 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_dm_rsp(nskb, f_bit);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -273,16 +279,21 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_dm_rsp(nskb, f_bit);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -294,17 +305,22 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_dm_rsp(nskb, f_bit);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+       u8 f_bit;
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb;
+       struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+       struct llc_opt *llc = llc_sk(sk);
+@@ -323,16 +339,21 @@
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
+                                        llc->vR, INCORRECT);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -346,17 +367,22 @@
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
+                                        llc->vR, INCORRECT);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ {
+       u8 f_bit;
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb;
+       llc_pdu_decode_pf_bit(skb, &f_bit);
+@@ -371,41 +397,50 @@
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
+                                        llc->vR, INCORRECT);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      u8 p_bit = 1;
++      int rc;
+       struct llc_opt *llc = llc_sk(sk);
+       struct llc_sap *sap = llc->sap;
+       llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+                           llc->daddr.lsap, LLC_PDU_CMD);
+-      llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+-      lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+-      llc_conn_send_pdu(sk, skb);
+-      llc_conn_ac_inc_vs_by_1(sk, skb);
+-      return 0;
++      llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
++      rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++      if (!rc) {
++              llc_conn_send_pdu(sk, skb);
++              llc_conn_ac_inc_vs_by_1(sk, skb);
++      }
++      return rc;
+ }
+ int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      u8 p_bit = 0;
++      int rc;
+       struct llc_opt *llc = llc_sk(sk);
+       struct llc_sap *sap = llc->sap;
+       llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+                           llc->daddr.lsap, LLC_PDU_CMD);
+-      llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+-      lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+-      llc_conn_send_pdu(sk, skb);
+-      llc_conn_ac_inc_vs_by_1(sk, skb);
+-      return 0;
++      llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
++      rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++      if (!rc) {
++              llc_conn_send_pdu(sk, skb);
++              llc_conn_ac_inc_vs_by_1(sk, skb);
++      }
++      return rc;
+ }
+ int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+@@ -431,16 +466,18 @@
+ int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      u8 p_bit = 0;
++      int rc;
+       struct llc_opt *llc = llc_sk(sk);
+       struct llc_sap *sap = llc->sap;
+       llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+                           llc->daddr.lsap, LLC_PDU_CMD);
+-      llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+-      lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+-      llc_conn_send_pdu(sk, skb);
+-      llc_conn_ac_inc_vs_by_1(sk, skb);
++      llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
++      rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++      if (!rc) {
++              llc_conn_send_pdu(sk, skb);
++              llc_conn_ac_inc_vs_by_1(sk, skb);
++      }
+       return 0;
+ }
+@@ -457,9 +494,8 @@
+                                               struct sk_buff *skb)
+ {
+       u8 nr;
+-      u8 f_bit = 0;
+       struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -469,15 +505,17 @@
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+-              llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
+-              llc_conn_send_pdu(sk, nskb);
++              llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (!rc)
++                      llc_conn_send_pdu(sk, nskb);
++              else
++                      kfree_skb(skb);
+       }
+       if (rc) {
+               nr = LLC_I_GET_NR(pdu);
+               rc = 0;
+-              llc_conn_resend_i_pdu_as_cmd(sk, nr, f_bit);
++              llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
+       }
+       return rc;
+ }
+@@ -493,28 +531,32 @@
+ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+-              u8 p_bit = 1;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_CMD);
+-              llc_pdu_init_as_rej_cmd(nskb, p_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -526,16 +568,21 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -547,37 +594,46 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+-              u8 p_bit = 1;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_CMD);
+-              llc_pdu_init_as_rnr_cmd(nskb, p_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -589,16 +645,21 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -610,11 +671,16 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
+@@ -631,70 +697,82 @@
+ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+-              u8 f_bit = 0;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+-              llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+-              u8 p_bit = 1;
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_CMD);
+-              llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+-              u8 p_bit = 1;
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_CMD);
+-              llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -706,16 +784,21 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+@@ -727,53 +810,66 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+-              u8 f_bit = 0;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+-              llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+-              u8 f_bit = 0;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+-              llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ void llc_conn_set_p_flag(struct sock *sk, u8 value)
+@@ -788,10 +884,9 @@
+ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       struct llc_opt *llc = llc_sk(sk);
+-      u8 p_bit = 1;
+       if (nskb) {
+               struct llc_sap *sap = llc->sap;
+@@ -802,41 +897,49 @@
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_CMD);
+-              llc_pdu_init_as_sabme_cmd(nskb, p_bit);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, dmac);
+-              rc = 0;
+-              llc_conn_send_pdu(sk, nskb);
+-      }
+-      llc_conn_set_p_flag(sk, p_bit);
+-
+-      return rc;
++              llc_pdu_init_as_sabme_cmd(nskb, 1);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
++              if (rc)
++                      goto free;
++              llc_conn_send_pdu(sk, nskb);
++              llc_conn_set_p_flag(sk, 1);
++      }
++out:
++      return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+-              u8 f_bit = llc->f_flag;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+-              llc_pdu_init_as_ua_rsp(nskb, f_bit);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_ua_rsp(nskb, llc->f_flag);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ {
+       u8 f_bit;
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       llc_pdu_decode_pf_bit(skb, &f_bit);
+@@ -848,11 +951,16 @@
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+               llc_pdu_init_as_ua_rsp(nskb, f_bit);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
+@@ -935,17 +1043,19 @@
+  */
+ int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
+ {
++      int rc;
+       struct llc_opt *llc = llc_sk(sk);
+-      u8 p_bit = llc->ack_pf;
+       struct llc_sap *sap = llc->sap;
+       llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+                           llc->daddr.lsap, LLC_PDU_RSP);
+-      llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+-      lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+-      llc_conn_send_pdu(sk, skb);
+-      llc_conn_ac_inc_vs_by_1(sk, skb);
+-      return 0;
++      llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
++      rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
++      if (!rc) {
++              llc_conn_send_pdu(sk, skb);
++              llc_conn_ac_inc_vs_by_1(sk, skb);
++      }
++      return rc;
+ }
+ /**
+@@ -983,23 +1093,27 @@
+  */
+ int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
+ {
+-      int rc = 1;
++      int rc = -ENOBUFS;
+       struct sk_buff *nskb = llc_alloc_frame();
+       if (nskb) {
+               struct llc_opt *llc = llc_sk(sk);
+               struct llc_sap *sap = llc->sap;
+-              u8 f_bit = llc->ack_pf;
+               nskb->dev = llc->dev;
+               llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+                                   llc->daddr.lsap, LLC_PDU_RSP);
+-              llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
+-              lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
+-              rc = 0;
++              llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
++              rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
++              if (rc)
++                      goto free;
+               llc_conn_send_pdu(sk, nskb);
+       }
++out:
+       return rc;
++free:
++      kfree_skb(nskb);
++      goto out;
+ }
+ /**
+@@ -1193,7 +1307,6 @@
+ {
+       int acked;
+       u16 unacked = 0;
+-      u8 fbit;
+       struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+       struct llc_opt *llc = llc_sk(sk);
+@@ -1215,8 +1328,10 @@
+                       mod_timer(&llc->ack_timer.timer,
+                                 jiffies + llc->ack_timer.expire * HZ);
+       } else if (llc->failed_data_req) {
+-              llc_pdu_decode_pf_bit(skb, &fbit);
+-              if (fbit == 1) {
++              u8 f_bit;
++
++              llc_pdu_decode_pf_bit(skb, &f_bit);
++              if (f_bit == 1) {
+                       llc->failed_data_req = 0;
+                       llc_conn_ac_data_confirm(sk, skb);
+               }
+Index: linux-2.6.0-test5/net/llc/llc_conn.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_conn.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_conn.c       2003-09-27 11:38:42.108126976 +0800
+@@ -11,21 +11,22 @@
+  *
+  * See the GNU General Public License for more details.
+  */
+-#include <linux/netdevice.h>
+-#include <linux/interrupt.h>
++
+ #include <linux/init.h>
+-#include <net/llc_if.h>
+ #include <net/llc_sap.h>
+ #include <net/llc_conn.h>
+ #include <net/sock.h>
+ #include <linux/tcp.h>
+-#include <net/llc_main.h>
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_st.h>
+-#include <net/llc_mac.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_s_ev.h>
++
++#if 0
++#define dprintk(args...) printk(KERN_DEBUG args)
++#else
++#define dprintk(args...)
++#endif
+ static int llc_find_offset(int state, int ev_type);
+ static void llc_conn_send_pdus(struct sock *sk);
+@@ -39,22 +40,6 @@
+ /* Offset table on connection states transition diagram */
+ static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
+-void llc_save_primitive(struct sk_buff* skb, u8 prim)
+-{
+-      struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
+-
+-       /* save primitive for use by the user. */
+-      addr->sllc_family = skb->sk->sk_family;
+-      addr->sllc_arphrd = skb->dev->type;
+-      addr->sllc_test   = prim == LLC_TEST_PRIM;
+-      addr->sllc_xid    = prim == LLC_XID_PRIM;
+-      addr->sllc_ua     = prim == LLC_DATAUNIT_PRIM;
+-      llc_pdu_decode_sa(skb, addr->sllc_smac);
+-      llc_pdu_decode_da(skb, addr->sllc_dmac);
+-      llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
+-      llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
+-}
+-
+ /**
+  *    llc_conn_state_process - sends event to connection state machine
+  *    @sk: connection
+@@ -541,35 +526,6 @@
+ }
+ /**
+- *    llc_lookup_dgram - Finds dgram socket for the local sap/mac
+- *    @sap: SAP
+- *    @laddr: address of local LLC (MAC + SAP)
+- *
+- *    Search socket list of the SAP and finds connection using the local
+- *    mac, and local sap. Returns pointer for socket found, %NULL otherwise.
+- */
+-struct sock *llc_lookup_dgram(struct llc_sap *sap, struct llc_addr *laddr)
+-{
+-      struct sock *rc;
+-      struct hlist_node *node;
+-
+-      read_lock_bh(&sap->sk_list.lock);
+-      sk_for_each(rc, node, &sap->sk_list.list) {
+-              struct llc_opt *llc = llc_sk(rc);
+-
+-              if (rc->sk_type == SOCK_DGRAM &&
+-                  llc->laddr.lsap == laddr->lsap &&
+-                  llc_mac_match(llc->laddr.mac, laddr->mac)) {
+-                      sock_hold(rc);
+-                      goto found;
+-              }
+-      }
+-      rc = NULL;
+-found:
+-      read_unlock_bh(&sap->sk_list.lock);
+-      return rc;
+-}
+-/**
+  *    llc_data_accept_state - designates if in this state data can be sent.
+  *    @state: state of connection.
+  *
+@@ -651,3 +607,323 @@
+       }
+       return rc;
+ }
++
++/**
++ *    llc_sap_add_socket - adds a socket to a SAP
++ *    @sap: SAP
++ *    @sk: socket
++ *
++ *    This function adds a socket to sk_list of a SAP.
++ */
++void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
++{
++      write_lock_bh(&sap->sk_list.lock);
++      llc_sk(sk)->sap = sap;
++      sk_add_node(sk, &sap->sk_list.list);
++      write_unlock_bh(&sap->sk_list.lock);
++}
++
++/**
++ *    llc_sap_remove_socket - removes a socket from SAP
++ *    @sap: SAP
++ *    @sk: socket
++ *
++ *    This function removes a connection from sk_list.list of a SAP if
++ *    the connection was in this list.
++ */
++void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
++{
++      write_lock_bh(&sap->sk_list.lock);
++      sk_del_node_init(sk);
++      write_unlock_bh(&sap->sk_list.lock);
++}
++
++/**
++ *    llc_conn_rcv - sends received pdus to the connection state machine
++ *    @sk: current connection structure.
++ *    @skb: received frame.
++ *
++ *    Sends received pdus to the connection state machine.
++ */
++static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
++{
++      struct llc_conn_state_ev *ev = llc_conn_ev(skb);
++      struct llc_opt *llc = llc_sk(sk);
++
++      if (!llc->dev)
++              llc->dev = skb->dev;
++      ev->type   = LLC_CONN_EV_TYPE_PDU;
++      ev->reason = 0;
++      return llc_conn_state_process(sk, skb);
++}
++
++void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
++{
++      struct llc_addr saddr, daddr;
++      struct sock *sk;
++
++      llc_pdu_decode_sa(skb, saddr.mac);
++      llc_pdu_decode_ssap(skb, &saddr.lsap);
++      llc_pdu_decode_da(skb, daddr.mac);
++      llc_pdu_decode_dsap(skb, &daddr.lsap);
++
++      sk = llc_lookup_established(sap, &saddr, &daddr);
++      if (!sk) {
++              /*
++               * Didn't find an active connection; verify if there
++               * is a listening socket for this llc addr
++               */
++              struct llc_opt *llc;
++              struct sock *parent = llc_lookup_listener(sap, &daddr);
++
++              if (!parent) {
++                      dprintk("llc_lookup_listener failed!\n");
++                      goto drop;
++              }
++
++              sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC);
++              if (!sk) {
++                      sock_put(parent);
++                      goto drop;
++              }
++              llc = llc_sk(sk);
++              memcpy(&llc->laddr, &daddr, sizeof(llc->laddr));
++              memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
++              llc_sap_add_socket(sap, sk);
++              sock_hold(sk);
++              sock_put(parent);
++              skb->sk = parent;
++      } else
++              skb->sk = sk;
++      bh_lock_sock(sk);
++      if (!sock_owned_by_user(sk))
++              llc_conn_rcv(sk, skb);
++      else {
++              dprintk("%s: adding to backlog...\n", __FUNCTION__);
++              llc_set_backlog_type(skb, LLC_PACKET);
++              sk_add_backlog(sk, skb);
++      }
++      bh_unlock_sock(sk);
++      sock_put(sk);
++      return;
++drop:
++      kfree_skb(skb);
++}
++
++#undef LLC_REFCNT_DEBUG
++#ifdef LLC_REFCNT_DEBUG
++static atomic_t llc_sock_nr;
++#endif
++
++/**
++ *    llc_release_sockets - releases all sockets in a sap
++ *    @sap: sap to release its sockets
++ *
++ *    Releases all connections of a sap. Returns 0 if all actions complete
++ *    successfully, nonzero otherwise
++ */
++int llc_release_sockets(struct llc_sap *sap)
++{
++      int rc = 0;
++      struct sock *sk;
++      struct hlist_node *node;
++
++      write_lock_bh(&sap->sk_list.lock);
++
++      sk_for_each(sk, node, &sap->sk_list.list) {
++              llc_sk(sk)->state = LLC_CONN_STATE_TEMP;
++
++              if (llc_send_disc(sk))
++                      rc = 1;
++      }
++
++      write_unlock_bh(&sap->sk_list.lock);
++      return rc;
++}
++
++/**
++ *    llc_backlog_rcv - Processes rx frames and expired timers.
++ *    @sk: LLC sock (p8022 connection)
++ *    @skb: queued rx frame or event
++ *
++ *    This function processes frames that has received and timers that has
++ *    expired during sending an I pdu (refer to data_req_handler).  frames
++ *    queue by llc_rcv function (llc_mac.c) and timers queue by timer
++ *    callback functions(llc_c_ac.c).
++ */
++static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
++{
++      int rc = 0;
++      struct llc_opt *llc = llc_sk(sk);
++
++      if (llc_backlog_type(skb) == LLC_PACKET) {
++              if (llc->state > 1) /* not closed */
++                      rc = llc_conn_rcv(sk, skb);
++              else
++                      goto out_kfree_skb;
++      } else if (llc_backlog_type(skb) == LLC_EVENT) {
++              /* timer expiration event */
++              if (llc->state > 1)  /* not closed */
++                      rc = llc_conn_state_process(sk, skb);
++              else
++                      goto out_kfree_skb;
++      } else {
++              printk(KERN_ERR "%s: invalid skb in backlog\n", __FUNCTION__);
++              goto out_kfree_skb;
++      }
++out:
++      return rc;
++out_kfree_skb:
++      kfree_skb(skb);
++      goto out;
++}
++
++/**
++ *     llc_sk_init - Initializes a socket with default llc values.
++ *     @sk: socket to initialize.
++ *
++ *     Initializes a socket with default llc values.
++ */
++int llc_sk_init(struct sock* sk)
++{
++      struct llc_opt *llc = kmalloc(sizeof(*llc), GFP_ATOMIC);
++      int rc = -ENOMEM;
++
++      if (!llc)
++              goto out;
++      memset(llc, 0, sizeof(*llc));
++      rc = 0;
++
++      llc->sk       = sk;
++      llc->state    = LLC_CONN_STATE_ADM;
++      llc->inc_cntr = llc->dec_cntr = 2;
++      llc->dec_step = llc->connect_step = 1;
++
++      init_timer(&llc->ack_timer.timer);
++      llc->ack_timer.expire         = LLC_ACK_TIME;
++      llc->ack_timer.timer.data     = (unsigned long)sk;
++      llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
++
++      init_timer(&llc->pf_cycle_timer.timer);
++      llc->pf_cycle_timer.expire         = LLC_P_TIME;
++      llc->pf_cycle_timer.timer.data     = (unsigned long)sk;
++      llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
++
++      init_timer(&llc->rej_sent_timer.timer);
++      llc->rej_sent_timer.expire         = LLC_REJ_TIME;
++      llc->rej_sent_timer.timer.data     = (unsigned long)sk;
++      llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
++
++      init_timer(&llc->busy_state_timer.timer);
++      llc->busy_state_timer.expire         = LLC_BUSY_TIME;
++      llc->busy_state_timer.timer.data     = (unsigned long)sk;
++      llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
++
++      llc->n2 = 2;   /* max retransmit */
++      llc->k  = 2;   /* tx win size, will adjust dynam */
++      llc->rw = 128; /* rx win size (opt and equal to
++                      * tx_win of remote LLC) */
++      skb_queue_head_init(&llc->pdu_unack_q);
++      sk->sk_backlog_rcv = llc_backlog_rcv;
++      llc_sk(sk) = llc;
++out:
++      return rc;
++}
++
++/**
++ *    llc_sk_alloc - Allocates LLC sock
++ *    @family: upper layer protocol family
++ *    @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
++ *
++ *    Allocates a LLC sock and initializes it. Returns the new LLC sock
++ *    or %NULL if there's no memory available for one
++ */
++struct sock *llc_sk_alloc(int family, int priority)
++{
++      struct sock *sk = sk_alloc(family, priority, 1, NULL);
++
++      if (!sk)
++              goto out;
++      if (llc_sk_init(sk))
++              goto outsk;
++      sock_init_data(NULL, sk);
++      sk_set_owner(sk, THIS_MODULE);
++#ifdef LLC_REFCNT_DEBUG
++      atomic_inc(&llc_sock_nr);
++      printk(KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk,
++              __FUNCTION__, atomic_read(&llc_sock_nr));
++#endif
++out:
++      return sk;
++outsk:
++      sk_free(sk);
++      sk = NULL;
++      goto out;
++}
++
++/**
++ *    llc_sk_free - Frees a LLC socket
++ *    @sk - socket to free
++ *
++ *    Frees a LLC socket
++ */
++void llc_sk_free(struct sock *sk)
++{
++      struct llc_opt *llc = llc_sk(sk);
++
++      llc->state = LLC_CONN_OUT_OF_SVC;
++      /* Stop all (possibly) running timers */
++      llc_conn_ac_stop_all_timers(sk, NULL);
++#ifdef DEBUG_LLC_CONN_ALLOC
++      printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __FUNCTION__,
++              skb_queue_len(&llc->pdu_unack_q),
++              skb_queue_len(&sk->sk_write_queue));
++#endif
++      skb_queue_purge(&sk->sk_receive_queue);
++      skb_queue_purge(&sk->sk_write_queue);
++      skb_queue_purge(&llc->pdu_unack_q);
++#ifdef LLC_REFCNT_DEBUG
++      if (atomic_read(&sk->sk_refcnt) != 1) {
++              printk(KERN_DEBUG "Destruction of LLC sock %p delayed in %s, cnt=%d\n",
++                      sk, __FUNCTION__, atomic_read(&sk->sk_refcnt));
++              printk(KERN_DEBUG "%d LLC sockets are still alive\n",
++                      atomic_read(&llc_sock_nr));
++      } else {
++              atomic_dec(&llc_sock_nr);
++              printk(KERN_DEBUG "LLC socket %p released in %s, %d are still alive\n", sk,
++                      __FUNCTION__, atomic_read(&llc_sock_nr));
++      }
++#endif
++      sock_put(sk);
++}
++
++/**
++ *    llc_sk_reset - resets a connection
++ *    @sk: LLC socket to reset
++ *
++ *    Resets a connection to the out of service state. Stops its timers
++ *    and frees any frames in the queues of the connection.
++ */
++void llc_sk_reset(struct sock *sk)
++{
++      struct llc_opt *llc = llc_sk(sk);
++
++      llc_conn_ac_stop_all_timers(sk, NULL);
++      skb_queue_purge(&sk->sk_write_queue);
++      skb_queue_purge(&llc->pdu_unack_q);
++      llc->remote_busy_flag   = 0;
++      llc->cause_flag         = 0;
++      llc->retry_count        = 0;
++      llc_conn_set_p_flag(sk, 0);
++      llc->f_flag             = 0;
++      llc->s_flag             = 0;
++      llc->ack_pf             = 0;
++      llc->first_pdu_Ns       = 0;
++      llc->ack_must_be_send   = 0;
++      llc->dec_step           = 1;
++      llc->inc_cntr           = 2;
++      llc->dec_cntr           = 2;
++      llc->X                  = 0;
++      llc->failed_data_req    = 0 ;
++      llc->last_nr            = 0;
++}
+Index: linux-2.6.0-test5/net/llc/llc_core.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_core.c  2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_core.c       2003-09-27 11:38:42.109126824 +0800
+@@ -0,0 +1,181 @@
++/*
++ * llc_core.c - Minimum needed routines for sap handling and module init/exit
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/if_ether.h>
++#include <linux/netdevice.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <net/llc.h>
++
++LIST_HEAD(llc_sap_list);
++rwlock_t llc_sap_list_lock = RW_LOCK_UNLOCKED;
++
++unsigned char llc_station_mac_sa[ETH_ALEN];
++
++/**
++ *    llc_sap_alloc - allocates and initializes sap.
++ *
++ *    Allocates and initializes sap.
++ */
++struct llc_sap *llc_sap_alloc(void)
++{
++      struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
++
++      if (sap) {
++              memset(sap, 0, sizeof(*sap));
++              sap->state = LLC_SAP_STATE_ACTIVE;
++              memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
++              rwlock_init(&sap->sk_list.lock);
++      }
++      return sap;
++}
++
++/**
++ *    llc_add_sap - add sap to station list
++ *    @sap: Address of the sap
++ *
++ *    Adds a sap to the LLC's station sap list.
++ */
++void llc_add_sap(struct llc_sap *sap)
++{
++      write_lock_bh(&llc_sap_list_lock);
++      list_add_tail(&sap->node, &llc_sap_list);
++      write_unlock_bh(&llc_sap_list_lock);
++}
++
++/**
++ *    llc_del_sap - del sap from station list
++ *    @sap: Address of the sap
++ *
++ *    Removes a sap to the LLC's station sap list.
++ */
++void llc_del_sap(struct llc_sap *sap)
++{
++      write_lock_bh(&llc_sap_list_lock);
++      list_del(&sap->node);
++      write_unlock_bh(&llc_sap_list_lock);
++}
++
++/**
++ *    llc_sap_find - searchs a SAP in station
++ *    @sap_value: sap to be found
++ *
++ *    Searchs for a sap in the sap list of the LLC's station upon the sap ID.
++ *    Returns the sap or %NULL if not found.
++ */
++struct llc_sap *llc_sap_find(unsigned char sap_value)
++{
++      struct llc_sap* sap;
++
++      read_lock_bh(&llc_sap_list_lock);
++      list_for_each_entry(sap, &llc_sap_list, node)
++              if (sap->laddr.lsap == sap_value)
++                      goto out;
++      sap = NULL;
++out:
++      read_unlock_bh(&llc_sap_list_lock);
++      return sap;
++}
++
++/**
++ *    llc_sap_open - open interface to the upper layers.
++ *    @lsap: SAP number.
++ *    @func: rcv func for datalink protos
++ *
++ *    Interface function to upper layer. Each one who wants to get a SAP
++ *    (for example NetBEUI) should call this function. Returns the opened
++ *    SAP for success, NULL for failure.
++ */
++struct llc_sap *llc_sap_open(unsigned char lsap,
++                           int (*func)(struct sk_buff *skb,
++                                       struct net_device *dev,
++                                       struct packet_type *pt))
++{
++      struct llc_sap *sap = llc_sap_find(lsap);
++
++      if (sap) { /* SAP already exists */
++              sap = NULL;
++              goto out;
++      }
++      sap = llc_sap_alloc();
++      if (!sap)
++              goto out;
++      sap->laddr.lsap = lsap;
++      sap->rcv_func   = func;
++      llc_add_sap(sap);
++out:
++      return sap;
++}
++
++/**
++ *    llc_sap_close - close interface for upper layers.
++ *    @sap: SAP to be closed.
++ *
++ *    Close interface function to upper layer. Each one who wants to
++ *    close an open SAP (for example NetBEUI) should call this function.
++ *    Removes this sap from the list of saps in the station and then
++ *    frees the memory for this sap.
++ */
++void llc_sap_close(struct llc_sap *sap)
++{
++      WARN_ON(!hlist_empty(&sap->sk_list.list));
++      llc_del_sap(sap);
++      kfree(sap);
++}
++
++static struct packet_type llc_packet_type = {
++      .type = __constant_htons(ETH_P_802_2),
++      .func = llc_rcv,
++      .data = (void *)1,
++};
++
++static struct packet_type llc_tr_packet_type = {
++      .type = __constant_htons(ETH_P_TR_802_2),
++      .func = llc_rcv,
++      .data = (void *)1,
++};
++
++static int __init llc_init(void)
++{
++      if (dev_base->next)
++              memcpy(llc_station_mac_sa, dev_base->next->dev_addr, ETH_ALEN);
++      else
++              memset(llc_station_mac_sa, 0, ETH_ALEN);
++      dev_add_pack(&llc_packet_type);
++      dev_add_pack(&llc_tr_packet_type);
++      return 0;
++}
++
++static void __exit llc_exit(void)
++{
++      dev_remove_pack(&llc_packet_type);
++      dev_remove_pack(&llc_tr_packet_type);
++}
++
++module_init(llc_init);
++module_exit(llc_exit);
++
++EXPORT_SYMBOL(llc_station_mac_sa);
++EXPORT_SYMBOL(llc_sap_list);
++EXPORT_SYMBOL(llc_sap_list_lock);
++EXPORT_SYMBOL(llc_sap_find);
++EXPORT_SYMBOL(llc_sap_open);
++EXPORT_SYMBOL(llc_sap_close);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
++MODULE_DESCRIPTION("LLC IEEE 802.2 core support");
+Index: linux-2.6.0-test5/net/llc/llc_if.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_if.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_if.c 2003-09-27 11:38:42.113126216 +0800
+@@ -25,136 +25,8 @@
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_st.h>
+-#include <net/llc_main.h>
+-/**
+- *    llc_sap_open - open interface to the upper layers.
+- *    @lsap: SAP number.
+- *    @func: rcv func for datalink protos
+- *
+- *    Interface function to upper layer. Each one who wants to get a SAP
+- *    (for example NetBEUI) should call this function. Returns the opened
+- *    SAP for success, NULL for failure.
+- */
+-struct llc_sap *llc_sap_open(u8 lsap, int (*func)(struct sk_buff *skb,
+-                                                struct net_device *dev,
+-                                                struct packet_type *pt))
+-{
+-      /* verify this SAP is not already open; if so, return error */
+-      struct llc_sap *sap;
+-
+-      sap = llc_sap_find(lsap);
+-      if (sap) { /* SAP already exists */
+-              sap = NULL;
+-              goto out;
+-      }
+-      /* sap requested does not yet exist */
+-      sap = llc_sap_alloc();
+-      if (!sap)
+-              goto out;
+-      /* allocated a SAP; initialize it and clear out its memory pool */
+-      sap->laddr.lsap = lsap;
+-      sap->rcv_func   = func;
+-      sap->station    = &llc_main_station;
+-      /* initialized SAP; add it to list of SAPs this station manages */
+-      llc_sap_save(sap);
+-out:
+-      return sap;
+-}
+-
+-/**
+- *    llc_sap_close - close interface for upper layers.
+- *    @sap: SAP to be closed.
+- *
+- *    Close interface function to upper layer. Each one who wants to
+- *    close an open SAP (for example NetBEUI) should call this function.
+- */
+-void llc_sap_close(struct llc_sap *sap)
+-{
+-      llc_free_sap(sap);
+-}
+-
+-/**
+- *    llc_build_and_send_ui_pkt - unitdata request interface for upper layers
+- *    @sap: sap to use
+- *    @skb: packet to send
+- *    @dmac: destination mac address
+- *    @dsap: destination sap
+- *
+- *    Upper layers calls this function when upper layer wants to send data
+- *    using connection-less mode communication (UI pdu).
+- *
+- *    Accept data frame from network layer to be sent using connection-
+- *    less mode communication; timeout/retries handled by network layer;
+- *    package primitive as an event and send to SAP event handler
+- */
+-void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
+-                             u8 *dmac, u8 dsap)
+-{
+-      struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+-
+-      ev->saddr.lsap = sap->laddr.lsap;
+-      ev->daddr.lsap = dsap;
+-      memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+-      memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+-
+-      ev->type      = LLC_SAP_EV_TYPE_PRIM;
+-      ev->prim      = LLC_DATAUNIT_PRIM;
+-      ev->prim_type = LLC_PRIM_TYPE_REQ;
+-      llc_sap_state_process(sap, skb);
+-}
+-
+-/**
+- *    llc_build_and_send_test_pkt - TEST interface for upper layers.
+- *    @sap: sap to use
+- *    @skb: packet to send
+- *    @dmac: destination mac address
+- *    @dsap: destination sap
+- *
+- *    This function is called when upper layer wants to send a TEST pdu.
+- *    Returns 0 for success, 1 otherwise.
+- */
+-void llc_build_and_send_test_pkt(struct llc_sap *sap, 
+-                               struct sk_buff *skb, u8 *dmac, u8 dsap)
+-{
+-      struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+-
+-      ev->saddr.lsap = sap->laddr.lsap;
+-      ev->daddr.lsap = dsap;
+-      memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+-      memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+-      
+-      ev->type      = LLC_SAP_EV_TYPE_PRIM;
+-      ev->prim      = LLC_TEST_PRIM;
+-      ev->prim_type = LLC_PRIM_TYPE_REQ;
+-      llc_sap_state_process(sap, skb);
+-}
+-
+-/**
+- *    llc_build_and_send_xid_pkt - XID interface for upper layers
+- *    @sap: sap to use
+- *    @skb: packet to send
+- *    @dmac: destination mac address
+- *    @dsap: destination sap
+- *
+- *    This function is called when upper layer wants to send a XID pdu.
+- *    Returns 0 for success, 1 otherwise.
+- */
+-void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
+-                              u8 *dmac, u8 dsap)
+-{
+-      struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+-
+-      ev->saddr.lsap = sap->laddr.lsap;
+-      ev->daddr.lsap = dsap;
+-      memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+-      memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
+-
+-      ev->type      = LLC_SAP_EV_TYPE_PRIM;
+-      ev->prim      = LLC_XID_PRIM;
+-      ev->prim_type = LLC_PRIM_TYPE_REQ;
+-      llc_sap_state_process(sap, skb);
+-}
++u8 llc_mac_null_var[IFHWADDRLEN];
+ /**
+  *    llc_build_and_send_pkt - Connection data sending for upper layers.
+@@ -307,7 +179,3 @@
+       }
+       return rc;
+ }
+-
+-EXPORT_SYMBOL(llc_sap_open);
+-EXPORT_SYMBOL(llc_sap_close);
+-EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
+Index: linux-2.6.0-test5/net/llc/llc_input.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_input.c 2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_input.c      2003-09-27 11:38:42.114126064 +0800
+@@ -0,0 +1,189 @@
++/*
++ * llc_input.c - Minimal input path for LLC
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++#include <linux/netdevice.h>
++#include <net/llc.h>
++#include <net/llc_pdu.h>
++#include <net/llc_sap.h>
++
++#if 0
++#define dprintk(args...) printk(KERN_DEBUG args)
++#else
++#define dprintk(args...)
++#endif
++
++/*
++ * Packet handler for the station, registerable because in the minimal
++ * LLC core that is taking shape only the very minimal subset of LLC that
++ * is needed for things like IPX, Appletalk, etc will stay, with all the
++ * rest in the llc1 and llc2 modules.
++ */
++static void (*llc_station_handler)(struct sk_buff *skb);
++
++/*
++ * Packet handlers for LLC_DEST_SAP and LLC_DEST_CONN.
++ */
++static void (*llc_type_handlers[2])(struct llc_sap *sap,
++                                  struct sk_buff *skb);
++
++void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
++                                          struct sk_buff *skb))
++{
++      if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
++              llc_type_handlers[type] = handler;
++}
++
++void llc_remove_pack(int type)
++{
++      if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
++              llc_type_handlers[type] = NULL;
++}
++
++void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
++{
++      llc_station_handler = handler;
++}
++
++/**
++ *    llc_pdu_type - returns which LLC component must handle for PDU
++ *    @skb: input skb
++ *
++ *    This function returns which LLC component must handle this PDU.
++ */
++static __inline__ int llc_pdu_type(struct sk_buff *skb)
++{
++      int type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
++      struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
++
++      if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
++              goto out;
++      switch (LLC_U_PDU_CMD(pdu)) {
++      case LLC_1_PDU_CMD_XID:
++      case LLC_1_PDU_CMD_UI:
++      case LLC_1_PDU_CMD_TEST:
++              type = LLC_DEST_SAP;
++              break;
++      case LLC_2_PDU_CMD_SABME:
++      case LLC_2_PDU_CMD_DISC:
++      case LLC_2_PDU_RSP_UA:
++      case LLC_2_PDU_RSP_DM:
++      case LLC_2_PDU_RSP_FRMR:
++              break;
++      default:
++              type = LLC_DEST_INVALID;
++              break;
++      }
++out:
++      return type;
++}
++
++/**
++ *    llc_fixup_skb - initializes skb pointers
++ *    @skb: This argument points to incoming skb
++ *
++ *    Initializes internal skb pointer to start of network layer by deriving
++ *    length of LLC header; finds length of LLC control field in LLC header
++ *    by looking at the two lowest-order bits of the first control field
++ *    byte; field is either 3 or 4 bytes long.
++ */
++static inline int llc_fixup_skb(struct sk_buff *skb)
++{
++      u8 llc_len = 2;
++      struct llc_pdu_sn *pdu;
++
++      if (!pskb_may_pull(skb, sizeof(*pdu)))
++              return 0;
++
++      pdu = (struct llc_pdu_sn *)skb->data;
++      if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
++              llc_len = 1;
++      llc_len += 2;
++      skb->h.raw += llc_len;
++      skb_pull(skb, llc_len);
++      if (skb->protocol == htons(ETH_P_802_2)) {
++              u16 pdulen = ((struct ethhdr *)skb->mac.raw)->h_proto,
++                  data_size = ntohs(pdulen) - llc_len;
++
++              skb_trim(skb, data_size);
++      }
++      return 1;
++}
++
++/**
++ *    llc_rcv - 802.2 entry point from net lower layers
++ *    @skb: received pdu
++ *    @dev: device that receive pdu
++ *    @pt: packet type
++ *
++ *    When the system receives a 802.2 frame this function is called. It
++ *    checks SAP and connection of received pdu and passes frame to
++ *    llc_{station,sap,conn}_rcv for sending to proper state machine. If
++ *    the frame is related to a busy connection (a connection is sending
++ *    data now), it queues this frame in the connection's backlog.
++ */
++int llc_rcv(struct sk_buff *skb, struct net_device *dev,
++          struct packet_type *pt)
++{
++      struct llc_sap *sap;
++      struct llc_pdu_sn *pdu;
++      int dest;
++
++      /*
++       * When the interface is in promisc. mode, drop all the crap that it
++       * receives, do not try to analyse it.
++       */
++      if (unlikely(skb->pkt_type == PACKET_OTHERHOST)) {
++              dprintk("%s: PACKET_OTHERHOST\n", __FUNCTION__);
++              goto drop;
++      }
++      skb = skb_share_check(skb, GFP_ATOMIC);
++      if (unlikely(!skb))
++              goto out;
++      if (unlikely(!llc_fixup_skb(skb)))
++              goto drop;
++      pdu = llc_pdu_sn_hdr(skb);
++      if (unlikely(!pdu->dsap)) /* NULL DSAP, refer to station */
++             goto handle_station;
++      sap = llc_sap_find(pdu->dsap);
++      if (unlikely(!sap)) {/* unknown SAP */
++              dprintk("%s: llc_sap_find(%02X) failed!\n", __FUNCTION__,
++                      pdu->dsap);
++              goto drop;
++      }
++      /*
++       * First the upper layer protocols that don't need the full
++       * LLC functionality
++       */
++      if (sap->rcv_func) {
++              sap->rcv_func(skb, dev, pt);
++              goto out;
++      }
++      dest = llc_pdu_type(skb);
++      if (unlikely(!dest || !llc_type_handlers[dest - 1]))
++              goto drop;
++      llc_type_handlers[dest - 1](sap, skb);
++out:
++      return 0;
++drop:
++      kfree_skb(skb);
++      goto out;
++handle_station:
++      if (!llc_station_handler)
++              goto drop;
++      llc_station_handler(skb);
++      goto out;
++}
++
++EXPORT_SYMBOL(llc_add_pack);
++EXPORT_SYMBOL(llc_remove_pack);
++EXPORT_SYMBOL(llc_set_station_handler);
+Index: linux-2.6.0-test5/net/llc/llc_output.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_output.c        2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_output.c     2003-09-27 11:38:42.114126064 +0800
+@@ -0,0 +1,105 @@
++/*
++ * llc_output.c - LLC minimal output path
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License version 2 as published by the Free Software
++ * Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License version 2 for more details.
++ */
++
++#include <linux/if_arp.h>
++#include <linux/if_tr.h>
++#include <linux/netdevice.h>
++#include <linux/skbuff.h>
++#include <net/llc.h>
++#include <net/llc_pdu.h>
++
++/**
++ *    llc_mac_hdr_init - fills MAC header fields
++ *    @skb: Address of the frame to initialize its MAC header
++ *    @sa: The MAC source address
++ *    @da: The MAC destination address
++ *
++ *    Fills MAC header fields, depending on MAC type. Returns 0, If MAC type
++ *    is a valid type and initialization completes correctly 1, otherwise.
++ */
++int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da)
++{
++      int rc = 0;
++
++      switch (skb->dev->type) {
++#ifdef CONFIG_TR
++      case ARPHRD_IEEE802_TR: {
++              struct net_device *dev = skb->dev;
++              struct trh_hdr *trh;
++              
++              trh = (struct trh_hdr *)skb_push(skb, sizeof(*trh));
++              trh->ac = AC;
++              trh->fc = LLC_FRAME;
++              if (sa)
++                      memcpy(trh->saddr, sa, dev->addr_len);
++              else
++                      memset(trh->saddr, 0, dev->addr_len);
++              if (da) {
++                      memcpy(trh->daddr, da, dev->addr_len);
++                      tr_source_route(skb, trh, dev);
++              }
++              skb->mac.raw = skb->data;
++              break;
++      }
++#endif
++      case ARPHRD_ETHER:
++      case ARPHRD_LOOPBACK: {
++              unsigned short len = skb->len;
++              struct ethhdr *eth;
++
++              skb->mac.raw = skb_push(skb, sizeof(*eth));
++              eth = (struct ethhdr *)skb->mac.raw;
++              eth->h_proto = htons(len);
++              memcpy(eth->h_dest, da, ETH_ALEN);
++              memcpy(eth->h_source, sa, ETH_ALEN);
++              break;
++      }
++      default:
++              printk(KERN_WARNING "device type not supported: %d\n",
++                     skb->dev->type);
++              rc = -EINVAL;
++      }
++      return rc;
++}
++
++/**
++ *    llc_build_and_send_ui_pkt - unitdata request interface for upper layers
++ *    @sap: sap to use
++ *    @skb: packet to send
++ *    @dmac: destination mac address
++ *    @dsap: destination sap
++ *
++ *    Upper layers calls this function when upper layer wants to send data
++ *    using connection-less mode communication (UI pdu).
++ *
++ *    Accept data frame from network layer to be sent using connection-
++ *    less mode communication; timeout/retries handled by network layer;
++ *    package primitive as an event and send to SAP event handler
++ */
++int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
++                            unsigned char *dmac, unsigned char dsap)
++{
++      int rc;
++      llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
++                          dsap, LLC_PDU_CMD);
++      llc_pdu_init_as_ui_cmd(skb);
++      rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
++      if (!rc)
++              rc = dev_queue_xmit(skb);
++      return rc;
++}
++
++EXPORT_SYMBOL(llc_mac_hdr_init);
++EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
+Index: linux-2.6.0-test5/net/llc/llc_output.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_output.h        2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_output.h     2003-09-27 11:38:42.115125912 +0800
+@@ -0,0 +1,20 @@
++#ifndef LLC_OUTPUT_H
++#define LLC_OUTPUT_H
++/*
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License version 2 as published by the Free Software
++ * Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License version 2 for more details.
++ */
++
++struct sk_buff;
++
++int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da);
++
++#endif /* LLC_OUTPUT_H */
+Index: linux-2.6.0-test5/net/llc/llc_pdu.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_pdu.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_pdu.c        2003-09-27 11:38:42.120125152 +0800
+@@ -11,35 +11,13 @@
+  *
+  * See the GNU General Public License for more details.
+  */
++
+ #include <linux/netdevice.h>
+-#include <linux/if_tr.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_if.h>
+-#include <net/llc_main.h>
+ static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
+-static __inline__ int llc_get_hdr_len(u8 pdu_type);
+ static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu);
+-/**
+- *    llc_pdu_header_init - initializes pdu header
+- *    @skb: input skb that header must be set into it.
+- *    @type: type of PDU (U, I or S).
+- *    @ssap: source sap.
+- *    @dsap: destination sap.
+- *    @cr: command/response bit (0 or 1).
+- *
+- *    This function sets DSAP, SSAP and command/Response bit in LLC header.
+- */
+-void llc_pdu_header_init(struct sk_buff *skb, u8 type, u8 ssap, u8 dsap, u8 cr)
+-{
+-      struct llc_pdu_un *pdu =
+-                   llc_set_pdu_hdr(skb, skb_push(skb, llc_get_hdr_len(type)));
+-      pdu->dsap = dsap;
+-      pdu->ssap = ssap;
+-      pdu->ssap |= cr;
+-}
+-
+ void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
+ {
+       llc_pdu_un_hdr(skb)->ssap |= pdu_type;
+@@ -115,114 +93,6 @@
+ }
+ /**
+- *    llc_pdu_decode_sa - extracs source address (MAC) of input frame
+- *    @skb: input skb that source address must be extracted from it.
+- *    @sa: pointer to source address (6 byte array).
+- *
+- *    This function extracts source address(MAC) of input frame.
+- */
+-void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
+-{
+-      if (skb->protocol == ntohs(ETH_P_802_2))
+-              memcpy(sa, ((struct ethhdr *)skb->mac.raw)->h_source, ETH_ALEN);
+-      else if (skb->protocol == ntohs(ETH_P_TR_802_2))
+-              memcpy(sa, ((struct trh_hdr *)skb->mac.raw)->saddr, ETH_ALEN);
+-}
+-
+-/**
+- *    llc_pdu_decode_da - extracts dest address of input frame
+- *    @skb: input skb that destination address must be extracted from it
+- *    @sa: pointer to destination address (6 byte array).
+- *
+- *    This function extracts destination address(MAC) of input frame.
+- */
+-void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
+-{
+-      if (skb->protocol == ntohs(ETH_P_802_2))
+-              memcpy(da, ((struct ethhdr *)skb->mac.raw)->h_dest, ETH_ALEN);
+-      else if (skb->protocol == ntohs(ETH_P_TR_802_2))
+-              memcpy(da, ((struct trh_hdr *)skb->mac.raw)->daddr, ETH_ALEN);
+-}
+-
+-/**
+- *    llc_pdu_decode_dsap - extracts dest SAP of input frame
+- *    @skb: input skb that destination SAP must be extracted from it.
+- *    @dsap: destination SAP (output argument).
+- *
+- *    This function extracts destination SAP of input frame. right bit of
+- *    DSAP designates individual/group SAP.
+- */
+-void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
+-{
+-      *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
+-}
+-
+-/**
+- *    llc_pdu_decode_ssap - extracts source SAP of input frame
+- *    @skb: input skb that source SAP must be extracted from it.
+- *    @ssap: source SAP (output argument).
+- *
+- *    This function extracts source SAP of input frame. Right bit of SSAP is
+- *    command/response bit.
+- */
+-void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
+-{
+-      *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
+-}
+-
+-/**
+- *    llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
+- *    @skb: input skb that header must be set into it.
+- *
+- *    This function sets third byte of LLC header as a UI PDU.
+- */
+-void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
+-{
+-      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+-      pdu->ctrl_1  = LLC_PDU_TYPE_U;
+-      pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
+-}
+-
+-/**
+- *    llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
+- *    @skb: input skb that header must be set into it.
+- *
+- *    This function sets third,fourth,fifth and sixth bytes of LLC header as
+- *    a XID PDU.
+- */
+-void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported,
+-                           u8 rx_window)
+-{
+-      struct llc_xid_info *xid_info;
+-      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+-      pdu->ctrl_1      = LLC_PDU_TYPE_U;
+-      pdu->ctrl_1     |= LLC_1_PDU_CMD_XID;
+-      pdu->ctrl_1     |= LLC_U_PF_BIT_MASK;
+-      xid_info         = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
+-      xid_info->fmt_id = LLC_XID_FMT_ID;      /* 0x81 */
+-      xid_info->type   = svcs_supported;
+-      xid_info->rw     = rx_window << 1;      /* size of receive window */
+-      skb_put(skb, 3);
+-}
+-
+-/**
+- *    llc_pdu_init_as_test_cmd - sets PDU as TEST
+- *    @skb - Address of the skb to build
+- *
+- *    Sets a PDU as TEST
+- */
+-void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
+-{
+-      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+-      pdu->ctrl_1  = LLC_PDU_TYPE_U;
+-      pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
+-      pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+-}
+-
+-/**
+  *    llc_pdu_init_as_disc_cmd - Builds DISC PDU
+  *    @skb: Address of the skb to build
+  *    @p_bit: The P bit to set in the PDU
+@@ -350,55 +220,6 @@
+ }
+ /**
+- *    llc_pdu_init_as_xid_rsp - builds XID response PDU
+- *    @skb: Address of the skb to build
+- *    @svcs_supported: The class of the LLC (I or II)
+- *    @rx_window: The size of the receive window of the LLC
+- *
+- *    Builds a pdu frame as an XID response.
+- */
+-void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported,
+-                           u8 rx_window)
+-{
+-      struct llc_xid_info *xid_info;
+-      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+-      pdu->ctrl_1      = LLC_PDU_TYPE_U;
+-      pdu->ctrl_1     |= LLC_1_PDU_CMD_XID;
+-      pdu->ctrl_1     |= LLC_U_PF_BIT_MASK;
+-
+-      xid_info         = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
+-      xid_info->fmt_id = LLC_XID_FMT_ID;
+-      xid_info->type   = svcs_supported;
+-      xid_info->rw     = rx_window << 1;
+-      skb_put(skb, 3);
+-}
+-
+-/**
+- *    llc_pdu_init_as_test_rsp - build TEST response PDU
+- *    @skb: Address of the skb to build
+- *    @ev_skb: The received TEST command PDU frame
+- *
+- *    Builds a pdu frame as a TEST response.
+- */
+-void llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb)
+-{
+-      int dsize;
+-      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
+-
+-      pdu->ctrl_1  = LLC_PDU_TYPE_U;
+-      pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
+-      pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+-      if (ev_skb->protocol == ntohs(ETH_P_802_2)) {
+-              struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
+-
+-              dsize = ntohs(((struct ethhdr *)ev_skb->mac.raw)->h_proto) - 3;
+-              memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
+-              skb_put(skb, dsize);
+-      }
+-}
+-
+-/**
+  *    llc_pdu_init_as_frmr_rsp - builds FRMR response PDU
+  *    @skb: Address of the frame to build
+  *    @prev_pdu: The rejected PDU frame
+@@ -533,58 +354,6 @@
+ }
+ /**
+- *    llc_decode_pdu_type - designates component LLC must handle for PDU
+- *    @skb: input skb
+- *    @dest: destination component
+- *
+- *    This function designates which component of LLC must handle this PDU.
+- */
+-void llc_decode_pdu_type(struct sk_buff *skb, u8 *dest)
+-{
+-      u8 type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
+-      struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+-
+-      if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
+-              goto out;
+-      switch (LLC_U_PDU_CMD(pdu)) {
+-      case LLC_1_PDU_CMD_XID:
+-      case LLC_1_PDU_CMD_UI:
+-      case LLC_1_PDU_CMD_TEST:
+-              type = LLC_DEST_SAP;
+-              break;
+-      case LLC_2_PDU_CMD_SABME:
+-      case LLC_2_PDU_CMD_DISC:
+-      case LLC_2_PDU_RSP_UA:
+-      case LLC_2_PDU_RSP_DM:
+-      case LLC_2_PDU_RSP_FRMR:
+-              break;
+-      default:
+-              type = LLC_DEST_INVALID;
+-              break;
+-      }
+-out:
+-      *dest = type;
+-}
+-
+-/**
+- *    llc_get_hdr_len - designates LLC header length
+- *    @type: type of PDU.
+- *
+- *    This function designates LLC header length of PDU. header length for I
+- *    and S PDU is 4 and for U is 3 bytes. Returns the length of header.
+- */
+-static __inline__ int llc_get_hdr_len(u8 type)
+-{
+-      static int hdr_len[] = {
+-              [LLC_PDU_TYPE_U] = 3,
+-              [LLC_PDU_TYPE_I] = 4,
+-              [LLC_PDU_TYPE_S] = 4,
+-      };
+-
+-      return hdr_len[type];
+-}
+-
+-/**
+  *    llc_pdu_get_pf_bit - extracts p/f bit of input PDU
+  *    @pdu: pointer to LLC header.
+  *
+Index: linux-2.6.0-test5/net/llc/llc_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_proc.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_proc.c       2003-09-27 11:38:42.123124696 +0800
+@@ -20,13 +20,11 @@
+ #include <linux/errno.h>
+ #include <linux/seq_file.h>
+ #include <net/sock.h>
++#include <net/llc.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_ev.h>
+ #include <net/llc_c_st.h>
+ #include <net/llc_conn.h>
+-#include <net/llc_mac.h>
+-#include <net/llc_main.h>
+-#include <net/llc_sap.h>
+ static void llc_ui_format_mac(struct seq_file *seq, unsigned char *mac)
+ {
+@@ -41,7 +39,7 @@
+       struct hlist_node *node;
+       struct sock *sk = NULL;
+-      list_for_each(sap_entry, &llc_main_station.sap_list.list) {
++      list_for_each(sap_entry, &llc_sap_list) {
+               sap = list_entry(sap_entry, struct llc_sap, node);
+               read_lock_bh(&sap->sk_list.lock);
+@@ -66,8 +64,8 @@
+ {
+       loff_t l = *pos;
+-      read_lock_bh(&llc_main_station.sap_list.lock);
+-      return l ? llc_get_sk_idx(--l) : (void *)1;
++      read_lock_bh(&llc_sap_list_lock);
++      return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -77,7 +75,7 @@
+       struct llc_sap *sap;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               sk = llc_get_sk_idx(0);
+               goto out;
+       }
+@@ -92,7 +90,7 @@
+       read_unlock_bh(&sap->sk_list.lock);
+       sk = NULL;
+       for (;;) {
+-              if (sap->node.next == &llc_main_station.sap_list.list)
++              if (sap->node.next == &llc_sap_list)
+                       break;
+               sap = list_entry(sap->node.next, struct llc_sap, node);
+               read_lock_bh(&sap->sk_list.lock);
+@@ -115,7 +113,7 @@
+               read_unlock_bh(&sap->sk_list.lock);
+       }
+-      read_unlock_bh(&llc_main_station.sap_list.lock);
++      read_unlock_bh(&llc_sap_list_lock);
+ }
+ static int llc_seq_socket_show(struct seq_file *seq, void *v)
+@@ -123,7 +121,7 @@
+       struct sock* sk;
+       struct llc_opt *llc;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "SKt Mc local_mac_sap        remote_mac_sap   "
+                             "    tx_queue rx_queue st uid link\n");
+               goto out;
+@@ -172,7 +170,7 @@
+       struct sock* sk;
+       struct llc_opt *llc;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Connection list:\n"
+                             "dsap state      retr txw rxw pf ff sf df rs cs "
+                             "tack tpfc trs tbs blog busr\n");
+Index: linux-2.6.0-test5/net/llc/llc_s_ac.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_s_ac.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_s_ac.c       2003-09-27 11:38:42.125124392 +0800
+@@ -17,13 +17,14 @@
+  *
+  * See the GNU General Public License for more details.
+  */
++
+ #include <linux/netdevice.h>
+-#include <net/llc_if.h>
+-#include <net/llc_sap.h>
+-#include <net/llc_main.h>
+-#include <net/llc_s_ev.h>
++#include <net/llc.h>
+ #include <net/llc_pdu.h>
+-#include <net/llc_mac.h>
++#include <net/llc_s_ac.h>
++#include <net/llc_s_ev.h>
++#include <net/llc_sap.h>
++#include "llc_output.h"
+ /**
+  *    llc_sap_action_unit_data_ind - forward UI PDU to network layer
+@@ -56,7 +57,7 @@
+       llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+                           ev->daddr.lsap, LLC_PDU_CMD);
+       llc_pdu_init_as_ui_cmd(skb);
+-      rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
++      rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+       if (!rc)
+               rc = dev_queue_xmit(skb);
+       return rc;
+@@ -79,7 +80,7 @@
+       llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+                           ev->daddr.lsap, LLC_PDU_CMD);
+       llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
+-      rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
++      rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+       if (!rc)
+               rc = dev_queue_xmit(skb);
+       return rc;
+@@ -109,7 +110,7 @@
+       llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+                           LLC_PDU_RSP);
+       llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
+-      rc = lan_hdrs_init(nskb, mac_sa, mac_da);
++      rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
+       if (!rc)
+               rc = dev_queue_xmit(nskb);
+ out:
+@@ -133,7 +134,7 @@
+       llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+                           ev->daddr.lsap, LLC_PDU_CMD);
+       llc_pdu_init_as_test_cmd(skb);
+-      rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
++      rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
+       if (!rc)
+               rc = dev_queue_xmit(skb);
+       return rc;
+@@ -155,7 +156,7 @@
+       llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+                           LLC_PDU_RSP);
+       llc_pdu_init_as_test_rsp(nskb, skb);
+-      rc = lan_hdrs_init(nskb, mac_sa, mac_da);
++      rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
+       if (!rc)
+               rc = dev_queue_xmit(nskb);
+ out:
+Index: linux-2.6.0-test5/net/llc/llc_sap.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_sap.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/llc_sap.c        2003-09-27 11:38:42.128123936 +0800
+@@ -11,46 +11,53 @@
+  *
+  * See the GNU General Public License for more details.
+  */
+-#include <linux/skbuff.h>
++
++#include <net/llc.h>
++#include <net/llc_if.h>
+ #include <net/llc_conn.h>
++#include <net/llc_pdu.h>
+ #include <net/llc_sap.h>
+-#include <net/llc_s_ev.h>
+ #include <net/llc_s_ac.h>
++#include <net/llc_s_ev.h>
+ #include <net/llc_s_st.h>
+ #include <net/sock.h>
+ #include <linux/tcp.h>
+-#include <net/llc_main.h>
+-#include <net/llc_pdu.h>
+-#include <linux/if_tr.h>
++#include <linux/llc.h>
+ /**
+- *    llc_sap_assign_sock - adds a connection to a SAP
+- *    @sap: pointer to SAP.
+- *    @conn: pointer to connection.
++ *    llc_alloc_frame - allocates sk_buff for frame
+  *
+- *    This function adds a connection to connection_list of a SAP.
++ *    Allocates an sk_buff for frame and initializes sk_buff fields.
++ *    Returns allocated skb or %NULL when out of memory.
+  */
+-void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk)
++struct sk_buff *llc_alloc_frame(void)
+ {
+-      write_lock_bh(&sap->sk_list.lock);
+-      llc_sk(sk)->sap = sap;
+-      sk_add_node(sk, &sap->sk_list.list);
+-      write_unlock_bh(&sap->sk_list.lock);
++      struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
++
++      if (skb) {
++              skb_reserve(skb, 50);
++              skb->nh.raw   = skb->h.raw = skb->data;
++              skb->protocol = htons(ETH_P_802_2);
++              skb->dev      = dev_base->next;
++              skb->mac.raw  = skb->head;
++      }
++      return skb;
+ }
+-/**
+- *    llc_sap_unassign_sock - removes a connection from SAP
+- *    @sap: SAP
+- *    @sk: pointer to connection
+- *
+- *    This function removes a connection from sk_list.list of a SAP if
+- *    the connection was in this list.
+- */
+-void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
++void llc_save_primitive(struct sk_buff* skb, u8 prim)
+ {
+-      write_lock_bh(&sap->sk_list.lock);
+-      sk_del_node_init(sk);
+-      write_unlock_bh(&sap->sk_list.lock);
++      struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
++
++       /* save primitive for use by the user. */
++      addr->sllc_family = skb->sk->sk_family;
++      addr->sllc_arphrd = skb->dev->type;
++      addr->sllc_test   = prim == LLC_TEST_PRIM;
++      addr->sllc_xid    = prim == LLC_XID_PRIM;
++      addr->sllc_ua     = prim == LLC_DATAUNIT_PRIM;
++      llc_pdu_decode_sa(skb, addr->sllc_smac);
++      llc_pdu_decode_da(skb, addr->sllc_dmac);
++      llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
++      llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
+ }
+ /**
+@@ -193,3 +200,118 @@
+       } 
+       kfree_skb(skb);
+ }
++
++/**
++ *    llc_build_and_send_test_pkt - TEST interface for upper layers.
++ *    @sap: sap to use
++ *    @skb: packet to send
++ *    @dmac: destination mac address
++ *    @dsap: destination sap
++ *
++ *    This function is called when upper layer wants to send a TEST pdu.
++ *    Returns 0 for success, 1 otherwise.
++ */
++void llc_build_and_send_test_pkt(struct llc_sap *sap, 
++                               struct sk_buff *skb, u8 *dmac, u8 dsap)
++{
++      struct llc_sap_state_ev *ev = llc_sap_ev(skb);
++
++      ev->saddr.lsap = sap->laddr.lsap;
++      ev->daddr.lsap = dsap;
++      memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
++      memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
++      
++      ev->type      = LLC_SAP_EV_TYPE_PRIM;
++      ev->prim      = LLC_TEST_PRIM;
++      ev->prim_type = LLC_PRIM_TYPE_REQ;
++      llc_sap_state_process(sap, skb);
++}
++
++/**
++ *    llc_build_and_send_xid_pkt - XID interface for upper layers
++ *    @sap: sap to use
++ *    @skb: packet to send
++ *    @dmac: destination mac address
++ *    @dsap: destination sap
++ *
++ *    This function is called when upper layer wants to send a XID pdu.
++ *    Returns 0 for success, 1 otherwise.
++ */
++void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
++                              u8 *dmac, u8 dsap)
++{
++      struct llc_sap_state_ev *ev = llc_sap_ev(skb);
++
++      ev->saddr.lsap = sap->laddr.lsap;
++      ev->daddr.lsap = dsap;
++      memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
++      memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
++
++      ev->type      = LLC_SAP_EV_TYPE_PRIM;
++      ev->prim      = LLC_XID_PRIM;
++      ev->prim_type = LLC_PRIM_TYPE_REQ;
++      llc_sap_state_process(sap, skb);
++}
++
++/**
++ *    llc_sap_rcv - sends received pdus to the sap state machine
++ *    @sap: current sap component structure.
++ *    @skb: received frame.
++ *
++ *    Sends received pdus to the sap state machine.
++ */
++static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb)
++{
++      struct llc_sap_state_ev *ev = llc_sap_ev(skb);
++
++      ev->type   = LLC_SAP_EV_TYPE_PDU;
++      ev->reason = 0;
++      llc_sap_state_process(sap, skb);
++}
++
++/**
++ *    llc_lookup_dgram - Finds dgram socket for the local sap/mac
++ *    @sap: SAP
++ *    @laddr: address of local LLC (MAC + SAP)
++ *
++ *    Search socket list of the SAP and finds connection using the local
++ *    mac, and local sap. Returns pointer for socket found, %NULL otherwise.
++ */
++struct sock *llc_lookup_dgram(struct llc_sap *sap, struct llc_addr *laddr)
++{
++      struct sock *rc;
++      struct hlist_node *node;
++
++      read_lock_bh(&sap->sk_list.lock);
++      sk_for_each(rc, node, &sap->sk_list.list) {
++              struct llc_opt *llc = llc_sk(rc);
++
++              if (rc->sk_type == SOCK_DGRAM &&
++                  llc->laddr.lsap == laddr->lsap &&
++                  llc_mac_match(llc->laddr.mac, laddr->mac)) {
++                      sock_hold(rc);
++                      goto found;
++              }
++      }
++      rc = NULL;
++found:
++      read_unlock_bh(&sap->sk_list.lock);
++      return rc;
++}
++
++void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
++{
++      struct llc_addr laddr;
++      struct sock *sk;
++
++      llc_pdu_decode_da(skb, laddr.mac);
++      llc_pdu_decode_dsap(skb, &laddr.lsap);
++
++      sk = llc_lookup_dgram(sap, &laddr);
++      if (sk) {
++              skb->sk = sk;
++              llc_sap_rcv(sap, skb);
++              sock_put(sk);
++      } else
++              kfree_skb(skb);
++}
+Index: linux-2.6.0-test5/net/llc/llc_station.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/llc_station.c       2003-09-27 11:38:18.493716912 +0800
++++ linux-2.6.0-test5/net/llc/llc_station.c    2003-09-27 11:38:42.130123632 +0800
+@@ -0,0 +1,713 @@
++/*
++ * llc_station.c - station component of LLC
++ *
++ * Copyright (c) 1997 by Procom Technology, Inc.
++ *             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++ *
++ * This program can be redistributed or modified under the terms of the
++ * GNU General Public License as published by the Free Software Foundation.
++ * This program is distributed without any warranty or implied warranty
++ * of merchantability or fitness for a particular purpose.
++ *
++ * See the GNU General Public License for more details.
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <net/llc.h>
++#include <net/llc_sap.h>
++#include <net/llc_conn.h>
++#include <net/llc_c_ac.h>
++#include <net/llc_s_ac.h>
++#include <net/llc_c_ev.h>
++#include <net/llc_c_st.h>
++#include <net/llc_s_ev.h>
++#include <net/llc_s_st.h>
++#include <net/llc_pdu.h>
++
++/**
++ * struct llc_station - LLC station component
++ *
++ * SAP and connection resource manager, one per adapter.
++ *
++ * @state - state of station
++ * @xid_r_count - XID response PDU counter
++ * @mac_sa - MAC source address
++ * @sap_list - list of related SAPs
++ * @ev_q - events entering state mach.
++ * @mac_pdu_q - PDUs ready to send to MAC
++ */
++struct llc_station {
++      u8                          state;
++      u8                          xid_r_count;
++      struct timer_list           ack_timer;
++      u8                          retry_count;
++      u8                          maximum_retry;
++      struct {
++              struct sk_buff_head list;
++              spinlock_t          lock;
++      } ev_q;
++      struct sk_buff_head         mac_pdu_q;
++};
++
++/* Types of events (possible values in 'ev->type') */
++#define LLC_STATION_EV_TYPE_SIMPLE    1
++#define LLC_STATION_EV_TYPE_CONDITION 2
++#define LLC_STATION_EV_TYPE_PRIM      3
++#define LLC_STATION_EV_TYPE_PDU               4       /* command/response PDU */
++#define LLC_STATION_EV_TYPE_ACK_TMR   5
++#define LLC_STATION_EV_TYPE_RPT_STATUS        6
++
++/* Events */
++#define LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK             1
++#define LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK          2
++#define LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY     3
++#define LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY     4
++#define LLC_STATION_EV_RX_NULL_DSAP_XID_C                     5
++#define LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ      6
++#define LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ      7
++#define LLC_STATION_EV_RX_NULL_DSAP_TEST_C                    8
++#define LLC_STATION_EV_DISABLE_REQ                            9
++
++struct llc_station_state_ev {
++      u8               type;
++      u8               prim;
++      u8               prim_type;
++      u8               reason;
++      struct list_head node; /* node in station->ev_q.list */
++};
++
++static __inline__ struct llc_station_state_ev *
++                                      llc_station_ev(struct sk_buff *skb)
++{
++      return (struct llc_station_state_ev *)skb->cb;
++}
++
++typedef int (*llc_station_ev_t)(struct sk_buff *skb);
++
++#define LLC_STATION_STATE_DOWN                1       /* initial state */
++#define LLC_STATION_STATE_DUP_ADDR_CHK        2
++#define LLC_STATION_STATE_UP          3
++
++#define LLC_NBR_STATION_STATES                3       /* size of state table */
++
++typedef int (*llc_station_action_t)(struct sk_buff *skb);
++
++/* Station component state table structure */
++struct llc_station_state_trans {
++      llc_station_ev_t ev;
++      u8 next_state;
++      llc_station_action_t *ev_actions;
++};
++
++struct llc_station_state {
++      u8 curr_state;
++      struct llc_station_state_trans **transitions;
++};
++
++static struct llc_station llc_main_station;
++
++static int llc_stat_ev_enable_with_dup_addr_check(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);  
++      
++      return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
++             ev->prim_type ==
++                            LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1;
++}
++
++static int llc_stat_ev_enable_without_dup_addr_check(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);  
++      
++      return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
++             ev->prim_type ==
++                      LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1;
++}
++
++static int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);  
++      
++      return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
++              llc_main_station.retry_count <
++              llc_main_station.maximum_retry ? 0 : 1;
++}
++
++static int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);  
++      
++      return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
++              llc_main_station.retry_count ==
++              llc_main_station.maximum_retry ? 0 : 1;
++}
++
++static int llc_stat_ev_rx_null_dsap_xid_c(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);  
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      return ev->type == LLC_STATION_EV_TYPE_PDU &&
++             LLC_PDU_IS_CMD(pdu) &&                   /* command PDU */
++             LLC_PDU_TYPE_IS_U(pdu) &&                /* U type PDU */
++             LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
++             !pdu->dsap ? 0 : 1;                      /* NULL DSAP value */
++}
++
++static int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      return ev->type == LLC_STATION_EV_TYPE_PDU &&
++             LLC_PDU_IS_RSP(pdu) &&                   /* response PDU */
++             LLC_PDU_TYPE_IS_U(pdu) &&                /* U type PDU */
++             LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
++             !pdu->dsap &&                            /* NULL DSAP value */
++             !llc_main_station.xid_r_count ? 0 : 1;
++}
++
++static int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      return ev->type == LLC_STATION_EV_TYPE_PDU &&
++             LLC_PDU_IS_RSP(pdu) &&                   /* response PDU */
++             LLC_PDU_TYPE_IS_U(pdu) &&                /* U type PDU */
++             LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
++             !pdu->dsap &&                            /* NULL DSAP value */
++             llc_main_station.xid_r_count == 1 ? 0 : 1;
++}
++
++static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);
++      struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
++
++      return ev->type == LLC_STATION_EV_TYPE_PDU &&
++             LLC_PDU_IS_CMD(pdu) &&                   /* command PDU */
++             LLC_PDU_TYPE_IS_U(pdu) &&                /* U type PDU */
++             LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
++             !pdu->dsap ? 0 : 1;                      /* NULL DSAP */
++}
++
++static int llc_stat_ev_disable_req(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++      return ev->type == LLC_STATION_EV_TYPE_PRIM &&
++             ev->prim == LLC_DISABLE_PRIM &&
++             ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
++}
++
++/**
++ *    llc_station_send_pdu - queues PDU to send
++ *    @skb: Address of the PDU
++ *
++ *    Queues a PDU to send to the MAC layer.
++ */
++static void llc_station_send_pdu(struct sk_buff *skb)
++{
++      skb_queue_tail(&llc_main_station.mac_pdu_q, skb);
++      while ((skb = skb_dequeue(&llc_main_station.mac_pdu_q)) != NULL)
++              if (dev_queue_xmit(skb))
++                      break;
++}
++
++static int llc_station_ac_start_ack_timer(struct sk_buff *skb)
++{
++      mod_timer(&llc_main_station.ack_timer, jiffies + LLC_ACK_TIME * HZ);
++      return 0;
++}
++
++static int llc_station_ac_set_retry_cnt_0(struct sk_buff *skb)
++{
++      llc_main_station.retry_count = 0;
++      return 0;
++}
++
++static int llc_station_ac_inc_retry_cnt_by_1(struct sk_buff *skb)
++{
++      llc_main_station.retry_count++;
++      return 0;
++}
++
++static int llc_station_ac_set_xid_r_cnt_0(struct sk_buff *skb)
++{
++      llc_main_station.xid_r_count = 0;
++      return 0;
++}
++
++static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
++{
++      llc_main_station.xid_r_count++;
++      return 0;
++}
++
++static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
++{
++      int rc = 1;
++      struct sk_buff *nskb = llc_alloc_frame();
++
++      if (!nskb)
++              goto out;
++      llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
++      llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
++      rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
++      if (rc)
++              goto free;
++      llc_station_send_pdu(nskb);
++out:
++      return rc;
++free:
++      kfree_skb(skb);
++      goto out;
++}
++
++static int llc_station_ac_send_xid_r(struct sk_buff *skb)
++{
++      u8 mac_da[ETH_ALEN], dsap;
++      int rc = 1;
++      struct sk_buff* nskb = llc_alloc_frame();
++
++      if (!nskb)
++              goto out;
++      rc = 0;
++      nskb->dev = skb->dev;
++      llc_pdu_decode_sa(skb, mac_da);
++      llc_pdu_decode_ssap(skb, &dsap);
++      llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
++      llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
++      rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
++      if (rc)
++              goto free;
++      llc_station_send_pdu(nskb);
++out:
++      return rc;
++free:
++      kfree_skb(skb);
++      goto out;
++}
++
++static int llc_station_ac_send_test_r(struct sk_buff *skb)
++{
++      u8 mac_da[ETH_ALEN], dsap;
++      int rc = 1;
++      struct sk_buff *nskb = llc_alloc_frame();
++
++      if (!nskb)
++              goto out;
++      rc = 0;
++      nskb->dev = skb->dev;
++      llc_pdu_decode_sa(skb, mac_da);
++      llc_pdu_decode_ssap(skb, &dsap);
++      llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
++              llc_pdu_init_as_test_rsp(nskb, skb);
++      rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
++      if (rc)
++              goto free;
++      llc_station_send_pdu(nskb);
++out:
++      return rc;
++free:
++      kfree_skb(skb);
++      goto out;
++}
++
++static int llc_station_ac_report_status(struct sk_buff *skb)
++{
++      return 0;
++}
++
++/* COMMON STATION STATE transitions */
++
++/* dummy last-transition indicator; common to all state transition groups
++ * last entry for this state
++ * all members are zeros, .bss zeroes it
++ */
++static struct llc_station_state_trans llc_stat_state_trans_end;
++
++/* DOWN STATE transitions */
++
++/* state transition for LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK event */
++static llc_station_action_t llc_stat_down_state_actions_1[] = {
++      [0] = llc_station_ac_start_ack_timer,
++      [1] = llc_station_ac_set_retry_cnt_0,
++      [2] = llc_station_ac_set_xid_r_cnt_0,
++      [3] = llc_station_ac_send_null_dsap_xid_c,
++      [4] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_down_state_trans_1 = {
++      .ev         = llc_stat_ev_enable_with_dup_addr_check,
++      .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++      .ev_actions = llc_stat_down_state_actions_1,
++};
++
++/* state transition for LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK event */
++static llc_station_action_t llc_stat_down_state_actions_2[] = {
++      [0] = llc_station_ac_report_status,     /* STATION UP */
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_down_state_trans_2 = {
++      .ev         = llc_stat_ev_enable_without_dup_addr_check,
++      .next_state = LLC_STATION_STATE_UP,
++      .ev_actions = llc_stat_down_state_actions_2,
++};
++
++/* array of pointers; one to each transition */
++static struct llc_station_state_trans *llc_stat_dwn_state_trans[] = {
++      [0] = &llc_stat_down_state_trans_1,
++      [1] = &llc_stat_down_state_trans_2,
++      [2] = &llc_stat_state_trans_end,
++};
++
++/* UP STATE transitions */
++/* state transition for LLC_STATION_EV_DISABLE_REQ event */
++static llc_station_action_t llc_stat_up_state_actions_1[] = {
++      [0] = llc_station_ac_report_status,     /* STATION DOWN */
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_up_state_trans_1 = {
++      .ev         = llc_stat_ev_disable_req,
++      .next_state = LLC_STATION_STATE_DOWN,
++      .ev_actions = llc_stat_up_state_actions_1,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
++static llc_station_action_t llc_stat_up_state_actions_2[] = {
++      [0] = llc_station_ac_send_xid_r,
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_up_state_trans_2 = {
++      .ev         = llc_stat_ev_rx_null_dsap_xid_c,
++      .next_state = LLC_STATION_STATE_UP,
++      .ev_actions = llc_stat_up_state_actions_2,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_TEST_C event */
++static llc_station_action_t llc_stat_up_state_actions_3[] = {
++      [0] = llc_station_ac_send_test_r,
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_up_state_trans_3 = {
++      .ev         = llc_stat_ev_rx_null_dsap_test_c,
++      .next_state = LLC_STATION_STATE_UP,
++      .ev_actions = llc_stat_up_state_actions_3,
++};
++
++/* array of pointers; one to each transition */
++static struct llc_station_state_trans *llc_stat_up_state_trans [] = {
++      [0] = &llc_stat_up_state_trans_1,
++      [1] = &llc_stat_up_state_trans_2,
++      [2] = &llc_stat_up_state_trans_3,
++      [3] = &llc_stat_state_trans_end,
++};
++
++/* DUP ADDR CHK STATE transitions */
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_1[] = {
++      [0] = llc_station_ac_inc_xid_r_cnt_by_1,
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_1 = {
++      .ev         = llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq,
++      .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++      .ev_actions = llc_stat_dupaddr_state_actions_1,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_2[] = {
++      [0] = llc_station_ac_report_status,     /* DUPLICATE ADDRESS FOUND */
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_2 = {
++      .ev         = llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq,
++      .next_state = LLC_STATION_STATE_DOWN,
++      .ev_actions = llc_stat_dupaddr_state_actions_2,
++};
++
++/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
++static llc_station_action_t llc_stat_dupaddr_state_actions_3[] = {
++      [0] = llc_station_ac_send_xid_r,
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_3 = {
++      .ev         = llc_stat_ev_rx_null_dsap_xid_c,
++      .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++      .ev_actions = llc_stat_dupaddr_state_actions_3,
++};
++
++/* state transition for LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_4[] = {
++      [0] = llc_station_ac_start_ack_timer,
++      [1] = llc_station_ac_inc_retry_cnt_by_1,
++      [2] = llc_station_ac_set_xid_r_cnt_0,
++      [3] = llc_station_ac_send_null_dsap_xid_c,
++      [4] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_4 = {
++      .ev         = llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry,
++      .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
++      .ev_actions = llc_stat_dupaddr_state_actions_4,
++};
++
++/* state transition for LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY
++ * event
++ */
++static llc_station_action_t llc_stat_dupaddr_state_actions_5[] = {
++      [0] = llc_station_ac_report_status,     /* STATION UP */
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_5 = {
++      .ev         = llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry,
++      .next_state = LLC_STATION_STATE_UP,
++      .ev_actions = llc_stat_dupaddr_state_actions_5,
++};
++
++/* state transition for LLC_STATION_EV_DISABLE_REQ event */
++static llc_station_action_t llc_stat_dupaddr_state_actions_6[] = {
++      [0] = llc_station_ac_report_status,     /* STATION DOWN */
++      [1] = NULL,
++};
++
++static struct llc_station_state_trans llc_stat_dupaddr_state_trans_6 = {
++      .ev         = llc_stat_ev_disable_req,
++      .next_state = LLC_STATION_STATE_DOWN,
++      .ev_actions = llc_stat_dupaddr_state_actions_6,
++};
++
++/* array of pointers; one to each transition */
++static struct llc_station_state_trans *llc_stat_dupaddr_state_trans[] = {
++      [0] = &llc_stat_dupaddr_state_trans_6,  /* Request */
++      [1] = &llc_stat_dupaddr_state_trans_4,  /* Timer */
++      [2] = &llc_stat_dupaddr_state_trans_5,
++      [3] = &llc_stat_dupaddr_state_trans_1,  /* Receive frame */
++      [4] = &llc_stat_dupaddr_state_trans_2,
++      [5] = &llc_stat_dupaddr_state_trans_3,
++      [6] = &llc_stat_state_trans_end,
++};
++
++static struct llc_station_state
++                      llc_station_state_table[LLC_NBR_STATION_STATES] = {
++      [LLC_STATION_STATE_DOWN - 1] = {
++              .curr_state  = LLC_STATION_STATE_DOWN,
++              .transitions = llc_stat_dwn_state_trans,
++      },
++      [LLC_STATION_STATE_DUP_ADDR_CHK - 1] = {
++              .curr_state  = LLC_STATION_STATE_DUP_ADDR_CHK,
++              .transitions = llc_stat_dupaddr_state_trans,
++      },
++      [LLC_STATION_STATE_UP - 1] = {
++              .curr_state  = LLC_STATION_STATE_UP,
++              .transitions = llc_stat_up_state_trans,
++      },
++};
++
++/**
++ *    llc_exec_station_trans_actions - executes actions for transition
++ *    @trans: Address of the transition
++ *    @skb: Address of the event that caused the transition
++ *
++ *    Executes actions of a transition of the station state machine. Returns
++ *    0 if all actions complete successfully, nonzero otherwise.
++ */
++static u16 llc_exec_station_trans_actions(struct llc_station_state_trans *trans,
++                                        struct sk_buff *skb)
++{
++      u16 rc = 0;
++      llc_station_action_t *next_action = trans->ev_actions;
++
++      for (; next_action && *next_action; next_action++)
++              if ((*next_action)(skb))
++                      rc = 1;
++      return rc;
++}
++
++/**
++ *    llc_find_station_trans - finds transition for this event
++ *    @skb: Address of the event
++ *
++ *    Search thru events of the current state of the station until list
++ *    exhausted or it's obvious that the event is not valid for the current
++ *    state. Returns the address of the transition if cound, %NULL otherwise.
++ */
++static struct llc_station_state_trans *
++                              llc_find_station_trans(struct sk_buff *skb)
++{
++      int i = 0;
++      struct llc_station_state_trans *rc = NULL;
++      struct llc_station_state_trans **next_trans;
++      struct llc_station_state *curr_state =
++                              &llc_station_state_table[llc_main_station.state - 1];
++
++      for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
++              if (!next_trans[i]->ev(skb)) {
++                      rc = next_trans[i];
++                      break;
++              }
++      return rc;
++}
++
++/**
++ *    llc_station_free_ev - frees an event
++ *    @skb: Address of the event
++ *
++ *    Frees an event.
++ */
++static void llc_station_free_ev(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++      if (ev->type == LLC_STATION_EV_TYPE_PDU)
++              kfree_skb(skb);
++}
++
++/**
++ *    llc_station_next_state - processes event and goes to the next state
++ *    @skb: Address of the event
++ *
++ *    Processes an event, executes any transitions related to that event and
++ *    updates the state of the station.
++ */
++static u16 llc_station_next_state(struct sk_buff *skb)
++{
++      u16 rc = 1;
++      struct llc_station_state_trans *trans;
++
++      if (llc_main_station.state > LLC_NBR_STATION_STATES)
++              goto out;
++      trans = llc_find_station_trans(skb);
++      if (trans) {
++              /* got the state to which we next transition; perform the
++               * actions associated with this transition before actually
++               * transitioning to the next state
++               */
++              rc = llc_exec_station_trans_actions(trans, skb);
++              if (!rc)
++                      /* transition station to next state if all actions
++                       * execute successfully; done; wait for next event
++                       */
++                      llc_main_station.state = trans->next_state;
++      } else
++              /* event not recognized in current state; re-queue it for
++               * processing again at a later time; return failure
++               */
++              rc = 0;
++out:
++      llc_station_free_ev(skb);
++      return rc;
++}
++
++/**
++ *    llc_station_service_events - service events in the queue
++ *
++ *    Get an event from the station event queue (if any); attempt to service
++ *    the event; if event serviced, get the next event (if any) on the event
++ *    queue; if event not service, re-queue the event on the event queue and
++ *    attempt to service the next event; when serviced all events in queue,
++ *    finished; if don't transition to different state, just service all
++ *    events once; if transition to new state, service all events again.
++ *    Caller must hold llc_main_station.ev_q.lock.
++ */
++static void llc_station_service_events(void)
++{
++      struct sk_buff *skb;
++
++      while ((skb = skb_dequeue(&llc_main_station.ev_q.list)) != NULL)
++              llc_station_next_state(skb);
++}
++
++/**
++ *    llc_station_state_process: queue event and try to process queue.
++ *    @skb: Address of the event
++ *
++ *    Queues an event (on the station event queue) for handling by the
++ *    station state machine and attempts to process any queued-up events.
++ */
++void llc_station_state_process(struct sk_buff *skb)
++{
++      spin_lock_bh(&llc_main_station.ev_q.lock);
++      skb_queue_tail(&llc_main_station.ev_q.list, skb);
++      llc_station_service_events();
++      spin_unlock_bh(&llc_main_station.ev_q.lock);
++}
++
++static void llc_station_ack_tmr_cb(unsigned long timeout_data)
++{
++      struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
++
++      if (skb) {
++              struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++              ev->type = LLC_STATION_EV_TYPE_ACK_TMR;
++              llc_station_state_process(skb);
++      }
++}
++
++/*
++ *    llc_station_rcv - send received pdu to the station state machine
++ *    @skb: received frame.
++ *
++ *    Sends data unit to station state machine.
++ */
++static void llc_station_rcv(struct sk_buff *skb)
++{
++      struct llc_station_state_ev *ev = llc_station_ev(skb);
++
++      ev->type   = LLC_STATION_EV_TYPE_PDU;
++      ev->reason = 0;
++      llc_station_state_process(skb);
++}
++
++int __init llc_station_init(void)
++{
++      u16 rc = -ENOBUFS;
++      struct sk_buff *skb;
++      struct llc_station_state_ev *ev;
++
++      skb_queue_head_init(&llc_main_station.mac_pdu_q);
++      skb_queue_head_init(&llc_main_station.ev_q.list);
++      spin_lock_init(&llc_main_station.ev_q.lock);
++      init_timer(&llc_main_station.ack_timer);
++      llc_main_station.ack_timer.data     = (unsigned long)&llc_main_station;
++      llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
++
++      skb = alloc_skb(0, GFP_ATOMIC);
++      if (!skb)
++              goto out;
++      rc = 0;
++      llc_set_station_handler(llc_station_rcv);
++      ev = llc_station_ev(skb);
++      memset(ev, 0, sizeof(*ev));
++      llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
++      llc_main_station.maximum_retry  = 1;
++      llc_main_station.state          = LLC_STATION_STATE_DOWN;
++      ev->type        = LLC_STATION_EV_TYPE_SIMPLE;
++      ev->prim_type   = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
++      rc = llc_station_next_state(skb);
++out:
++      return rc;
++}
++
++void __exit llc_station_exit(void)
++{
++      llc_set_station_handler(NULL);
++}
+Index: linux-2.6.0-test5/net/llc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/net/llc/Makefile    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/llc/Makefile 2003-09-27 11:38:42.132123328 +0800
+@@ -2,7 +2,7 @@
+ # Makefile for the Linux 802.2 LLC (fully-functional) layer.
+ #
+ # Copyright (c) 1997 by Procom Technology,Inc.
+-#             2001, 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
++#             2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ #
+ # This program can be redistributed or modified under the terms of the 
+ # GNU General Public License as published by the Free Software Foundation.
+@@ -14,7 +14,11 @@
+ obj-$(CONFIG_LLC) += llc.o
+-llc-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_mac.o llc_sap.o llc_s_st.o \
+-       llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \
+-       llc_s_ev.o llc_evnt.o llc_pdu.o llc_proc.o
+-llc-$(CONFIG_LLC_UI)  += af_llc.o
++llc-y := llc_core.o llc_input.o llc_output.o
++
++obj-$(CONFIG_LLC2) += llc2.o
++
++llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \
++        llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o
++
++llc2-$(CONFIG_PROC_FS) += llc_proc.o
+Index: linux-2.6.0-test5/net/netlink/af_netlink.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netlink/af_netlink.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netlink/af_netlink.c 2003-09-27 11:38:42.138122416 +0800
+@@ -988,7 +988,7 @@
+ static void *netlink_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       read_lock(&nl_table_lock);
+-      return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : (void *) 1;
++      return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -997,7 +997,7 @@
+       ++*pos;
+-      if (v == (void *) 1) 
++      if (v == SEQ_START_TOKEN)
+               return netlink_seq_socket_idx(seq, 0);
+               
+       s = sk_next(v);
+@@ -1023,7 +1023,7 @@
+ static int netlink_seq_show(struct seq_file *seq, void *v)
+ {
+-      if (v == (void *)1) 
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq,
+                        "sk       Eth Pid    Groups   "
+                        "Rmem     Wmem     Dump     Locks\n");
+Index: linux-2.6.0-test5/net/netrom/af_netrom.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/af_netrom.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/af_netrom.c   2003-09-27 11:38:42.147121048 +0800
+@@ -62,6 +62,7 @@
+ static spinlock_t nr_list_lock = SPIN_LOCK_UNLOCKED;
+ static struct proto_ops nr_proto_ops;
++void nr_init_timers(struct sock *sk);
+ static struct sock *nr_alloc_sock(void)
+ {
+@@ -279,17 +280,12 @@
+               kfree_skb(skb);
+       }
+-      while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
+-              kfree_skb(skb);
+-      }
+       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 + 2 * HZ;
+               sk->sk_timer.function = nr_destroy_timer;
+-              sk->sk_timer.data     = (unsigned long)sk;
++              sk->sk_timer.expires  = jiffies + 2 * HZ;
+               add_timer(&sk->sk_timer);
+       } else
+               sock_put(sk);
+@@ -442,10 +438,7 @@
+       skb_queue_head_init(&nr->reseq_queue);
+       skb_queue_head_init(&nr->frag_queue);
+-      init_timer(&nr->t1timer);
+-      init_timer(&nr->t2timer);
+-      init_timer(&nr->t4timer);
+-      init_timer(&nr->idletimer);
++      nr_init_timers(sk);
+       nr->t1     = sysctl_netrom_transport_timeout;
+       nr->t2     = sysctl_netrom_transport_acknowledge_delay;
+@@ -491,10 +484,7 @@
+       skb_queue_head_init(&nr->reseq_queue);
+       skb_queue_head_init(&nr->frag_queue);
+-      init_timer(&nr->t1timer);
+-      init_timer(&nr->t2timer);
+-      init_timer(&nr->t4timer);
+-      init_timer(&nr->idletimer);
++      nr_init_timers(sk);
+       onr = nr_sk(osk);
+@@ -1241,8 +1231,6 @@
+ #ifdef CONFIG_PROC_FS
+-/* Marker for header entry */
+-#define NETROM_PROC_START     ((void *)1)
+ static void *nr_info_start(struct seq_file *seq, loff_t *pos)
+ {
+       struct sock *s;
+@@ -1251,7 +1239,7 @@
+       spin_lock_bh(&nr_list_lock);
+       if (*pos == 0)
+-              return NETROM_PROC_START;
++              return SEQ_START_TOKEN;
+       sk_for_each(s, node, &nr_list) {
+               if (i == *pos)
+@@ -1265,7 +1253,7 @@
+ {
+       ++*pos;
+-      return (v == NETROM_PROC_START) ? sk_head(&nr_list) 
++      return (v == SEQ_START_TOKEN) ? sk_head(&nr_list) 
+               : sk_next((struct sock *)v);
+ }
+       
+@@ -1281,7 +1269,7 @@
+       nr_cb *nr;
+       const char *devname;
+-      if (v == NETROM_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq,
+ "user_addr dest_node src_node  dev    my  your  st  vs  vr  va    t1     t2     t4      idle   n2  wnd Snd-Q Rcv-Q inode\n");
+Index: linux-2.6.0-test5/net/netrom/nr_loopback.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/nr_loopback.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/nr_loopback.c 2003-09-27 11:38:42.148120896 +0800
+@@ -14,19 +14,17 @@
+ #include <net/netrom.h>
+ #include <linux/init.h>
+-static struct sk_buff_head loopback_queue;
+-static struct timer_list loopback_timer;
++static void nr_loopback_timer(unsigned long);
+-static void nr_set_loopback_timer(void);
++static struct sk_buff_head loopback_queue;
++static struct timer_list loopback_timer = TIMER_INITIALIZER(nr_loopback_timer, 0, 0);
+-void nr_loopback_init(void)
++void __init nr_loopback_init(void)
+ {
+       skb_queue_head_init(&loopback_queue);
+-
+-      init_timer(&loopback_timer);
+ }
+-static int nr_loopback_running(void)
++static inline int nr_loopback_running(void)
+ {
+       return timer_pending(&loopback_timer);
+ }
+@@ -42,26 +40,13 @@
+               skb_queue_tail(&loopback_queue, skbn);
+               if (!nr_loopback_running())
+-                      nr_set_loopback_timer();
++                      mod_timer(&loopback_timer, jiffies + 10);
+       }
+       kfree_skb(skb);
+       return 1;
+ }
+-static void nr_loopback_timer(unsigned long);
+-
+-static void nr_set_loopback_timer(void)
+-{
+-      del_timer(&loopback_timer);
+-
+-      loopback_timer.data     = 0;
+-      loopback_timer.function = &nr_loopback_timer;
+-      loopback_timer.expires  = jiffies + 10;
+-
+-      add_timer(&loopback_timer);
+-}
+-
+ static void nr_loopback_timer(unsigned long param)
+ {
+       struct sk_buff *skb;
+@@ -80,12 +65,12 @@
+                       dev_put(dev);
+               if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
+-                      nr_set_loopback_timer();
++                      mod_timer(&loopback_timer, jiffies + 10);
+       }
+ }
+ void __exit nr_loopback_clear(void)
+ {
+-      del_timer(&loopback_timer);
++      del_timer_sync(&loopback_timer);
+       skb_queue_purge(&loopback_queue);
+ }
+Index: linux-2.6.0-test5/net/netrom/nr_route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/nr_route.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/nr_route.c    2003-09-27 11:38:42.155119832 +0800
+@@ -841,7 +841,6 @@
+ }
+ #ifdef CONFIG_PROC_FS
+-#define NETROM_PROC_START     ((void *) 1)
+ static void *nr_node_start(struct seq_file *seq, loff_t *pos)
+ {
+@@ -851,7 +850,7 @@
+  
+       spin_lock_bh(&nr_node_list_lock);
+       if (*pos == 0)
+-              return NETROM_PROC_START;
++              return SEQ_START_TOKEN;
+       nr_node_for_each(nr_node, node, &nr_node_list) {
+               if (i == *pos)
+@@ -867,7 +866,7 @@
+       struct hlist_node *node;
+       ++*pos;
+       
+-      node = (v == NETROM_PROC_START)  
++      node = (v == SEQ_START_TOKEN)  
+               ? nr_node_list.first
+               : ((struct nr_node *)v)->node_node.next;
+@@ -883,7 +882,7 @@
+ {
+       int i;
+-      if (v == NETROM_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq,
+                        "callsign  mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
+       else {
+@@ -936,7 +935,7 @@
+       spin_lock_bh(&nr_neigh_list_lock);
+       if (*pos == 0)
+-              return NETROM_PROC_START;
++              return SEQ_START_TOKEN;
+       nr_neigh_for_each(nr_neigh, node, &nr_neigh_list) {
+               if (i == *pos)
+@@ -950,7 +949,7 @@
+       struct hlist_node *node;
+       ++*pos;
+       
+-      node = (v == NETROM_PROC_START)  
++      node = (v == SEQ_START_TOKEN)  
+               ? nr_neigh_list.first
+               : ((struct nr_neigh *)v)->neigh_node.next;
+@@ -966,7 +965,7 @@
+ {
+       int i;
+-      if (v == NETROM_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "addr  callsign  dev  qual lock count failed digipeaters\n");
+       else {
+               struct nr_neigh *nr_neigh = v;
+Index: linux-2.6.0-test5/net/netrom/nr_timer.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netrom/nr_timer.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netrom/nr_timer.c    2003-09-27 11:38:42.157119528 +0800
+@@ -36,69 +36,63 @@
+ static void nr_t4timer_expiry(unsigned long);
+ static void nr_idletimer_expiry(unsigned long);
+-void nr_start_t1timer(struct sock *sk)
++void nr_init_timers(struct sock *sk)
+ {
+       nr_cb *nr = nr_sk(sk);
+-      del_timer(&nr->t1timer);
+-
++      init_timer(&nr->t1timer);
+       nr->t1timer.data     = (unsigned long)sk;
+       nr->t1timer.function = &nr_t1timer_expiry;
+-      nr->t1timer.expires  = jiffies + nr->t1;
++      
++      init_timer(&nr->t2timer);
++      nr->t2timer.data     = (unsigned long)sk;
++      nr->t2timer.function = &nr_t2timer_expiry;
++
++      init_timer(&nr->t4timer);
++      nr->t4timer.data     = (unsigned long)sk;
++      nr->t4timer.function = &nr_t4timer_expiry;
++
++      init_timer(&nr->idletimer);
++      nr->idletimer.data     = (unsigned long)sk;
++      nr->idletimer.function = &nr_idletimer_expiry;
+-      add_timer(&nr->t1timer);
++      /* initialized by sock_init_data */
++      sk->sk_timer.data     = (unsigned long)sk;
++      sk->sk_timer.function = &nr_heartbeat_expiry;
+ }
+-void nr_start_t2timer(struct sock *sk)
++void nr_start_t1timer(struct sock *sk)
+ {
+       nr_cb *nr = nr_sk(sk);
+-      del_timer(&nr->t2timer);
++      mod_timer(&nr->t1timer, jiffies + nr->t1);
++}
+-      nr->t2timer.data     = (unsigned long)sk;
+-      nr->t2timer.function = &nr_t2timer_expiry;
+-      nr->t2timer.expires  = jiffies + nr->t2;
++void nr_start_t2timer(struct sock *sk)
++{
++      nr_cb *nr = nr_sk(sk);
+-      add_timer(&nr->t2timer);
++      mod_timer(&nr->t2timer, jiffies + nr->t2);
+ }
+ void nr_start_t4timer(struct sock *sk)
+ {
+       nr_cb *nr = nr_sk(sk);
+-      del_timer(&nr->t4timer);
+-
+-      nr->t4timer.data     = (unsigned long)sk;
+-      nr->t4timer.function = &nr_t4timer_expiry;
+-      nr->t4timer.expires  = jiffies + nr->t4;
+-
+-      add_timer(&nr->t4timer);
++      mod_timer(&nr->t4timer, jiffies + nr->t4);
+ }
+ void nr_start_idletimer(struct sock *sk)
+ {
+       nr_cb *nr = nr_sk(sk);
+-      del_timer(&nr->idletimer);
+-
+-      if (nr->idle > 0) {
+-              nr->idletimer.data     = (unsigned long)sk;
+-              nr->idletimer.function = &nr_idletimer_expiry;
+-              nr->idletimer.expires  = jiffies + nr->idle;
+-
+-              add_timer(&nr->idletimer);
+-      }
++      if (nr->idle > 0)
++              mod_timer(&nr->idletimer, jiffies + nr->idle);
+ }
+ void nr_start_heartbeat(struct sock *sk)
+ {
+-      del_timer(&sk->sk_timer);
+-
+-      sk->sk_timer.data     = (unsigned long)sk;
+-      sk->sk_timer.function = &nr_heartbeat_expiry;
+-      sk->sk_timer.expires  = jiffies + 5 * HZ;
+-
+-      add_timer(&sk->sk_timer);
++      mod_timer(&sk->sk_timer, jiffies + 5 * HZ);
+ }
+ void nr_stop_t1timer(struct sock *sk)
+Index: linux-2.6.0-test5/net/netsyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/netsyms.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/netsyms.c    2003-09-27 11:38:42.163118616 +0800
+@@ -511,7 +511,7 @@
+ EXPORT_SYMBOL(dev_add_pack);
+ EXPORT_SYMBOL(dev_remove_pack);
+ EXPORT_SYMBOL(__dev_remove_pack);
+-EXPORT_SYMBOL(dev_get);
++EXPORT_SYMBOL(__dev_get);
+ EXPORT_SYMBOL(dev_alloc);
+ EXPORT_SYMBOL(dev_alloc_name);
+ EXPORT_SYMBOL(__netdev_watchdog_up);
+Index: linux-2.6.0-test5/net/packet/af_packet.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/packet/af_packet.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/packet/af_packet.c   2003-09-27 11:38:42.173117096 +0800
+@@ -381,6 +381,23 @@
+ }
+ #endif
++static inline unsigned run_filter(struct sk_buff *skb, struct sock *sk, unsigned res)
++{
++      struct sk_filter *filter;
++
++      bh_lock_sock(sk);
++      filter = sk->sk_filter;
++      /*
++       * Our caller already checked that filter != NULL but we need to
++       * verify that under bh_lock_sock() to be safe
++       */
++      if (likely(filter != NULL))
++              res = sk_run_filter(skb, filter->insns, filter->len);
++      bh_unlock_sock(sk);
++
++      return res;
++}
++
+ /*
+    This function makes lazy skb cloning in hope that most of packets
+    are discarded by BPF.
+@@ -429,15 +446,7 @@
+       snaplen = skb->len;
+       if (sk->sk_filter) {
+-              unsigned res = snaplen;
+-              struct sk_filter *filter;
+-
+-              bh_lock_sock(sk);
+-              if ((filter = sk->sk_filter) != NULL)
+-                      res = sk_run_filter(skb, sk->sk_filter->insns,
+-                                          sk->sk_filter->len);
+-              bh_unlock_sock(sk);
+-
++              unsigned res = run_filter(skb, sk, snaplen);
+               if (res == 0)
+                       goto drop_n_restore;
+               if (snaplen > res)
+@@ -533,15 +542,7 @@
+       snaplen = skb->len;
+       if (sk->sk_filter) {
+-              unsigned res = snaplen;
+-              struct sk_filter *filter;
+-
+-              bh_lock_sock(sk);
+-              if ((filter = sk->sk_filter) != NULL)
+-                      res = sk_run_filter(skb, sk->sk_filter->insns,
+-                                          sk->sk_filter->len);
+-              bh_unlock_sock(sk);
+-
++              unsigned res = run_filter(skb, sk, snaplen);
+               if (res == 0)
+                       goto drop_n_restore;
+               if (snaplen > res)
+Index: linux-2.6.0-test5/net/rose/af_rose.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rose/af_rose.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rose/af_rose.c       2003-09-27 11:38:42.183115576 +0800
+@@ -1344,7 +1344,7 @@
+       spin_lock_bh(&rose_list_lock);
+       if (*pos == 0)
+-              return ROSE_PROC_START;
++              return SEQ_START_TOKEN;
+       
+       i = 1;
+       sk_for_each(s, node, &rose_list) {
+@@ -1359,7 +1359,7 @@
+ {
+       ++*pos;
+-      return (v == ROSE_PROC_START) ? sk_head(&rose_list) 
++      return (v == SEQ_START_TOKEN) ? sk_head(&rose_list) 
+               : sk_next((struct sock *)v);
+ }
+       
+@@ -1370,7 +1370,7 @@
+ static int rose_info_show(struct seq_file *seq, void *v)
+ {
+-      if (v == ROSE_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, 
+                        "dest_addr  dest_call src_addr   src_call  dev   lci neigh st vs vr va   t  t1  t2  t3  hb    idle Snd-Q Rcv-Q inode\n");
+Index: linux-2.6.0-test5/net/rose/rose_route.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rose/rose_route.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rose/rose_route.c    2003-09-27 11:38:42.191114360 +0800
+@@ -1076,7 +1076,7 @@
+       spin_lock_bh(&rose_neigh_list_lock);
+       if (*pos == 0)
+-              return ROSE_PROC_START;
++              return SEQ_START_TOKEN;
+       for (rose_node = rose_node_list; rose_node && i < *pos; 
+            rose_node = rose_node->next, ++i);
+@@ -1088,7 +1088,7 @@
+ {
+       ++*pos;
+       
+-      return (v == ROSE_PROC_START) ? rose_node_list 
++      return (v == SEQ_START_TOKEN) ? rose_node_list 
+               : ((struct rose_node *)v)->next;
+ }
+@@ -1101,7 +1101,7 @@
+ {
+       int i;
+-      if (v == ROSE_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "address    mask n neigh neigh neigh\n");
+       else {
+               const struct rose_node *rose_node = v;
+@@ -1152,7 +1152,7 @@
+       spin_lock_bh(&rose_neigh_list_lock);
+       if (*pos == 0)
+-              return ROSE_PROC_START;
++              return SEQ_START_TOKEN;
+       for (rose_neigh = rose_neigh_list; rose_neigh && i < *pos; 
+            rose_neigh = rose_neigh->next, ++i);
+@@ -1164,7 +1164,7 @@
+ {
+       ++*pos;
+       
+-      return (v == ROSE_PROC_START) ? rose_neigh_list 
++      return (v == SEQ_START_TOKEN) ? rose_neigh_list 
+               : ((struct rose_neigh *)v)->next;
+ }
+@@ -1177,7 +1177,7 @@
+ {
+       int i;
+-      if (v == ROSE_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, 
+                        "addr  callsign  dev  count use mode restart  t0  tf digipeaters\n");
+       else {
+@@ -1234,7 +1234,7 @@
+       spin_lock_bh(&rose_route_list_lock);
+       if (*pos == 0)
+-              return ROSE_PROC_START;
++              return SEQ_START_TOKEN;
+       for (rose_route = rose_route_list; rose_route && i < *pos; 
+            rose_route = rose_route->next, ++i);
+@@ -1246,7 +1246,7 @@
+ {
+       ++*pos;
+       
+-      return (v == ROSE_PROC_START) ? rose_route_list 
++      return (v == SEQ_START_TOKEN) ? rose_route_list 
+               : ((struct rose_route *)v)->next;
+ }
+@@ -1257,7 +1257,7 @@
+ static int rose_route_show(struct seq_file *seq, void *v)
+ {
+-      if (v == ROSE_PROC_START)
++      if (v == SEQ_START_TOKEN)
+               seq_puts(seq, 
+                        "lci  address     callsign   neigh  <-> lci  address     callsign   neigh\n");
+       else {
+Index: linux-2.6.0-test5/net/rxrpc/call.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/call.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/call.c 2003-09-27 11:38:42.211111320 +0800
+@@ -53,20 +53,25 @@
+ };
+ const char *rxrpc_pkts[] = {
+-      "?00", "data", "ack", "busy", "abort", "ackall", "chall", "resp", "debug",
++      "?00",
++      "data", "ack", "busy", "abort", "ackall", "chall", "resp", "debug",
+       "?09", "?10", "?11", "?12", "?13", "?14", "?15"
+ };
+ const char *rxrpc_acks[] = {
+-      "---", "REQ", "DUP", "SEQ", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL", "-?-"
++      "---", "REQ", "DUP", "SEQ", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL",
++      "-?-"
+ };
+ static const char _acktype[] = "NA-";
+ static void rxrpc_call_receive_packet(struct rxrpc_call *call);
+-static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc_message *msg);
+-static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_message *msg);
+-static void rxrpc_call_definitively_ACK(struct rxrpc_call *call, rxrpc_seq_t higest);
++static void rxrpc_call_receive_data_packet(struct rxrpc_call *call,
++                                         struct rxrpc_message *msg);
++static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call,
++                                        struct rxrpc_message *msg);
++static void rxrpc_call_definitively_ACK(struct rxrpc_call *call,
++                                      rxrpc_seq_t higest);
+ static void rxrpc_call_resend(struct rxrpc_call *call, rxrpc_seq_t highest);
+ static int __rxrpc_call_read_data(struct rxrpc_call *call);
+@@ -75,7 +80,7 @@
+                                rxrpc_seq_t seq,
+                                size_t count);
+ #define _state(call) \
+-      _debug("[[[ state %s ]]]",rxrpc_call_states[call->app_call_state]);
++      _debug("[[[ state %s ]]]", rxrpc_call_states[call->app_call_state]);
+ static void rxrpc_call_default_attn_func(struct rxrpc_call *call)
+ {
+@@ -103,7 +108,7 @@
+ {
+       struct rxrpc_call *call = (struct rxrpc_call *) _call;
+-      _debug("ACKS TIMEOUT %05lu",jiffies - call->cjif);
++      _debug("ACKS TIMEOUT %05lu", jiffies - call->cjif);
+       call->flags |= RXRPC_CALL_ACKS_TIMO;
+       rxrpc_krxiod_queue_call(call);
+@@ -113,7 +118,7 @@
+ {
+       struct rxrpc_call *call = (struct rxrpc_call *) _call;
+-      _debug("RCV TIMEOUT %05lu",jiffies - call->cjif);
++      _debug("RCV TIMEOUT %05lu", jiffies - call->cjif);
+       call->flags |= RXRPC_CALL_RCV_TIMO;
+       rxrpc_krxiod_queue_call(call);
+@@ -133,15 +138,18 @@
+ /*
+  * calculate a timeout based on an RTT value
+  */
+-static inline unsigned long __rxrpc_rtt_based_timeout(struct rxrpc_call *call, unsigned long val)
++static inline unsigned long __rxrpc_rtt_based_timeout(struct rxrpc_call *call,
++                                                    unsigned long val)
+ {
+-      unsigned long expiry = call->conn->peer->rtt / (1000000/HZ);
++      unsigned long expiry = call->conn->peer->rtt / (1000000 / HZ);
+       expiry += 10;
+-      if (expiry<HZ/25) expiry = HZ/25;
+-      if (expiry>HZ) expiry = HZ;
++      if (expiry < HZ / 25)
++              expiry = HZ / 25;
++      if (expiry > HZ)
++              expiry = HZ;
+-      _leave(" = %lu jiffies",expiry);
++      _leave(" = %lu jiffies", expiry);
+       return jiffies + expiry;
+ } /* end __rxrpc_rtt_based_timeout() */
+@@ -154,7 +162,7 @@
+ {
+       struct rxrpc_call *call;
+-      _enter("%p",conn);
++      _enter("%p", conn);
+       /* allocate and initialise a call record */
+       call = (struct rxrpc_call *) get_zeroed_page(GFP_KERNEL);
+@@ -163,7 +171,7 @@
+               return -ENOMEM;
+       }
+-      atomic_set(&call->usage,1);
++      atomic_set(&call->usage, 1);
+       init_waitqueue_head(&call->waitq);
+       spin_lock_init(&call->lock);
+@@ -200,7 +208,7 @@
+       call->cjif = jiffies;
+-      _leave(" = 0 (%p)",call);
++      _leave(" = 0 (%p)", call);
+       *_call = call;
+@@ -217,34 +225,37 @@
+                     rxrpc_call_aemap_func_t aemap,
+                     struct rxrpc_call **_call)
+ {
+-      DECLARE_WAITQUEUE(myself,current);
++      DECLARE_WAITQUEUE(myself, current);
+       struct rxrpc_call *call;
+       int ret, cix, loop;
+-      _enter("%p",conn);
++      _enter("%p", conn);
+       /* allocate and initialise a call record */
+-      ret = __rxrpc_create_call(conn,&call);
+-      if (ret<0) {
+-              _leave(" = %d",ret);
++      ret = __rxrpc_create_call(conn, &call);
++      if (ret < 0) {
++              _leave(" = %d", ret);
+               return ret;
+       }
+       call->app_call_state = RXRPC_CSTATE_CLNT_SND_ARGS;
+-      if (attn) call->app_attn_func = attn;
+-      if (error) call->app_error_func = error;
+-      if (aemap) call->app_aemap_func = aemap;
++      if (attn)
++              call->app_attn_func = attn;
++      if (error)
++              call->app_error_func = error;
++      if (aemap)
++              call->app_aemap_func = aemap;
+       _state(call);
+       spin_lock(&conn->lock);
+       set_current_state(TASK_INTERRUPTIBLE);
+-      add_wait_queue(&conn->chanwait,&myself);
++      add_wait_queue(&conn->chanwait, &myself);
+  try_again:
+       /* try to find an unused channel */
+-      for (cix=0; cix<4; cix++)
++      for (cix = 0; cix < 4; cix++)
+               if (!conn->channels[cix])
+                       goto obtained_chan;
+@@ -263,14 +274,15 @@
+       /* got a channel - now attach to the connection */
+  obtained_chan:
+-      remove_wait_queue(&conn->chanwait,&myself);
++      remove_wait_queue(&conn->chanwait, &myself);
+       set_current_state(TASK_RUNNING);
+       /* concoct a unique call number */
+  next_callid:
+       call->call_id = htonl(++conn->call_counter);
+-      for (loop=0; loop<4; loop++)
+-              if (conn->channels[loop] && conn->channels[loop]->call_id==call->call_id)
++      for (loop = 0; loop < 4; loop++)
++              if (conn->channels[loop] &&
++                  conn->channels[loop]->call_id == call->call_id)
+                       goto next_callid;
+       rxrpc_get_connection(conn);
+@@ -281,24 +293,23 @@
+       spin_unlock(&conn->lock);
+       down_write(&rxrpc_calls_sem);
+-      list_add_tail(&call->call_link,&rxrpc_calls);
++      list_add_tail(&call->call_link, &rxrpc_calls);
+       up_write(&rxrpc_calls_sem);
+       __RXACCT(atomic_inc(&rxrpc_call_count));
+       *_call = call;
+-      _leave(" = 0 (call=%p cix=%u)",call,cix);
++      _leave(" = 0 (call=%p cix=%u)", call, cix);
+       return 0;
+  error_unwait:
+-      remove_wait_queue(&conn->chanwait,&myself);
++      remove_wait_queue(&conn->chanwait, &myself);
+       set_current_state(TASK_RUNNING);
+       spin_unlock(&conn->lock);
+-      free_page((unsigned long)call);
+-      _leave(" = %d",ret);
++      free_page((unsigned long) call);
++      _leave(" = %d", ret);
+       return ret;
+-
+ } /* end rxrpc_create_call() */
+ /*****************************************************************************/
+@@ -315,18 +326,18 @@
+       cix = ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK;
+-      _enter("%p,%u,%u",conn,ntohl(msg->hdr.callNumber),cix);
++      _enter("%p,%u,%u", conn, ntohl(msg->hdr.callNumber), cix);
+       /* allocate and initialise a call record */
+-      ret = __rxrpc_create_call(conn,&call);
+-      if (ret<0) {
+-              _leave(" = %d",ret);
++      ret = __rxrpc_create_call(conn, &call);
++      if (ret < 0) {
++              _leave(" = %d", ret);
+               return ret;
+       }
+       call->pkt_rcv_count = 1;
+       call->app_call_state = RXRPC_CSTATE_SRVR_RCV_OPID;
+-      call->app_mark = sizeof(u32);
++      call->app_mark = sizeof(uint32_t);
+       _state(call);
+@@ -348,20 +359,20 @@
+       spin_unlock(&conn->lock);
+-      if (ret<0) {
+-              free_page((unsigned long)call);
++      if (ret < 0) {
++              free_page((unsigned long) call);
+               call = NULL;
+       }
+-      if (ret==0) {
++      if (ret == 0) {
+               down_write(&rxrpc_calls_sem);
+-              list_add_tail(&call->call_link,&rxrpc_calls);
++              list_add_tail(&call->call_link, &rxrpc_calls);
+               up_write(&rxrpc_calls_sem);
+               __RXACCT(atomic_inc(&rxrpc_call_count));
+               *_call = call;
+       }
+-      _leave(" = %d [%p]",ret,call);
++      _leave(" = %d [%p]", ret, call);
+       return ret;
+ } /* end rxrpc_incoming_call() */
+@@ -377,10 +388,11 @@
+       _enter("%p{u=%d}",call,atomic_read(&call->usage));
+       /* sanity check */
+-      if (atomic_read(&call->usage)<=0)
++      if (atomic_read(&call->usage) <= 0)
+               BUG();
+-      /* to prevent a race, the decrement and the de-list must be effectively atomic */
++      /* to prevent a race, the decrement and the de-list must be effectively
++       * atomic */
+       spin_lock(&conn->lock);
+       if (likely(!atomic_dec_and_test(&call->usage))) {
+               spin_unlock(&conn->lock);
+@@ -388,7 +400,7 @@
+               return;
+       }
+-      if (conn->channels[ntohl(call->chan_ix)]==call)
++      if (conn->channels[ntohl(call->chan_ix)] == call)
+               conn->channels[ntohl(call->chan_ix)] = NULL;
+       spin_unlock(&conn->lock);
+@@ -412,25 +424,29 @@
+               rxrpc_put_message(call->snd_ping);
+       while (!list_empty(&call->acks_pendq)) {
+-              msg = list_entry(call->acks_pendq.next,struct rxrpc_message,link);
++              msg = list_entry(call->acks_pendq.next,
++                               struct rxrpc_message, link);
+               list_del(&msg->link);
+               rxrpc_put_message(msg);
+       }
+       while (!list_empty(&call->rcv_receiveq)) {
+-              msg = list_entry(call->rcv_receiveq.next,struct rxrpc_message,link);
++              msg = list_entry(call->rcv_receiveq.next,
++                               struct rxrpc_message, link);
+               list_del(&msg->link);
+               rxrpc_put_message(msg);
+       }
+       while (!list_empty(&call->app_readyq)) {
+-              msg = list_entry(call->app_readyq.next,struct rxrpc_message,link);
++              msg = list_entry(call->app_readyq.next,
++                               struct rxrpc_message, link);
+               list_del(&msg->link);
+               rxrpc_put_message(msg);
+       }
+       while (!list_empty(&call->app_unreadyq)) {
+-              msg = list_entry(call->app_unreadyq.next,struct rxrpc_message,link);
++              msg = list_entry(call->app_unreadyq.next,
++                               struct rxrpc_message, link);
+               list_del(&msg->link);
+               rxrpc_put_message(msg);
+       }
+@@ -442,7 +458,7 @@
+       up_write(&rxrpc_calls_sem);
+       __RXACCT(atomic_dec(&rxrpc_call_count));
+-      free_page((unsigned long)call);
++      free_page((unsigned long) call);
+       _leave(" [destroyed]");
+ } /* end rxrpc_put_call() */
+@@ -451,7 +467,8 @@
+ /*
+  * actually generate a normal ACK
+  */
+-static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call, rxrpc_seq_t seq)
++static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call,
++                                            rxrpc_seq_t seq)
+ {
+       struct rxrpc_message *msg;
+       struct iovec diov[3];
+@@ -478,35 +495,36 @@
+       diov[0].iov_len  = sizeof(struct rxrpc_ackpacket);
+       diov[0].iov_base = &call->ackr;
+-      diov[1].iov_len  = (call->ackr_pend_cnt+3);
++      diov[1].iov_len  = call->ackr_pend_cnt + 3;
+       diov[1].iov_base = call->ackr_array;
+       diov[2].iov_len  = sizeof(aux);
+       diov[2].iov_base = &aux;
+       /* build and send the message */
+-      ret = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_ACK,3,diov,GFP_KERNEL,&msg);
+-      if (ret<0)
++      ret = rxrpc_conn_newmsg(call->conn,call, RXRPC_PACKET_TYPE_ACK,
++                              3, diov, GFP_KERNEL, &msg);
++      if (ret < 0)
+               goto out;
+       msg->seq = seq;
+       msg->hdr.seq = htonl(seq);
+       msg->hdr.flags |= RXRPC_SLOW_START_OK;
+-      ret = rxrpc_conn_sendmsg(call->conn,msg);
++      ret = rxrpc_conn_sendmsg(call->conn, msg);
+       rxrpc_put_message(msg);
+-      if (ret<0)
++      if (ret < 0)
+               goto out;
+       call->pkt_snd_count++;
+       /* count how many actual ACKs there were at the front */
+-      for (delta=0; delta<call->ackr_pend_cnt; delta++)
+-              if (call->ackr_array[delta]!=RXRPC_ACK_TYPE_ACK)
++      for (delta = 0; delta < call->ackr_pend_cnt; delta++)
++              if (call->ackr_array[delta] != RXRPC_ACK_TYPE_ACK)
+                       break;
+       call->ackr_pend_cnt -= delta; /* all ACK'd to this point */
+       /* crank the ACK window around */
+-      if (delta==0) {
++      if (delta == 0) {
+               /* un-ACK'd window */
+       }
+       else if (delta < RXRPC_CALL_ACK_WINDOW_SIZE) {
+@@ -528,22 +546,26 @@
+               /* fully ACK'd window
+                * - just clear the whole thing
+                */
+-              memset(&call->ackr_array,RXRPC_ACK_TYPE_NACK,sizeof(call->ackr_array));
++              memset(&call->ackr_array,
++                     RXRPC_ACK_TYPE_NACK,
++                     sizeof(call->ackr_array));
+       }
+       /* clear this ACK */
+-      memset(&call->ackr,0,sizeof(call->ackr));
++      memset(&call->ackr, 0, sizeof(call->ackr));
+  out:
+-      if (!call->app_call_state) printk("___ STATE 0 ___\n");
++      if (!call->app_call_state)
++              printk("___ STATE 0 ___\n");
+       return ret;
+ } /* end __rxrpc_call_gen_normal_ACK() */
+ /*****************************************************************************/
+ /*
+- * note the reception of a packet in the call's ACK records and generate an appropriate ACK packet
+- * if necessary
+- * - returns 0 if packet should be processed, 1 if packet should be ignored and -ve on an error
++ * note the reception of a packet in the call's ACK records and generate an
++ * appropriate ACK packet if necessary
++ * - returns 0 if packet should be processed, 1 if packet should be ignored
++ *   and -ve on an error
+  */
+ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
+                                  struct rxrpc_header *hdr,
+@@ -555,19 +577,20 @@
+       int ret = 0, err;
+       u8 special_ACK, do_ACK, force;
+-      _enter("%p,%p { seq=%d tp=%d fl=%02x }",call,hdr,ntohl(hdr->seq),hdr->type,hdr->flags);
++      _enter("%p,%p { seq=%d tp=%d fl=%02x }",
++             call, hdr, ntohl(hdr->seq), hdr->type, hdr->flags);
+       seq = ntohl(hdr->seq);
+       offset = seq - call->ackr_win_bot;
+       do_ACK = RXRPC_ACK_DELAY;
+       special_ACK = 0;
+-      force = (seq==1);
++      force = (seq == 1);
+       if (call->ackr_high_seq < seq)
+               call->ackr_high_seq = seq;
+       /* deal with generation of obvious special ACKs first */
+-      if (ack && ack->reason==RXRPC_ACK_PING) {
++      if (ack && ack->reason == RXRPC_ACK_PING) {
+               special_ACK = RXRPC_ACK_PING_RESPONSE;
+               ret = 1;
+               goto gen_ACK;
+@@ -594,9 +617,9 @@
+       /* okay... it's a normal data packet inside the ACK window */
+       call->ackr_array[offset] = RXRPC_ACK_TYPE_ACK;
+-      if (offset<call->ackr_pend_cnt) {
++      if (offset < call->ackr_pend_cnt) {
+       }
+-      else if (offset>call->ackr_pend_cnt) {
++      else if (offset > call->ackr_pend_cnt) {
+               do_ACK = RXRPC_ACK_OUT_OF_SEQUENCE;
+               call->ackr_pend_cnt = offset;
+               goto gen_ACK;
+@@ -616,8 +639,8 @@
+       }
+       /* re-ACK packets previously received out-of-order */
+-      for (offset++; offset<RXRPC_CALL_ACK_WINDOW_SIZE; offset++)
+-              if (call->ackr_array[offset]!=RXRPC_ACK_TYPE_ACK)
++      for (offset++; offset < RXRPC_CALL_ACK_WINDOW_SIZE; offset++)
++              if (call->ackr_array[offset] != RXRPC_ACK_TYPE_ACK)
+                       break;
+       call->ackr_pend_cnt = offset;
+@@ -629,55 +652,61 @@
+  gen_ACK:
+       _debug("%05lu ACKs pend=%u norm=%s special=%s%s",
+              jiffies - call->cjif,
+-             call->ackr_pend_cnt,rxrpc_acks[do_ACK],rxrpc_acks[special_ACK],
++             call->ackr_pend_cnt,
++             rxrpc_acks[do_ACK],
++             rxrpc_acks[special_ACK],
+              force ? " immediate" :
+-             do_ACK==RXRPC_ACK_REQUESTED ? " merge-req" :
++             do_ACK == RXRPC_ACK_REQUESTED ? " merge-req" :
+              hdr->flags & RXRPC_LAST_PACKET ? " finalise" :
+              " defer"
+              );
+       /* send any pending normal ACKs if need be */
+-      if (call->ackr_pend_cnt>0) {
++      if (call->ackr_pend_cnt > 0) {
+               /* fill out the appropriate form */
+-              call->ackr.bufferSpace          = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
+-              call->ackr.maxSkew              = htons(min(call->ackr_high_seq - seq,65535U));
+-              call->ackr.firstPacket          = htonl(call->ackr_win_bot);
+-              call->ackr.previousPacket       = call->ackr_prev_seq;
+-              call->ackr.serial               = hdr->serial;
+-              call->ackr.nAcks                = call->ackr_pend_cnt;
++              call->ackr.bufferSpace  = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
++              call->ackr.maxSkew      = htons(min(call->ackr_high_seq - seq,
++                                                  65535U));
++              call->ackr.firstPacket  = htonl(call->ackr_win_bot);
++              call->ackr.previousPacket = call->ackr_prev_seq;
++              call->ackr.serial       = hdr->serial;
++              call->ackr.nAcks        = call->ackr_pend_cnt;
+-              if (do_ACK==RXRPC_ACK_REQUESTED)
++              if (do_ACK == RXRPC_ACK_REQUESTED)
+                       call->ackr.reason = do_ACK;
+               /* generate the ACK immediately if necessary */
+               if (special_ACK || force) {
+-                      err = __rxrpc_call_gen_normal_ACK(call,do_ACK==RXRPC_ACK_DELAY ? 0 : seq);
+-                      if (err<0) {
++                      err = __rxrpc_call_gen_normal_ACK(
++                              call, do_ACK == RXRPC_ACK_DELAY ? 0 : seq);
++                      if (err < 0) {
+                               ret = err;
+                               goto out;
+                       }
+               }
+       }
+-      if (call->ackr.reason==RXRPC_ACK_REQUESTED)
++      if (call->ackr.reason == RXRPC_ACK_REQUESTED)
+               call->ackr_dfr_seq = seq;
+-      /* start the ACK timer if not running if there are any pending deferred ACKs */
+-      if (call->ackr_pend_cnt>0 &&
+-          call->ackr.reason!=RXRPC_ACK_REQUESTED &&
++      /* start the ACK timer if not running if there are any pending deferred
++       * ACKs */
++      if (call->ackr_pend_cnt > 0 &&
++          call->ackr.reason != RXRPC_ACK_REQUESTED &&
+           !timer_pending(&call->ackr_dfr_timo)
+           ) {
+               unsigned long timo;
+               timo = rxrpc_call_dfr_ack_timeout + jiffies;
+-              _debug("START ACKR TIMER for cj=%lu",timo-call->cjif);
++              _debug("START ACKR TIMER for cj=%lu", timo-call->cjif);
+               spin_lock(&call->lock);
+-              mod_timer(&call->ackr_dfr_timo,timo);
++              mod_timer(&call->ackr_dfr_timo, timo);
+               spin_unlock(&call->lock);
+       }
+-      else if ((call->ackr_pend_cnt==0 || call->ackr.reason==RXRPC_ACK_REQUESTED) &&
++      else if ((call->ackr_pend_cnt == 0 ||
++                call->ackr.reason == RXRPC_ACK_REQUESTED) &&
+                timer_pending(&call->ackr_dfr_timo)
+                ) {
+               /* stop timer if no pending ACKs */
+@@ -689,21 +718,25 @@
+       if (special_ACK) {
+               struct rxrpc_ackpacket ack;
+               struct iovec diov[2];
+-              u8 acks[1] = { RXRPC_ACK_TYPE_ACK };
++              uint8_t acks[1] = { RXRPC_ACK_TYPE_ACK };
+               /* fill out the appropriate form */
+-              ack.bufferSpace         = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
+-              ack.maxSkew             = htons(min(call->ackr_high_seq - seq,65535U));
+-              ack.firstPacket         = htonl(call->ackr_win_bot);
+-              ack.previousPacket      = call->ackr_prev_seq;
+-              ack.serial              = hdr->serial;
+-              ack.reason              = special_ACK;
+-              ack.nAcks               = 0;
+-              //ack.nAcks = special_ACK==RXRPC_ACK_OUT_OF_SEQUENCE ? 0 : hdr->seq ? 1 : 0;
+-
+-              _proto("Rx Sending s-ACK { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
+-                     ntohs(ack.maxSkew),ntohl(ack.firstPacket),ntohl(ack.previousPacket),
+-                     ntohl(ack.serial),rxrpc_acks[ack.reason],ack.nAcks);
++              ack.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
++              ack.maxSkew     = htons(min(call->ackr_high_seq - seq,65535U));
++              ack.firstPacket = htonl(call->ackr_win_bot);
++              ack.previousPacket = call->ackr_prev_seq;
++              ack.serial      = hdr->serial;
++              ack.reason      = special_ACK;
++              ack.nAcks       = 0;
++
++              _proto("Rx Sending s-ACK"
++                     " { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
++                     ntohs(ack.maxSkew),
++                     ntohl(ack.firstPacket),
++                     ntohl(ack.previousPacket),
++                     ntohl(ack.serial),
++                     rxrpc_acks[ack.reason],
++                     ack.nAcks);
+               diov[0].iov_len  = sizeof(struct rxrpc_ackpacket);
+               diov[0].iov_base = &ack;
+@@ -711,11 +744,11 @@
+               diov[1].iov_base = acks;
+               /* build and send the message */
+-              err = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_ACK,
+-                                      hdr->seq ? 2 : 1,diov,
++              err = rxrpc_conn_newmsg(call->conn,call, RXRPC_PACKET_TYPE_ACK,
++                                      hdr->seq ? 2 : 1, diov,
+                                       GFP_KERNEL,
+                                       &msg);
+-              if (err<0) {
++              if (err < 0) {
+                       ret = err;
+                       goto out;
+               }
+@@ -724,9 +757,9 @@
+               msg->hdr.seq = htonl(seq);
+               msg->hdr.flags |= RXRPC_SLOW_START_OK;
+-              err = rxrpc_conn_sendmsg(call->conn,msg);
++              err = rxrpc_conn_sendmsg(call->conn, msg);
+               rxrpc_put_message(msg);
+-              if (err<0) {
++              if (err < 0) {
+                       ret = err;
+                       goto out;
+               }
+@@ -737,7 +770,7 @@
+       if (hdr->seq)
+               call->ackr_prev_seq = hdr->seq;
+-      _leave(" = %d",ret);
++      _leave(" = %d", ret);
+       return ret;
+ } /* end rxrpc_call_generate_ACK() */
+@@ -748,7 +781,7 @@
+  */
+ void rxrpc_call_do_stuff(struct rxrpc_call *call)
+ {
+-      _enter("%p{flags=%lx}",call,call->flags);
++      _enter("%p{flags=%lx}", call, call->flags);
+       /* handle packet reception */
+       if (call->flags & RXRPC_CALL_RCV_PKT) {
+@@ -761,19 +794,19 @@
+       if (call->flags & RXRPC_CALL_ACKS_TIMO) {
+               _debug("- overdue ACK timeout");
+               call->flags &= ~RXRPC_CALL_ACKS_TIMO;
+-              rxrpc_call_resend(call,call->snd_seq_count);
++              rxrpc_call_resend(call, call->snd_seq_count);
+       }
+       /* handle lack of reception */
+       if (call->flags & RXRPC_CALL_RCV_TIMO) {
+               _debug("- reception timeout");
+               call->flags &= ~RXRPC_CALL_RCV_TIMO;
+-              rxrpc_call_abort(call,-EIO);
++              rxrpc_call_abort(call, -EIO);
+       }
+       /* handle deferred ACKs */
+       if (call->flags & RXRPC_CALL_ACKR_TIMO ||
+-          (call->ackr.nAcks>0 && call->ackr.reason==RXRPC_ACK_REQUESTED)
++          (call->ackr.nAcks > 0 && call->ackr.reason == RXRPC_ACK_REQUESTED)
+           ) {
+               _debug("- deferred ACK timeout: cj=%05lu r=%s n=%u",
+                      jiffies - call->cjif,
+@@ -782,9 +815,10 @@
+               call->flags &= ~RXRPC_CALL_ACKR_TIMO;
+-              if (call->ackr.nAcks>0 && call->app_call_state!=RXRPC_CSTATE_ERROR) {
++              if (call->ackr.nAcks > 0 &&
++                  call->app_call_state != RXRPC_CSTATE_ERROR) {
+                       /* generate ACK */
+-                      __rxrpc_call_gen_normal_ACK(call,call->ackr_dfr_seq);
++                      __rxrpc_call_gen_normal_ACK(call, call->ackr_dfr_seq);
+                       call->ackr_dfr_seq = 0;
+               }
+       }
+@@ -807,10 +841,11 @@
+       int ret;
+       u32 _error;
+-      _enter("%p{%08x},%p{%d},%d",conn,ntohl(conn->conn_id),call,ntohl(call->call_id),errno);
++      _enter("%p{%08x},%p{%d},%d",
++             conn, ntohl(conn->conn_id), call, ntohl(call->call_id), errno);
+       /* if this call is already aborted, then just wake up any waiters */
+-      if (call->app_call_state==RXRPC_CSTATE_ERROR) {
++      if (call->app_call_state == RXRPC_CSTATE_ERROR) {
+               spin_unlock(&call->lock);
+               call->app_error_func(call);
+               _leave(" = 0");
+@@ -820,12 +855,12 @@
+       rxrpc_get_call(call);
+       /* change the state _with_ the lock still held */
+-      call->app_call_state = RXRPC_CSTATE_ERROR;
+-      call->app_err_state = RXRPC_ESTATE_LOCAL_ABORT;
+-      call->app_errno = errno;
+-      call->app_mark = RXRPC_APP_MARK_EOF;
+-      call->app_read_buf = NULL;
+-      call->app_async_read = 0;
++      call->app_call_state    = RXRPC_CSTATE_ERROR;
++      call->app_err_state     = RXRPC_ESTATE_LOCAL_ABORT;
++      call->app_errno         = errno;
++      call->app_mark          = RXRPC_APP_MARK_EOF;
++      call->app_read_buf      = NULL;
++      call->app_async_read    = 0;
+       _state(call);
+@@ -840,22 +875,25 @@
+       del_timer_sync(&call->ackr_dfr_timo);
+       if (rxrpc_call_is_ack_pending(call))
+-              __rxrpc_call_gen_normal_ACK(call,0);
++              __rxrpc_call_gen_normal_ACK(call, 0);
+-      /* send the abort packet only if we actually traded some other packets */
++      /* send the abort packet only if we actually traded some other
++       * packets */
+       ret = 0;
+       if (call->pkt_snd_count || call->pkt_rcv_count) {
+               /* actually send the abort */
+-              _proto("Rx Sending Call ABORT { data=%d }",call->app_abort_code);
++              _proto("Rx Sending Call ABORT { data=%d }",
++                     call->app_abort_code);
+               _error = htonl(call->app_abort_code);
+               diov[0].iov_len  = sizeof(_error);
+               diov[0].iov_base = &_error;
+-              ret = rxrpc_conn_newmsg(conn,call,RXRPC_PACKET_TYPE_ABORT,1,diov,GFP_KERNEL,&msg);
+-              if (ret==0) {
+-                      ret = rxrpc_conn_sendmsg(conn,msg);
++              ret = rxrpc_conn_newmsg(conn, call, RXRPC_PACKET_TYPE_ABORT,
++                                      1, diov, GFP_KERNEL, &msg);
++              if (ret == 0) {
++                      ret = rxrpc_conn_sendmsg(conn, msg);
+                       rxrpc_put_message(msg);
+               }
+       }
+@@ -865,8 +903,7 @@
+       rxrpc_put_call(call);
+-      _leave(" = %d",ret);
+-
++      _leave(" = %d", ret);
+       return ret;
+ } /* end __rxrpc_call_abort() */
+@@ -879,7 +916,7 @@
+ {
+       spin_lock(&call->lock);
+-      return __rxrpc_call_abort(call,error);
++      return __rxrpc_call_abort(call, error);
+ } /* end rxrpc_call_abort() */
+@@ -891,11 +928,12 @@
+ {
+       struct rxrpc_message *msg;
+       struct list_head *_p;
+-      u32 data32;
++      uint32_t data32;
+-      _enter("%p",call);
++      _enter("%p", call);
+-      rxrpc_get_call(call); /* must not go away too soon if aborted by app-layer */
++      rxrpc_get_call(call); /* must not go away too soon if aborted by
++                             * app-layer */
+       while (!list_empty(&call->rcv_receiveq)) {
+               /* try to get next packet */
+@@ -907,9 +945,10 @@
+               }
+               spin_unlock(&call->lock);
+-              if (!_p) break;
++              if (!_p)
++                      break;
+-              msg = list_entry(_p,struct rxrpc_message,link);
++              msg = list_entry(_p, struct rxrpc_message, link);
+               _proto("Rx %05lu Received %s packet (%%%u,#%u,%c%c%c%c%c)",
+                      jiffies - call->cjif,
+@@ -927,9 +966,10 @@
+                       /* deal with data packets */
+               case RXRPC_PACKET_TYPE_DATA:
+                       /* ACK the packet if necessary */
+-                      switch (rxrpc_call_generate_ACK(call,&msg->hdr,NULL)) {
++                      switch (rxrpc_call_generate_ACK(call, &msg->hdr,
++                                                      NULL)) {
+                       case 0: /* useful packet */
+-                              rxrpc_call_receive_data_packet(call,msg);
++                              rxrpc_call_receive_data_packet(call, msg);
+                               break;
+                       case 1: /* duplicate or out-of-window packet */
+                               break;
+@@ -941,29 +981,30 @@
+                       /* deal with ACK packets */
+               case RXRPC_PACKET_TYPE_ACK:
+-                      rxrpc_call_receive_ack_packet(call,msg);
++                      rxrpc_call_receive_ack_packet(call, msg);
+                       break;
+                       /* deal with abort packets */
+               case RXRPC_PACKET_TYPE_ABORT:
+                       data32 = 0;
+-                      if (skb_copy_bits(msg->pkt,msg->offset,&data32,sizeof(data32))<0) {
++                      if (skb_copy_bits(msg->pkt, msg->offset,
++                                        &data32, sizeof(data32)) < 0) {
+                               printk("Rx Received short ABORT packet\n");
+                       }
+                       else {
+                               data32 = ntohl(data32);
+                       }
+-                      _proto("Rx Received Call ABORT { data=%d }",data32);
++                      _proto("Rx Received Call ABORT { data=%d }", data32);
+                       spin_lock(&call->lock);
+-                      call->app_call_state = RXRPC_CSTATE_ERROR;
+-                      call->app_err_state = RXRPC_ESTATE_PEER_ABORT;
+-                      call->app_abort_code = data32;
+-                      call->app_errno = -ECONNABORTED;
+-                      call->app_mark = RXRPC_APP_MARK_EOF;
+-                      call->app_read_buf = NULL;
+-                      call->app_async_read = 0;
++                      call->app_call_state    = RXRPC_CSTATE_ERROR;
++                      call->app_err_state     = RXRPC_ESTATE_PEER_ABORT;
++                      call->app_abort_code    = data32;
++                      call->app_errno         = -ECONNABORTED;
++                      call->app_mark          = RXRPC_APP_MARK_EOF;
++                      call->app_read_buf      = NULL;
++                      call->app_async_read    = 0;
+                       /* ask the app to translate the error code */
+                       call->app_aemap_func(call);
+@@ -974,7 +1015,8 @@
+               default:
+                       /* deal with other packet types */
+-                      _proto("Rx Unsupported packet type %u (#%u)",msg->hdr.type,msg->seq);
++                      _proto("Rx Unsupported packet type %u (#%u)",
++                             msg->hdr.type, msg->seq);
+                       break;
+               }
+@@ -990,14 +1032,18 @@
+ /*
+  * process next data packet
+  * - as the next data packet arrives:
+- *   - it is queued on app_readyq _if_ it is the next one expected (app_ready_seq+1)
++ *   - it is queued on app_readyq _if_ it is the next one expected
++ *     (app_ready_seq+1)
+  *   - it is queued on app_unreadyq _if_ it is not the next one expected
+- *   - if a packet placed on app_readyq completely fills a hole leading up to the first packet
+- *     on app_unreadyq, then packets now in sequence are tranferred to app_readyq
+- * - the application layer can only see packets on app_readyq (app_ready_qty bytes)
++ *   - if a packet placed on app_readyq completely fills a hole leading up to
++ *     the first packet on app_unreadyq, then packets now in sequence are
++ *     tranferred to app_readyq
++ * - the application layer can only see packets on app_readyq
++ *   (app_ready_qty bytes)
+  * - the application layer is prodded every time a new packet arrives
+  */
+-static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc_message *msg)
++static void rxrpc_call_receive_data_packet(struct rxrpc_call *call,
++                                         struct rxrpc_message *msg)
+ {
+       const struct rxrpc_operation *optbl, *op;
+       struct rxrpc_message *pmsg;
+@@ -1005,22 +1051,23 @@
+       int ret, lo, hi, rmtimo;
+       u32 opid;
+-      _enter("%p{%u},%p{%u}",call,ntohl(call->call_id),msg,msg->seq);
++      _enter("%p{%u},%p{%u}", call, ntohl(call->call_id), msg, msg->seq);
+       rxrpc_get_message(msg);
+-      /* add to the unready queue if we'd have to create a hole in the ready queue otherwise */
+-      if (msg->seq != call->app_ready_seq+1) {
+-              _debug("Call add packet %d to unreadyq",msg->seq);
++      /* add to the unready queue if we'd have to create a hole in the ready
++       * queue otherwise */
++      if (msg->seq != call->app_ready_seq + 1) {
++              _debug("Call add packet %d to unreadyq", msg->seq);
+               /* insert in seq order */
+               list_for_each(_p,&call->app_unreadyq) {
+-                      pmsg = list_entry(_p,struct rxrpc_message,link);
+-                      if (pmsg->seq>msg->seq)
++                      pmsg = list_entry(_p, struct rxrpc_message, link);
++                      if (pmsg->seq > msg->seq)
+                               break;
+               }
+-              list_add_tail(&msg->link,_p);
++              list_add_tail(&msg->link, _p);
+               _leave(" [unreadyq]");
+               return;
+@@ -1028,33 +1075,35 @@
+       /* next in sequence - simply append into the call's ready queue */
+       _debug("Call add packet %d to readyq (+%Zd => %Zd bytes)",
+-             msg->seq,msg->dsize,call->app_ready_qty);
++             msg->seq, msg->dsize, call->app_ready_qty);
+       spin_lock(&call->lock);
+       call->app_ready_seq = msg->seq;
+       call->app_ready_qty += msg->dsize;
+-      list_add_tail(&msg->link,&call->app_readyq);
++      list_add_tail(&msg->link, &call->app_readyq);
+       /* move unready packets to the readyq if we got rid of a hole */
+       while (!list_empty(&call->app_unreadyq)) {
+-              pmsg = list_entry(call->app_unreadyq.next,struct rxrpc_message,link);
++              pmsg = list_entry(call->app_unreadyq.next,
++                                struct rxrpc_message, link);
+-              if (pmsg->seq != call->app_ready_seq+1)
++              if (pmsg->seq != call->app_ready_seq + 1)
+                       break;
+               /* next in sequence - just move list-to-list */
+               _debug("Call transfer packet %d to readyq (+%Zd => %Zd bytes)",
+-                     pmsg->seq,pmsg->dsize,call->app_ready_qty);
++                     pmsg->seq, pmsg->dsize, call->app_ready_qty);
+               call->app_ready_seq = pmsg->seq;
+               call->app_ready_qty += pmsg->dsize;
+               list_del_init(&pmsg->link);
+-              list_add_tail(&pmsg->link,&call->app_readyq);
++              list_add_tail(&pmsg->link, &call->app_readyq);
+       }
+       /* see if we've got the last packet yet */
+       if (!list_empty(&call->app_readyq)) {
+-              pmsg = list_entry(call->app_readyq.prev,struct rxrpc_message,link);
++              pmsg = list_entry(call->app_readyq.prev,
++                                struct rxrpc_message, link);
+               if (pmsg->hdr.flags & RXRPC_LAST_PACKET) {
+                       call->app_last_rcv = 1;
+                       _debug("Last packet on readyq");
+@@ -1068,25 +1117,27 @@
+               _leave(" [error]");
+               return;
+-              /* extract the operation ID from an incoming call if that's not yet been done */
++              /* extract the operation ID from an incoming call if that's not
++               * yet been done */
+       case RXRPC_CSTATE_SRVR_RCV_OPID:
+               spin_unlock(&call->lock);
+               /* handle as yet insufficient data for the operation ID */
+-              if (call->app_ready_qty<4) {
++              if (call->app_ready_qty < 4) {
+                       if (call->app_last_rcv)
+-                              rxrpc_call_abort(call,-EINVAL); /* trouble - last packet seen */
++                              /* trouble - last packet seen */
++                              rxrpc_call_abort(call, -EINVAL);
+                       _leave("");
+                       return;
+               }
+               /* pull the operation ID out of the buffer */
+-              ret = rxrpc_call_read_data(call,&opid,sizeof(opid),0);
+-              if (ret<0) {
+-                      printk("Unexpected error from read-data: %d\n",ret);
+-                      if (call->app_call_state!=RXRPC_CSTATE_ERROR)
+-                              rxrpc_call_abort(call,ret);
++              ret = rxrpc_call_read_data(call, &opid, sizeof(opid), 0);
++              if (ret < 0) {
++                      printk("Unexpected error from read-data: %d\n", ret);
++                      if (call->app_call_state != RXRPC_CSTATE_ERROR)
++                              rxrpc_call_abort(call, ret);
+                       _leave("");
+                       return;
+               }
+@@ -1097,38 +1148,42 @@
+               lo = 0;
+               hi = call->conn->service->ops_end - optbl;
+-              while (lo<hi) {
+-                      int mid = (hi+lo) / 2;
++              while (lo < hi) {
++                      int mid = (hi + lo) / 2;
+                       op = &optbl[mid];
+-                      if (call->app_opcode==op->id)
++                      if (call->app_opcode == op->id)
+                               goto found_op;
+-                      if (call->app_opcode>op->id)
+-                              lo = mid+1;
++                      if (call->app_opcode > op->id)
++                              lo = mid + 1;
+                       else
+                               hi = mid;
+               }
+               /* search failed */
+               kproto("Rx Client requested operation %d from %s service",
+-                     call->app_opcode,call->conn->service->name);
+-              rxrpc_call_abort(call,-EINVAL);
++                     call->app_opcode, call->conn->service->name);
++              rxrpc_call_abort(call, -EINVAL);
+               _leave(" [inval]");
+               return;
+       found_op:
+               _proto("Rx Client requested operation %s from %s service",
+-                     op->name,call->conn->service->name);
++                     op->name, call->conn->service->name);
+-              /* we're now waiting for the argument block (unless the call was aborted) */
++              /* we're now waiting for the argument block (unless the call
++               * was aborted) */
+               spin_lock(&call->lock);
+-              if (call->app_call_state==RXRPC_CSTATE_SRVR_RCV_OPID ||
+-                  call->app_call_state==RXRPC_CSTATE_SRVR_SND_REPLY) {
++              if (call->app_call_state == RXRPC_CSTATE_SRVR_RCV_OPID ||
++                  call->app_call_state == RXRPC_CSTATE_SRVR_SND_REPLY) {
+                       if (!call->app_last_rcv)
+-                              call->app_call_state = RXRPC_CSTATE_SRVR_RCV_ARGS;
+-                      else if (call->app_ready_qty>0)
+-                              call->app_call_state = RXRPC_CSTATE_SRVR_GOT_ARGS;
++                              call->app_call_state =
++                                      RXRPC_CSTATE_SRVR_RCV_ARGS;
++                      else if (call->app_ready_qty > 0)
++                              call->app_call_state =
++                                      RXRPC_CSTATE_SRVR_GOT_ARGS;
+                       else
+-                              call->app_call_state = RXRPC_CSTATE_SRVR_SND_REPLY;
++                              call->app_call_state =
++                                      RXRPC_CSTATE_SRVR_SND_REPLY;
+                       call->app_mark = op->asize;
+                       call->app_user = op->user;
+               }
+@@ -1166,20 +1221,21 @@
+       default:
+               /* deal with data reception in an unexpected state */
+-              printk("Unexpected state [[[ %u ]]]\n",call->app_call_state);
+-              __rxrpc_call_abort(call,-EBADMSG);
++              printk("Unexpected state [[[ %u ]]]\n", call->app_call_state);
++              __rxrpc_call_abort(call, -EBADMSG);
+               _leave("");
+               return;
+       }
+-      if (call->app_call_state==RXRPC_CSTATE_CLNT_RCV_REPLY && call->app_last_rcv)
++      if (call->app_call_state == RXRPC_CSTATE_CLNT_RCV_REPLY &&
++          call->app_last_rcv)
+               BUG();
+       /* otherwise just invoke the data function whenever we can satisfy its desire for more
+        * data
+        */
+       _proto("Rx Received Op Data: st=%u qty=%Zu mk=%Zu%s",
+-             call->app_call_state,call->app_ready_qty,call->app_mark,
++             call->app_call_state, call->app_ready_qty, call->app_mark,
+              call->app_last_rcv ? " last-rcvd" : "");
+       spin_lock(&call->lock);
+@@ -1196,8 +1252,8 @@
+       case -ECONNABORTED:
+               spin_unlock(&call->lock);
+               break;
+-      default:                        
+-              __rxrpc_call_abort(call,ret);
++      default:
++              __rxrpc_call_abort(call, ret);
+               break;
+       }
+@@ -1211,17 +1267,18 @@
+ /*
+  * received an ACK packet
+  */
+-static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_message *msg)
++static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call,
++                                        struct rxrpc_message *msg)
+ {
+       struct rxrpc_ackpacket ack;
+       rxrpc_serial_t serial;
+       rxrpc_seq_t seq;
+       int ret;
+-      _enter("%p{%u},%p{%u}",call,ntohl(call->call_id),msg,msg->seq);
++      _enter("%p{%u},%p{%u}", call, ntohl(call->call_id), msg, msg->seq);
+       /* extract the basic ACK record */
+-      if (skb_copy_bits(msg->pkt,msg->offset,&ack,sizeof(ack))<0) {
++      if (skb_copy_bits(msg->pkt, msg->offset, &ack, sizeof(ack)) < 0) {
+               printk("Rx Received short ACK packet\n");
+               return;
+       }
+@@ -1241,10 +1298,14 @@
+              call->ackr.nAcks
+              );
+-      /* check the other side isn't ACK'ing a sequence number I haven't sent yet */
+-      if (ack.nAcks>0 && (seq > call->snd_seq_count || seq+ack.nAcks-1 > call->snd_seq_count)) {
+-              printk("Received ACK (#%u-#%u) for unsent packet\n",seq,seq+ack.nAcks-1);
+-              rxrpc_call_abort(call,-EINVAL);
++      /* check the other side isn't ACK'ing a sequence number I haven't sent
++       * yet */
++      if (ack.nAcks > 0 &&
++          (seq > call->snd_seq_count ||
++           seq + ack.nAcks - 1 > call->snd_seq_count)) {
++              printk("Received ACK (#%u-#%u) for unsent packet\n",
++                     seq, seq + ack.nAcks - 1);
++              rxrpc_call_abort(call, -EINVAL);
+               _leave("");
+               return;
+       }
+@@ -1255,7 +1316,7 @@
+               /* find the prompting packet */
+               spin_lock(&call->lock);
+-              if (call->snd_ping && call->snd_ping->hdr.serial==serial) {
++              if (call->snd_ping && call->snd_ping->hdr.serial == serial) {
+                       /* it was a ping packet */
+                       rttmsg = call->snd_ping;
+                       call->snd_ping = NULL;
+@@ -1263,22 +1324,28 @@
+                       if (rttmsg) {
+                               rttmsg->rttdone = 1;
+-                              rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
++                              rxrpc_peer_calculate_rtt(call->conn->peer,
++                                                       rttmsg, msg);
+                               rxrpc_put_message(rttmsg);
+                       }
+               }
+               else {
+                       struct list_head *_p;
+-                      /* it ought to be a data packet - look in the pending ACK list */
+-                      list_for_each(_p,&call->acks_pendq) {
+-                              rttmsg = list_entry(_p,struct rxrpc_message,link);
+-                              if (rttmsg->hdr.serial==serial) {
++                      /* it ought to be a data packet - look in the pending
++                       * ACK list */
++                      list_for_each(_p, &call->acks_pendq) {
++                              rttmsg = list_entry(_p, struct rxrpc_message,
++                                                  link);
++                              if (rttmsg->hdr.serial == serial) {
+                                       if (rttmsg->rttdone)
+-                                              break; /* never do RTT twice without resending */
++                                              /* never do RTT twice without
++                                               * resending */
++                                              break;
+                                       rttmsg->rttdone = 1;
+-                                      rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
++                                      rxrpc_peer_calculate_rtt(
++                                              call->conn->peer, rttmsg, msg);
+                                       break;
+                               }
+                       }
+@@ -1287,24 +1354,25 @@
+       }
+       switch (ack.reason) {
+-              /* deal with negative/positive acknowledgement of data packets */
++              /* deal with negative/positive acknowledgement of data
++               * packets */
+       case RXRPC_ACK_REQUESTED:
+       case RXRPC_ACK_DELAY:
+       case RXRPC_ACK_IDLE:
+-              rxrpc_call_definitively_ACK(call,seq-1);
++              rxrpc_call_definitively_ACK(call, seq - 1);
+       case RXRPC_ACK_DUPLICATE:
+       case RXRPC_ACK_OUT_OF_SEQUENCE:
+       case RXRPC_ACK_EXCEEDS_WINDOW:
+               call->snd_resend_cnt = 0;
+-              ret = rxrpc_call_record_ACK(call,msg,seq,ack.nAcks);
+-              if (ret<0)
+-                      rxrpc_call_abort(call,ret);
++              ret = rxrpc_call_record_ACK(call, msg, seq, ack.nAcks);
++              if (ret < 0)
++                      rxrpc_call_abort(call, ret);
+               break;
+               /* respond to ping packets immediately */
+       case RXRPC_ACK_PING:
+-              rxrpc_call_generate_ACK(call,&msg->hdr,&ack);
++              rxrpc_call_generate_ACK(call, &msg->hdr, &ack);
+               break;
+               /* only record RTT on ping response packets */
+@@ -1312,10 +1380,12 @@
+               if (call->snd_ping) {
+                       struct rxrpc_message *rttmsg;
+-                      /* only do RTT stuff if the response matches the retained ping */
++                      /* only do RTT stuff if the response matches the
++                       * retained ping */
+                       rttmsg = NULL;
+                       spin_lock(&call->lock);
+-                      if (call->snd_ping && call->snd_ping->hdr.serial==ack.serial) {
++                      if (call->snd_ping &&
++                          call->snd_ping->hdr.serial == ack.serial) {
+                               rttmsg = call->snd_ping;
+                               call->snd_ping = NULL;
+                       }
+@@ -1323,14 +1393,15 @@
+                       if (rttmsg) {
+                               rttmsg->rttdone = 1;
+-                              rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
++                              rxrpc_peer_calculate_rtt(call->conn->peer,
++                                                       rttmsg, msg);
+                               rxrpc_put_message(rttmsg);
+                       }
+               }
+               break;
+       default:
+-              printk("Unsupported ACK reason %u\n",ack.reason);
++              printk("Unsupported ACK reason %u\n", ack.reason);
+               break;
+       }
+@@ -1339,38 +1410,44 @@
+ /*****************************************************************************/
+ /*
+- * record definitive ACKs for all messages up to and including the one with the 'highest' seq
++ * record definitive ACKs for all messages up to and including the one with the
++ * 'highest' seq
+  */
+-static void rxrpc_call_definitively_ACK(struct rxrpc_call *call, rxrpc_seq_t highest)
++static void rxrpc_call_definitively_ACK(struct rxrpc_call *call,
++                                      rxrpc_seq_t highest)
+ {
+       struct rxrpc_message *msg;
+       int now_complete;
+-      _enter("%p{ads=%u},%u",call,call->acks_dftv_seq,highest);
++      _enter("%p{ads=%u},%u", call, call->acks_dftv_seq, highest);
+-      while (call->acks_dftv_seq<highest) {
++      while (call->acks_dftv_seq < highest) {
+               call->acks_dftv_seq++;
+-              _proto("Definitive ACK on packet #%u",call->acks_dftv_seq);
++              _proto("Definitive ACK on packet #%u", call->acks_dftv_seq);
+-              /* discard those at front of queue until message with highest ACK is found */
++              /* discard those at front of queue until message with highest
++               * ACK is found */
+               spin_lock(&call->lock);
+               msg = NULL;
+               if (!list_empty(&call->acks_pendq)) {
+-                      msg = list_entry(call->acks_pendq.next,struct rxrpc_message,link);
++                      msg = list_entry(call->acks_pendq.next,
++                                       struct rxrpc_message, link);
+                       list_del_init(&msg->link); /* dequeue */
+-                      if (msg->state==RXRPC_MSG_SENT)
++                      if (msg->state == RXRPC_MSG_SENT)
+                               call->acks_pend_cnt--;
+               }
+               spin_unlock(&call->lock);
+               /* insanity check */
+               if (!msg)
+-                      panic("%s(): acks_pendq unexpectedly empty\n",__FUNCTION__);
++                      panic("%s(): acks_pendq unexpectedly empty\n",
++                            __FUNCTION__);
+-              if (msg->seq!=call->acks_dftv_seq)
+-                      panic("%s(): Packet #%u expected at front of acks_pendq (#%u found)\n",
+-                            __FUNCTION__,call->acks_dftv_seq,msg->seq);
++              if (msg->seq != call->acks_dftv_seq)
++                      panic("%s(): Packet #%u expected at front of acks_pendq"
++                            " (#%u found)\n",
++                            __FUNCTION__, call->acks_dftv_seq, msg->seq);
+               /* discard the message */
+               msg->state = RXRPC_MSG_DONE;
+@@ -1380,8 +1457,8 @@
+       /* if all sent packets are definitively ACK'd then prod any sleepers just in case */
+       now_complete = 0;
+       spin_lock(&call->lock);
+-      if (call->acks_dftv_seq==call->snd_seq_count) {
+-              if (call->app_call_state!=RXRPC_CSTATE_COMPLETE) {
++      if (call->acks_dftv_seq == call->snd_seq_count) {
++              if (call->app_call_state != RXRPC_CSTATE_COMPLETE) {
+                       call->app_call_state = RXRPC_CSTATE_COMPLETE;
+                       _state(call);
+                       now_complete = 1;
+@@ -1417,13 +1494,15 @@
+       u8 acks[16];
+       _enter("%p{apc=%u ads=%u},%p,%u,%Zu",
+-             call,call->acks_pend_cnt,call->acks_dftv_seq,msg,seq,count);
++             call, call->acks_pend_cnt, call->acks_dftv_seq,
++             msg, seq, count);
+-      /* handle re-ACK'ing of definitively ACK'd packets (may be out-of-order ACKs) */
+-      if (seq<=call->acks_dftv_seq) {
++      /* handle re-ACK'ing of definitively ACK'd packets (may be out-of-order
++       * ACKs) */
++      if (seq <= call->acks_dftv_seq) {
+               unsigned delta = call->acks_dftv_seq - seq;
+-              if (count<=delta) {
++              if (count <= delta) {
+                       _leave(" = 0 [all definitively ACK'd]");
+                       return 0;
+               }
+@@ -1435,14 +1514,14 @@
+       highest = seq + count - 1;
+       resend = 0;
+-      while (count>0) {
++      while (count > 0) {
+               /* extract up to 16 ACK slots at a time */
+-              chunk = min(count,sizeof(acks));
++              chunk = min(count, sizeof(acks));
+               count -= chunk;
+-              memset(acks,2,sizeof(acks));
++              memset(acks, 2, sizeof(acks));
+-              if (skb_copy_bits(msg->pkt,msg->offset,&acks,chunk)<0) {
++              if (skb_copy_bits(msg->pkt, msg->offset, &acks, chunk) < 0) {
+                       printk("Rx Received short ACK packet\n");
+                       _leave(" = -EINVAL");
+                       return -EINVAL;
+@@ -1450,7 +1529,7 @@
+               msg->offset += chunk;
+               /* check that the ACK set is valid */
+-              for (ix=0; ix<chunk; ix++) {
++              for (ix = 0; ix < chunk; ix++) {
+                       switch (acks[ix]) {
+                       case RXRPC_ACK_TYPE_ACK:
+                               break;
+@@ -1458,14 +1537,16 @@
+                               resend = 1;
+                               break;
+                       default:
+-                              printk("Rx Received unsupported ACK state %u\n",acks[ix]);
++                              printk("Rx Received unsupported ACK state"
++                                     " %u\n", acks[ix]);
+                               _leave(" = -EINVAL");
+                               return -EINVAL;
+                       }
+               }
+-              _proto("Rx ACK of packets #%u-#%u [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c] (pend=%u)",
+-                     seq,(unsigned)(seq+chunk-1),
++              _proto("Rx ACK of packets #%u-#%u "
++                     "[%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c] (pend=%u)",
++                     seq, (unsigned) (seq + chunk - 1),
+                      _acktype[acks[0x0]],
+                      _acktype[acks[0x1]],
+                      _acktype[acks[0x2]],
+@@ -1485,53 +1566,60 @@
+                      call->acks_pend_cnt
+                      );
+-              /* mark the packets in the ACK queue as being provisionally ACK'd */
++              /* mark the packets in the ACK queue as being provisionally
++               * ACK'd */
+               ix = 0;
+               spin_lock(&call->lock);
+               /* find the first packet ACK'd/NAK'd here */
+-              list_for_each(_p,&call->acks_pendq) {
+-                      dmsg = list_entry(_p,struct rxrpc_message,link);
+-                      if (dmsg->seq==seq)
++              list_for_each(_p, &call->acks_pendq) {
++                      dmsg = list_entry(_p, struct rxrpc_message, link);
++                      if (dmsg->seq == seq)
+                               goto found_first;
+-                      _debug("- %u: skipping #%u",ix,dmsg->seq);
++                      _debug("- %u: skipping #%u", ix, dmsg->seq);
+               }
+               goto bad_queue;
+       found_first:
+               do {
+                       _debug("- %u: processing #%u (%c) apc=%u",
+-                             ix,dmsg->seq,_acktype[acks[ix]],call->acks_pend_cnt);
++                             ix, dmsg->seq, _acktype[acks[ix]],
++                             call->acks_pend_cnt);
+-                      if (acks[ix]==RXRPC_ACK_TYPE_ACK) {
+-                              if (dmsg->state==RXRPC_MSG_SENT) call->acks_pend_cnt--;
++                      if (acks[ix] == RXRPC_ACK_TYPE_ACK) {
++                              if (dmsg->state == RXRPC_MSG_SENT)
++                                      call->acks_pend_cnt--;
+                               dmsg->state = RXRPC_MSG_ACKED;
+                       }
+                       else {
+-                              if (dmsg->state==RXRPC_MSG_ACKED) call->acks_pend_cnt++;
++                              if (dmsg->state == RXRPC_MSG_ACKED)
++                                      call->acks_pend_cnt++;
+                               dmsg->state = RXRPC_MSG_SENT;
+                       }
+                       ix++;
+                       seq++;
+                       _p = dmsg->link.next;
+-                      dmsg = list_entry(_p,struct rxrpc_message,link);
+-              } while(ix<chunk && _p!=&call->acks_pendq && dmsg->seq==seq);
++                      dmsg = list_entry(_p, struct rxrpc_message, link);
++              } while(ix < chunk &&
++                      _p != &call->acks_pendq &&
++                      dmsg->seq == seq);
+-              if (ix<chunk)
++              if (ix < chunk)
+                       goto bad_queue;
+               spin_unlock(&call->lock);
+       }
+       if (resend)
+-              rxrpc_call_resend(call,highest);
++              rxrpc_call_resend(call, highest);
+-      /* if all packets are provisionally ACK'd, then wake up anyone who's waiting for that */
++      /* if all packets are provisionally ACK'd, then wake up anyone who's
++       * waiting for that */
+       now_complete = 0;
+       spin_lock(&call->lock);
+-      if (call->acks_pend_cnt==0) {
+-              if (call->app_call_state==RXRPC_CSTATE_SRVR_RCV_FINAL_ACK) {
++      if (call->acks_pend_cnt == 0) {
++              if (call->app_call_state == RXRPC_CSTATE_SRVR_RCV_FINAL_ACK) {
+                       call->app_call_state = RXRPC_CSTATE_COMPLETE;
+                       _state(call);
+               }
+@@ -1547,19 +1635,21 @@
+               call->app_attn_func(call);
+       }
+-      _leave(" = 0 (apc=%u)",call->acks_pend_cnt);
++      _leave(" = 0 (apc=%u)", call->acks_pend_cnt);
+       return 0;
+  bad_queue:
+-      panic("%s(): acks_pendq in bad state (packet #%u absent)\n",__FUNCTION__,seq);
++      panic("%s(): acks_pendq in bad state (packet #%u absent)\n",
++            __FUNCTION__, seq);
+ } /* end rxrpc_call_record_ACK() */
+ /*****************************************************************************/
+ /*
+  * transfer data from the ready packet queue to the asynchronous read buffer
+- * - since this func is the only one going to look at packets queued on app_readyq, we don't need
+- *   a lock to modify or access them, only to modify the queue pointers
++ * - since this func is the only one going to look at packets queued on
++ *   app_readyq, we don't need a lock to modify or access them, only to modify
++ *   the queue pointers
+  * - called with call->lock held
+  * - the buffer must be in kernel space
+  * - returns:
+@@ -1575,16 +1665,20 @@
+       int ret;
+       _enter("%p{as=%d buf=%p qty=%Zu/%Zu}",
+-             call,call->app_async_read,call->app_read_buf,call->app_ready_qty,call->app_mark);
++             call,
++             call->app_async_read, call->app_read_buf,
++             call->app_ready_qty, call->app_mark);
+       /* check the state */
+       switch (call->app_call_state) {
+       case RXRPC_CSTATE_SRVR_RCV_ARGS:
+       case RXRPC_CSTATE_CLNT_RCV_REPLY:
+               if (call->app_last_rcv) {
+-                      printk("%s(%p,%p,%Zd): Inconsistent call state (%s, last pkt)",
+-                            __FUNCTION__,call,call->app_read_buf,call->app_mark,
+-                            rxrpc_call_states[call->app_call_state]);
++                      printk("%s(%p,%p,%Zd):"
++                             " Inconsistent call state (%s, last pkt)",
++                             __FUNCTION__,
++                             call, call->app_read_buf, call->app_mark,
++                             rxrpc_call_states[call->app_call_state]);
+                       BUG();
+               }
+               break;
+@@ -1596,9 +1690,11 @@
+       case RXRPC_CSTATE_SRVR_SND_REPLY:
+               if (!call->app_last_rcv) {
+-                      printk("%s(%p,%p,%Zd): Inconsistent call state (%s, not last pkt)",
+-                            __FUNCTION__,call,call->app_read_buf,call->app_mark,
+-                            rxrpc_call_states[call->app_call_state]);
++                      printk("%s(%p,%p,%Zd):"
++                             " Inconsistent call state (%s, not last pkt)",
++                             __FUNCTION__,
++                             call, call->app_read_buf, call->app_mark,
++                             rxrpc_call_states[call->app_call_state]);
+                       BUG();
+               }
+               _debug("Trying to read data from call in SND_REPLY state");
+@@ -1609,13 +1705,14 @@
+               return -ECONNABORTED;
+       default:
+-              printk("reading in unexpected state [[[ %u ]]]\n",call->app_call_state);
++              printk("reading in unexpected state [[[ %u ]]]\n",
++                     call->app_call_state);
+               BUG();
+       }
+       /* handle the case of not having an async buffer */
+       if (!call->app_async_read) {
+-              if (call->app_mark==RXRPC_APP_MARK_EOF) {
++              if (call->app_mark == RXRPC_APP_MARK_EOF) {
+                       ret = call->app_last_rcv ? 0 : -EAGAIN;
+               }
+               else {
+@@ -1628,28 +1725,33 @@
+                       }
+               }
+-              _leave(" = %d [no buf]",ret);
++              _leave(" = %d [no buf]", ret);
+               return 0;
+       }
+-      while (!list_empty(&call->app_readyq) && call->app_mark>0) {
+-              msg = list_entry(call->app_readyq.next,struct rxrpc_message,link);
++      while (!list_empty(&call->app_readyq) && call->app_mark > 0) {
++              msg = list_entry(call->app_readyq.next,
++                               struct rxrpc_message, link);
+               /* drag as much data as we need out of this packet */
+-              qty = min(call->app_mark,msg->dsize);
++              qty = min(call->app_mark, msg->dsize);
+-              _debug("reading %Zu from skb=%p off=%lu",qty,msg->pkt,msg->offset);
++              _debug("reading %Zu from skb=%p off=%lu",
++                     qty, msg->pkt, msg->offset);
+               if (call->app_read_buf)
+-                      if (skb_copy_bits(msg->pkt,msg->offset,call->app_read_buf,qty)<0)
+-                              panic("%s: Failed to copy data from packet: (%p,%p,%Zd)",
+-                                    __FUNCTION__,call,call->app_read_buf,qty);
++                      if (skb_copy_bits(msg->pkt, msg->offset,
++                                        call->app_read_buf, qty) < 0)
++                              panic("%s: Failed to copy data from packet:"
++                                    " (%p,%p,%Zd)",
++                                    __FUNCTION__,
++                                    call, call->app_read_buf, qty);
+               /* if that packet is now empty, discard it */
+               call->app_ready_qty -= qty;
+               msg->dsize -= qty;
+-              if (msg->dsize==0) {
++              if (msg->dsize == 0) {
+                       list_del_init(&msg->link);
+                       rxrpc_put_message(msg);
+               }
+@@ -1658,10 +1760,11 @@
+               }
+               call->app_mark -= qty;
+-              if (call->app_read_buf) call->app_read_buf += qty;
++              if (call->app_read_buf)
++                      call->app_read_buf += qty;
+       }
+-      if (call->app_mark==0) {
++      if (call->app_mark == 0) {
+               call->app_async_read = 0;
+               call->app_mark = RXRPC_APP_MARK_EOF;
+               call->app_read_buf = NULL;
+@@ -1695,7 +1798,8 @@
+       }
+       if (call->app_last_rcv) {
+-              _debug("Insufficient data (%Zu/%Zu)",call->app_ready_qty,call->app_mark);
++              _debug("Insufficient data (%Zu/%Zu)",
++                     call->app_ready_qty, call->app_mark);
+               call->app_async_read = 0;
+               call->app_mark = RXRPC_APP_MARK_EOF;
+               call->app_read_buf = NULL;
+@@ -1710,22 +1814,26 @@
+ /*****************************************************************************/
+ /*
+- * attempt to read the specified amount of data from the call's ready queue into the buffer
+- * provided
+- * - since this func is the only one going to look at packets queued on app_readyq, we don't need
+- *   a lock to modify or access them, only to modify the queue pointers
++ * attempt to read the specified amount of data from the call's ready queue
++ * into the buffer provided
++ * - since this func is the only one going to look at packets queued on
++ *   app_readyq, we don't need a lock to modify or access them, only to modify
++ *   the queue pointers
+  * - if the buffer pointer is NULL, then data is merely drained, not copied
+- * - if flags&RXRPC_CALL_READ_BLOCK, then the function will wait until there is enough data or an
+- *   error will be generated
+- *   - note that the caller must have added the calling task to the call's wait queue beforehand
+- * - if flags&RXRPC_CALL_READ_ALL, then an error will be generated if this function doesn't read
+- *   all available data
++ * - if flags&RXRPC_CALL_READ_BLOCK, then the function will wait until there is
++ *   enough data or an error will be generated
++ *   - note that the caller must have added the calling task to the call's wait
++ *     queue beforehand
++ * - if flags&RXRPC_CALL_READ_ALL, then an error will be generated if this
++ *   function doesn't read all available data
+  */
+-int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int flags)
++int rxrpc_call_read_data(struct rxrpc_call *call,
++                       void *buffer, size_t size, int flags)
+ {
+       int ret;
+-      _enter("%p{arq=%Zu},%p,%Zd,%x",call,call->app_ready_qty,buffer,size,flags);
++      _enter("%p{arq=%Zu},%p,%Zd,%x",
++             call, call->app_ready_qty, buffer, size, flags);
+       spin_lock(&call->lock);
+@@ -1744,9 +1852,10 @@
+       ret = __rxrpc_call_read_data(call);
+       switch (ret) {
+       case 0:
+-              if (flags&RXRPC_CALL_READ_ALL && (!call->app_last_rcv || call->app_ready_qty>0)) {
++              if (flags & RXRPC_CALL_READ_ALL &&
++                  (!call->app_last_rcv || call->app_ready_qty > 0)) {
+                       _leave(" = -EBADMSG");
+-                      __rxrpc_call_abort(call,-EBADMSG);
++                      __rxrpc_call_abort(call, -EBADMSG);
+                       return -EBADMSG;
+               }
+@@ -1757,18 +1866,18 @@
+       case -ECONNABORTED:
+               spin_unlock(&call->lock);
+-              _leave(" = %d [aborted]",ret);
++              _leave(" = %d [aborted]", ret);
+               return ret;
+-      default:                        
+-              __rxrpc_call_abort(call,ret);
+-              _leave(" = %d",ret);
++      default:
++              __rxrpc_call_abort(call, ret);
++              _leave(" = %d", ret);
+               return ret;
+       case -EAGAIN:
+               spin_unlock(&call->lock);
+-              if (!(flags&RXRPC_CALL_READ_BLOCK)) {
++              if (!(flags & RXRPC_CALL_READ_BLOCK)) {
+                       _leave(" = -EAGAIN");
+                       return -EAGAIN;
+               }
+@@ -1789,7 +1898,7 @@
+                       return -EINTR;
+               }
+-              if (call->app_call_state==RXRPC_CSTATE_ERROR) {
++              if (call->app_call_state == RXRPC_CSTATE_ERROR) {
+                       _leave(" = -ECONNABORTED");
+                       return -ECONNABORTED;
+               }
+@@ -1804,8 +1913,8 @@
+ /*
+  * write data to a call
+  * - the data may not be sent immediately if it doesn't fill a buffer
+- * - if we can't queue all the data for buffering now, siov[] will have been adjusted to take
+- *   account of what has been sent
++ * - if we can't queue all the data for buffering now, siov[] will have been
++ *   adjusted to take account of what has been sent
+  */
+ int rxrpc_call_write_data(struct rxrpc_call *call,
+                         size_t sioc,
+@@ -1821,7 +1930,9 @@
+       char *buf;
+       int ret;
+-      _enter("%p,%Zu,%p,%02x,%x,%d,%p",call,sioc,siov,rxhdr_flags,alloc_flags,dup_data,size_sent);
++      _enter("%p,%Zu,%p,%02x,%x,%d,%p",
++             call, sioc, siov, rxhdr_flags, alloc_flags, dup_data,
++             size_sent);
+       *size_sent = 0;
+       size = 0;
+@@ -1840,8 +1951,9 @@
+       /* calculate how much data we've been given */
+       sptr = siov;
+-      for (; sioc>0; sptr++, sioc--) {
+-              if (!sptr->iov_len) continue;
++      for (; sioc > 0; sptr++, sioc--) {
++              if (!sptr->iov_len)
++                      continue;
+               if (!sptr->iov_base)
+                       goto out;
+@@ -1849,27 +1961,30 @@
+               size += sptr->iov_len;
+       }
+-      _debug("- size=%Zu mtu=%Zu",size,call->conn->mtu_size);
++      _debug("- size=%Zu mtu=%Zu", size, call->conn->mtu_size);
+       do {
+               /* make sure there's a message under construction */
+               if (!call->snd_nextmsg) {
+                       /* no - allocate a message with no data yet attached */
+-                      ret = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_DATA,
+-                                              0,NULL,alloc_flags,&call->snd_nextmsg);
+-                      if (ret<0)
++                      ret = rxrpc_conn_newmsg(call->conn, call,
++                                              RXRPC_PACKET_TYPE_DATA,
++                                              0, NULL, alloc_flags,
++                                              &call->snd_nextmsg);
++                      if (ret < 0)
+                               goto out;
+-                      _debug("- allocated new message [ds=%Zu]",call->snd_nextmsg->dsize);
++                      _debug("- allocated new message [ds=%Zu]",
++                             call->snd_nextmsg->dsize);
+               }
+               msg = call->snd_nextmsg;
+               msg->hdr.flags |= rxhdr_flags;
+               /* deal with zero-length terminal packet */
+-              if (size==0) {
++              if (size == 0) {
+                       if (rxhdr_flags & RXRPC_LAST_PACKET) {
+                               ret = rxrpc_call_flush(call);
+-                              if (ret<0)
++                              if (ret < 0)
+                                       goto out;
+                       }
+                       break;
+@@ -1877,24 +1992,27 @@
+               /* work out how much space current packet has available */
+               space = call->conn->mtu_size - msg->dsize;
+-              chunk = min(space,size);
++              chunk = min(space, size);
+-              _debug("- [before] space=%Zu chunk=%Zu",space,chunk);
++              _debug("- [before] space=%Zu chunk=%Zu", space, chunk);
+               while (!siov->iov_len)
+                       siov++;
+-              /* if we are going to have to duplicate the data then coalesce it too */
++              /* if we are going to have to duplicate the data then coalesce
++               * it too */
+               if (dup_data) {
+                       /* don't allocate more that 1 page at a time */
+-                      if (chunk>PAGE_SIZE)
++                      if (chunk > PAGE_SIZE)
+                               chunk = PAGE_SIZE;
+                       /* allocate a data buffer and attach to the message */
+-                      buf = kmalloc(chunk,alloc_flags);
++                      buf = kmalloc(chunk, alloc_flags);
+                       if (unlikely(!buf)) {
+-                              if (msg->dsize==sizeof(struct rxrpc_header)) {
+-                                      /* discard an empty msg and wind back the seq counter */
++                              if (msg->dsize ==
++                                  sizeof(struct rxrpc_header)) {
++                                      /* discard an empty msg and wind back
++                                       * the seq counter */
+                                       rxrpc_put_message(msg);
+                                       call->snd_nextmsg = NULL;
+                                       call->snd_seq_count--;
+@@ -1905,7 +2023,7 @@
+                       }
+                       tmp = msg->dcount++;
+-                      set_bit(tmp,&msg->dfree);
++                      set_bit(tmp, &msg->dfree);
+                       msg->data[tmp].iov_base = buf;
+                       msg->data[tmp].iov_len = chunk;
+                       msg->dsize += chunk;
+@@ -1913,9 +2031,9 @@
+                       size -= chunk;
+                       /* load the buffer with data */
+-                      while (chunk>0) {
+-                              tmp = min(chunk,siov->iov_len);
+-                              memcpy(buf,siov->iov_base,tmp);
++                      while (chunk > 0) {
++                              tmp = min(chunk, siov->iov_len);
++                              memcpy(buf, siov->iov_base, tmp);
+                               buf += tmp;
+                               siov->iov_base += tmp;
+                               siov->iov_len -= tmp;
+@@ -1926,7 +2044,8 @@
+               }
+               else {
+                       /* we want to attach the supplied buffers directly */
+-                      while (chunk>0 && msg->dcount<RXRPC_MSG_MAX_IOCS) {
++                      while (chunk > 0 &&
++                             msg->dcount < RXRPC_MSG_MAX_IOCS) {
+                               tmp = msg->dcount++;
+                               msg->data[tmp].iov_base = siov->iov_base;
+                               msg->data[tmp].iov_len = siov->iov_len;
+@@ -1938,20 +2057,20 @@
+                       }
+               }
+-              _debug("- [loaded] chunk=%Zu size=%Zu",chunk,size);
++              _debug("- [loaded] chunk=%Zu size=%Zu", chunk, size);
+               /* dispatch the message when full, final or requesting ACK */
+-              if (msg->dsize>=call->conn->mtu_size || rxhdr_flags) {
++              if (msg->dsize >= call->conn->mtu_size || rxhdr_flags) {
+                       ret = rxrpc_call_flush(call);
+-                      if (ret<0)
++                      if (ret < 0)
+                               goto out;
+               }
+-      } while(size>0);
++      } while(size > 0);
+       ret = 0;
+  out:
+-      _leave(" = %d (%Zd queued, %Zd rem)",ret,*size_sent,size);
++      _leave(" = %d (%Zd queued, %Zd rem)", ret, *size_sent, size);
+       return ret;
+ } /* end rxrpc_call_write_data() */
+@@ -1965,7 +2084,7 @@
+       struct rxrpc_message *msg;
+       int ret = 0;
+-      _enter("%p",call);
++      _enter("%p", call);
+       rxrpc_get_call(call);
+@@ -1983,25 +2102,28 @@
+               }
+               _proto("Sending DATA message { ds=%Zu dc=%u df=%02lu }",
+-                     msg->dsize,msg->dcount,msg->dfree);
++                     msg->dsize, msg->dcount, msg->dfree);
+               /* queue and adjust call state */
+               spin_lock(&call->lock);
+-              list_add_tail(&msg->link,&call->acks_pendq);
++              list_add_tail(&msg->link, &call->acks_pendq);
+-              /* decide what to do depending on current state and if this is the last packet */
++              /* decide what to do depending on current state and if this is
++               * the last packet */
+               ret = -EINVAL;
+               switch (call->app_call_state) {
+               case RXRPC_CSTATE_SRVR_SND_REPLY:
+                       if (msg->hdr.flags & RXRPC_LAST_PACKET) {
+-                              call->app_call_state = RXRPC_CSTATE_SRVR_RCV_FINAL_ACK;
++                              call->app_call_state =
++                                      RXRPC_CSTATE_SRVR_RCV_FINAL_ACK;
+                               _state(call);
+                       }
+                       break;
+               case RXRPC_CSTATE_CLNT_SND_ARGS:
+                       if (msg->hdr.flags & RXRPC_LAST_PACKET) {
+-                              call->app_call_state = RXRPC_CSTATE_CLNT_RCV_REPLY;
++                              call->app_call_state =
++                                      RXRPC_CSTATE_CLNT_RCV_REPLY;
+                               _state(call);
+                       }
+                       break;
+@@ -2016,19 +2138,20 @@
+               call->acks_pend_cnt++;
+               mod_timer(&call->acks_timeout,
+-                        __rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
++                        __rxrpc_rtt_based_timeout(call,
++                                                  rxrpc_call_acks_timeout));
+               spin_unlock(&call->lock);
+-              ret = rxrpc_conn_sendmsg(call->conn,msg);
+-              if (ret==0)
++              ret = rxrpc_conn_sendmsg(call->conn, msg);
++              if (ret == 0)
+                       call->pkt_snd_count++;
+       }
+  out:
+       rxrpc_put_call(call);
+-      _leave(" = %d",ret);
++      _leave(" = %d", ret);
+       return ret;
+ } /* end rxrpc_call_flush() */
+@@ -2043,14 +2166,16 @@
+       struct list_head *_p;
+       rxrpc_seq_t seq = 0;
+-      _enter("%p,%u",call,highest);
++      _enter("%p,%u", call, highest);
+       _proto("Rx Resend required");
+       /* handle too many resends */
+-      if (call->snd_resend_cnt>=rxrpc_call_max_resend) {
+-              _debug("Aborting due to too many resends (rcv=%d)",call->pkt_rcv_count);
+-              rxrpc_call_abort(call,call->pkt_rcv_count>0?-EIO:-ETIMEDOUT);
++      if (call->snd_resend_cnt >= rxrpc_call_max_resend) {
++              _debug("Aborting due to too many resends (rcv=%d)",
++                     call->pkt_rcv_count);
++              rxrpc_call_abort(call,
++                               call->pkt_rcv_count > 0 ? -EIO : -ETIMEDOUT);
+               _leave("");
+               return;
+       }
+@@ -2059,35 +2184,38 @@
+       call->snd_resend_cnt++;
+       for (;;) {
+               /* determine which the next packet we might need to ACK is */
+-              if (seq<=call->acks_dftv_seq)
++              if (seq <= call->acks_dftv_seq)
+                       seq = call->acks_dftv_seq;
+               seq++;
+-              if (seq>highest)
++              if (seq > highest)
+                       break;
+               /* look for the packet in the pending-ACK queue */
+-              list_for_each(_p,&call->acks_pendq) {
+-                      msg = list_entry(_p,struct rxrpc_message,link);
+-                      if (msg->seq==seq)
++              list_for_each(_p, &call->acks_pendq) {
++                      msg = list_entry(_p, struct rxrpc_message, link);
++                      if (msg->seq == seq)
+                               goto found_msg;
+               }
+-              panic("%s(%p,%d): Inconsistent pending-ACK queue (ds=%u sc=%u sq=%u)\n",
+-                    __FUNCTION__,call,highest,call->acks_dftv_seq,call->snd_seq_count,seq);
++              panic("%s(%p,%d):"
++                    " Inconsistent pending-ACK queue (ds=%u sc=%u sq=%u)\n",
++                    __FUNCTION__, call, highest,
++                    call->acks_dftv_seq, call->snd_seq_count, seq);
+       found_msg:
+-              if (msg->state!=RXRPC_MSG_SENT)
++              if (msg->state != RXRPC_MSG_SENT)
+                       continue; /* only un-ACK'd packets */
+               rxrpc_get_message(msg);
+               spin_unlock(&call->lock);
+-              /* send each message again (and ignore any errors we might incur) */
++              /* send each message again (and ignore any errors we might
++               * incur) */
+               _proto("Resending DATA message { ds=%Zu dc=%u df=%02lu }",
+-                     msg->dsize,msg->dcount,msg->dfree);
++                     msg->dsize, msg->dcount, msg->dfree);
+-              if (rxrpc_conn_sendmsg(call->conn,msg)==0)
++              if (rxrpc_conn_sendmsg(call->conn, msg) == 0)
+                       call->pkt_snd_count++;
+               rxrpc_put_message(msg);
+@@ -2096,7 +2224,8 @@
+       }
+       /* reset the timeout */
+-      mod_timer(&call->acks_timeout,__rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
++      mod_timer(&call->acks_timeout,
++                __rxrpc_rtt_based_timeout(call, rxrpc_call_acks_timeout));
+       spin_unlock(&call->lock);
+@@ -2109,10 +2238,10 @@
+  */
+ void rxrpc_call_handle_error(struct rxrpc_call *call, int local, int errno)
+ {
+-      _enter("%p{%u},%d",call,ntohl(call->call_id),errno);
++      _enter("%p{%u},%d", call, ntohl(call->call_id), errno);
+       /* if this call is already aborted, then just wake up any waiters */
+-      if (call->app_call_state==RXRPC_CSTATE_ERROR) {
++      if (call->app_call_state == RXRPC_CSTATE_ERROR) {
+               call->app_error_func(call);
+       }
+       else {
+@@ -2124,10 +2253,10 @@
+                       call->app_err_state = RXRPC_ESTATE_LOCAL_ERROR;
+               else
+                       call->app_err_state = RXRPC_ESTATE_REMOTE_ERROR;
+-              call->app_errno = errno;
+-              call->app_mark = RXRPC_APP_MARK_EOF;
+-              call->app_read_buf = NULL;
+-              call->app_async_read = 0;
++              call->app_errno         = errno;
++              call->app_mark          = RXRPC_APP_MARK_EOF;
++              call->app_read_buf      = NULL;
++              call->app_async_read    = 0;
+               /* map the error */
+               call->app_aemap_func(call);
+Index: linux-2.6.0-test5/net/rxrpc/connection.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/connection.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/connection.c   2003-09-27 11:38:42.218110256 +0800
+@@ -28,18 +28,20 @@
+ LIST_HEAD(rxrpc_conns);
+ DECLARE_RWSEM(rxrpc_conns_sem);
++unsigned long rxrpc_conn_timeout = 60 * 60;
+ static void __rxrpc_conn_timeout(rxrpc_timer_t *timer)
+ {
+-      struct rxrpc_connection *conn = list_entry(timer,struct rxrpc_connection,timeout);
++      struct rxrpc_connection *conn =
++              list_entry(timer, struct rxrpc_connection, timeout);
+-      _debug("Rx CONN TIMEOUT [%p{u=%d}]",conn,atomic_read(&conn->usage));
++      _debug("Rx CONN TIMEOUT [%p{u=%d}]", conn, atomic_read(&conn->usage));
+       rxrpc_conn_do_timeout(conn);
+ }
+ static const struct rxrpc_timer_ops rxrpc_conn_timer_ops = {
+-      .timed_out      = __rxrpc_conn_timeout,
++      timed_out:      __rxrpc_conn_timeout,
+ };
+ /*****************************************************************************/
+@@ -54,19 +56,20 @@
+       _enter("%p",peer);
+       /* allocate and initialise a connection record */
+-      conn = kmalloc(sizeof(struct rxrpc_connection),GFP_KERNEL);
++      conn = kmalloc(sizeof(struct rxrpc_connection), GFP_KERNEL);
+       if (!conn) {
+               _leave(" = -ENOMEM");
+               return -ENOMEM;
+       }
+-      memset(conn,0,sizeof(struct rxrpc_connection));
+-      atomic_set(&conn->usage,1);
++      memset(conn, 0, sizeof(struct rxrpc_connection));
++      atomic_set(&conn->usage, 1);
+       INIT_LIST_HEAD(&conn->link);
++      INIT_LIST_HEAD(&conn->id_link);
+       init_waitqueue_head(&conn->chanwait);
+       spin_lock_init(&conn->lock);
+-      rxrpc_timer_init(&conn->timeout,&rxrpc_conn_timer_ops);
++      rxrpc_timer_init(&conn->timeout, &rxrpc_conn_timer_ops);
+       do_gettimeofday(&conn->atime);
+       conn->mtu_size = 1024;
+@@ -75,7 +78,7 @@
+       __RXACCT(atomic_inc(&rxrpc_connection_count));
+       *_conn = conn;
+-      _leave(" = 0 (%p)",conn);
++      _leave(" = 0 (%p)", conn);
+       return 0;
+ } /* end __rxrpc_create_connection() */
+@@ -85,61 +88,123 @@
+  * create a new connection record for outgoing connections
+  */
+ int rxrpc_create_connection(struct rxrpc_transport *trans,
+-                          u16 port,
+-                          u32 addr,
+-                          unsigned short service_id,
++                          uint16_t port,
++                          uint32_t addr,
++                          uint16_t service_id,
+                           void *security,
+                           struct rxrpc_connection **_conn)
+ {
+-      struct rxrpc_connection *conn;
++      struct rxrpc_connection *candidate, *conn;
+       struct rxrpc_peer *peer;
++      struct list_head *_p;
++      uint32_t connid;
+       int ret;
+-      _enter("%p{%hu},%u,%hu",trans,trans->port,ntohs(port),service_id);
++      _enter("%p{%hu},%u,%hu", trans, trans->port, ntohs(port), service_id);
+       /* get a peer record */
+-      ret = rxrpc_peer_lookup(trans,addr,&peer);
+-      if (ret<0) {
+-              _leave(" = %d",ret);
++      ret = rxrpc_peer_lookup(trans, addr, &peer);
++      if (ret < 0) {
++              _leave(" = %d", ret);
+               return ret;
+       }
+       /* allocate and initialise a connection record */
+-      ret = __rxrpc_create_connection(peer,&conn);
+-      if (ret<0) {
++      ret = __rxrpc_create_connection(peer, &candidate);
++      if (ret < 0) {
+               rxrpc_put_peer(peer);
+-              _leave(" = %d",ret);
++              _leave(" = %d", ret);
+               return ret;
+       }
+       /* fill in the specific bits */
+-      conn->addr.sin_family   = AF_INET;
+-      conn->addr.sin_port     = port;
+-      conn->addr.sin_addr.s_addr = addr;
+-
+-      conn->in_epoch          = rxrpc_epoch;
+-      conn->out_epoch         = rxrpc_epoch;
+-      conn->in_clientflag     = 0;
+-      conn->out_clientflag    = RXRPC_CLIENT_INITIATED;
+-      conn->conn_id           = htonl((unsigned long) conn & RXRPC_CIDMASK);
+-      conn->service_id        = htons(service_id);
++      candidate->addr.sin_family      = AF_INET;
++      candidate->addr.sin_port        = port;
++      candidate->addr.sin_addr.s_addr = addr;
++
++      candidate->in_epoch             = rxrpc_epoch;
++      candidate->out_epoch            = rxrpc_epoch;
++      candidate->in_clientflag        = 0;
++      candidate->out_clientflag       = RXRPC_CLIENT_INITIATED;
++      candidate->service_id           = htons(service_id);
++
++      /* invent a unique connection ID */
++      write_lock(&peer->conn_idlock);
++
++ try_next_id:
++      connid = htonl(peer->conn_idcounter & RXRPC_CIDMASK);
++      peer->conn_idcounter += RXRPC_MAXCALLS;
++
++      list_for_each(_p, &peer->conn_idlist) {
++              conn = list_entry(_p, struct rxrpc_connection, id_link);
++              if (connid == conn->conn_id)
++                      goto try_next_id;
++              if (connid > conn->conn_id)
++                      break;
++      }
++
++      _debug("selected candidate conn ID %x.%u",
++             ntohl(peer->addr.s_addr), ntohl(connid));
++
++      candidate->conn_id = connid;
++      list_add_tail(&candidate->id_link, _p);
++
++      write_unlock(&peer->conn_idlock);
+       /* attach to peer */
+-      conn->peer = peer;
++      candidate->peer = peer;
+       write_lock(&peer->conn_lock);
+-      list_add_tail(&conn->link,&peer->conn_active);
++
++      /* search the peer's transport graveyard list */
++      spin_lock(&peer->conn_gylock);
++      list_for_each(_p, &peer->conn_graveyard) {
++              conn = list_entry(_p, struct rxrpc_connection, link);
++              if (conn->addr.sin_port == candidate->addr.sin_port     &&
++                  conn->security_ix   == candidate->security_ix       &&
++                  conn->service_id    == candidate->service_id        && 
++                  conn->in_clientflag == 0)
++                      goto found_in_graveyard;
++      }
++      spin_unlock(&peer->conn_gylock);
++
++      /* pick the new candidate */
++      _debug("created connection: {%08x} [out]", htonl(candidate->conn_id));
+       atomic_inc(&peer->conn_count);
++      conn = candidate;
++      candidate = NULL;
++
++ make_active:
++      list_add_tail(&conn->link, &peer->conn_active);
+       write_unlock(&peer->conn_lock);
+-      down_write(&rxrpc_conns_sem);
+-      list_add_tail(&conn->proc_link,&rxrpc_conns);
+-      up_write(&rxrpc_conns_sem);
++      if (candidate) {
++              write_lock(&peer->conn_idlock);
++              list_del(&candidate->id_link);
++              write_unlock(&peer->conn_idlock);
++
++              __RXACCT(atomic_dec(&rxrpc_connection_count));
++              kfree(candidate);
++      }
++      else {
++              down_write(&rxrpc_conns_sem);
++              list_add_tail(&conn->proc_link, &rxrpc_conns);
++              up_write(&rxrpc_conns_sem);
++      }
+       *_conn = conn;
+-      _leave(" = 0 (%p)",conn);
++      _leave(" = 0 (%p)", conn);
+       return 0;
++
++      /* handle resurrecting a connection from the graveyard */
++ found_in_graveyard:
++      _debug("resurrecting connection: {%08x} [out]", htonl(conn->conn_id));
++      rxrpc_get_connection(conn);
++      rxrpc_krxtimod_del_timer(&conn->timeout);
++      list_del_init(&conn->link);
++      spin_unlock(&peer->conn_gylock);
++      goto make_active;
+ } /* end rxrpc_create_connection() */
+ /*****************************************************************************/
+@@ -159,7 +224,10 @@
+       u8 x_clflag;
+       _enter("%p{{%hu}},%u,%hu",
+-             peer,peer->trans->port,ntohs(msg->pkt->h.uh->source),ntohs(msg->hdr.serviceId));
++             peer,
++             peer->trans->port,
++             ntohs(msg->pkt->h.uh->source),
++             ntohs(msg->hdr.serviceId));
+       x_port          = msg->pkt->h.uh->source;
+       x_epoch         = msg->hdr.epoch;
+@@ -170,8 +238,8 @@
+       /* [common case] search the transport's active list first */
+       read_lock(&peer->conn_lock);
+-      list_for_each(_p,&peer->conn_active) {
+-              conn = list_entry(_p,struct rxrpc_connection,link);
++      list_for_each(_p, &peer->conn_active) {
++              conn = list_entry(_p, struct rxrpc_connection, link);
+               if (conn->addr.sin_port         == x_port       &&
+                   conn->in_epoch              == x_epoch      &&
+                   conn->conn_id               == x_connid     &&
+@@ -187,9 +255,9 @@
+        * - only examine the graveyard for an outbound connection
+        */
+       if (x_clflag) {
+-              ret = __rxrpc_create_connection(peer,&candidate);
+-              if (ret<0) {
+-                      _leave(" = %d",ret);
++              ret = __rxrpc_create_connection(peer, &candidate);
++              if (ret < 0) {
++                      _leave(" = %d", ret);
+                       return ret;
+               }
+@@ -206,10 +274,11 @@
+               candidate->security_ix          = x_secix;
+       }
+-      /* search the active list again, just in case it appeared whilst we were busy */
++      /* search the active list again, just in case it appeared whilst we
++       * were busy */
+       write_lock(&peer->conn_lock);
+-      list_for_each(_p,&peer->conn_active) {
+-              conn = list_entry(_p,struct rxrpc_connection,link);
++      list_for_each(_p, &peer->conn_active) {
++              conn = list_entry(_p, struct rxrpc_connection, link);
+               if (conn->addr.sin_port         == x_port       &&
+                   conn->in_epoch              == x_epoch      &&
+                   conn->conn_id               == x_connid     &&
+@@ -221,8 +290,8 @@
+       /* search the transport's graveyard list */
+       spin_lock(&peer->conn_gylock);
+-      list_for_each(_p,&peer->conn_graveyard) {
+-              conn = list_entry(_p,struct rxrpc_connection,link);
++      list_for_each(_p, &peer->conn_graveyard) {
++              conn = list_entry(_p, struct rxrpc_connection, link);
+               if (conn->addr.sin_port         == x_port       &&
+                   conn->in_epoch              == x_epoch      &&
+                   conn->conn_id               == x_connid     &&
+@@ -241,6 +310,7 @@
+       }
+       /* we can now add the new candidate to the list */
++      _debug("created connection: {%08x} [in]", htonl(candidate->conn_id));
+       rxrpc_get_peer(peer);
+       conn = candidate;
+       candidate = NULL;
+@@ -248,25 +318,29 @@
+       fresh = 1;
+  make_active:
+-      list_add_tail(&conn->link,&peer->conn_active);
++      list_add_tail(&conn->link, &peer->conn_active);
+  success_uwfree:
+       write_unlock(&peer->conn_lock);
+       if (candidate) {
++              write_lock(&peer->conn_idlock);
++              list_del(&candidate->id_link);
++              write_unlock(&peer->conn_idlock);
++
+               __RXACCT(atomic_dec(&rxrpc_connection_count));
+               kfree(candidate);
+       }
+       if (fresh) {
+               down_write(&rxrpc_conns_sem);
+-              list_add_tail(&conn->proc_link,&rxrpc_conns);
++              list_add_tail(&conn->proc_link, &rxrpc_conns);
+               up_write(&rxrpc_conns_sem);
+       }
+  success:
+       *_conn = conn;
+-      _leave(" = 0 (%p)",conn);
++      _leave(" = 0 (%p)", conn);
+       return 0;
+       /* handle the connection being found in the active list straight off */
+@@ -277,6 +351,7 @@
+       /* handle resurrecting a connection from the graveyard */
+  found_in_graveyard:
++      _debug("resurrecting connection: {%08x} [in]", htonl(conn->conn_id));
+       rxrpc_get_peer(peer);
+       rxrpc_get_connection(conn);
+       rxrpc_krxtimod_del_timer(&conn->timeout);
+@@ -284,7 +359,8 @@
+       spin_unlock(&peer->conn_gylock);
+       goto make_active;
+-      /* handle finding the connection on the second time through the active list */
++      /* handle finding the connection on the second time through the active
++       * list */
+  found_active_second_chance:
+       rxrpc_get_connection(conn);
+       goto success_uwfree;
+@@ -294,19 +370,26 @@
+ /*****************************************************************************/
+ /*
+  * finish using a connection record
+- * - it will be transferred to the peer's connection graveyard when refcount reaches 0
++ * - it will be transferred to the peer's connection graveyard when refcount
++ *   reaches 0
+  */
+ void rxrpc_put_connection(struct rxrpc_connection *conn)
+ {
+-      struct rxrpc_peer *peer = conn->peer;
++      struct rxrpc_peer *peer;
++
++      if (!conn)
++              return;
++
++      _enter("%p{u=%d p=%hu}",
++             conn, atomic_read(&conn->usage), ntohs(conn->addr.sin_port));
+-      _enter("%p{u=%d p=%hu}",conn,atomic_read(&conn->usage),ntohs(conn->addr.sin_port));
++      peer = conn->peer;
++      spin_lock(&peer->conn_gylock);
+       /* sanity check */
+-      if (atomic_read(&conn->usage)<=0)
++      if (atomic_read(&conn->usage) <= 0)
+               BUG();
+-      spin_lock(&peer->conn_gylock);
+       if (likely(!atomic_dec_and_test(&conn->usage))) {
+               spin_unlock(&peer->conn_gylock);
+               _leave("");
+@@ -314,11 +397,11 @@
+       }
+       /* move to graveyard queue */
++      _debug("burying connection: {%08x}", htonl(conn->conn_id));
+       list_del(&conn->link);
+-      list_add_tail(&conn->link,&peer->conn_graveyard);
++      list_add_tail(&conn->link, &peer->conn_graveyard);
+-      /* discard in 100 secs */
+-      rxrpc_krxtimod_add_timer(&conn->timeout,20*HZ);
++      rxrpc_krxtimod_add_timer(&conn->timeout, rxrpc_conn_timeout * HZ);
+       spin_unlock(&peer->conn_gylock);
+@@ -335,16 +418,17 @@
+ {
+       struct rxrpc_peer *peer;
+-      _enter("%p{u=%d p=%hu}",conn,atomic_read(&conn->usage),ntohs(conn->addr.sin_port));
++      _enter("%p{u=%d p=%hu}",
++             conn, atomic_read(&conn->usage), ntohs(conn->addr.sin_port));
+       peer = conn->peer;
+-      if (atomic_read(&conn->usage)<0)
++      if (atomic_read(&conn->usage) < 0)
+               BUG();
+       /* remove from graveyard if still dead */
+       spin_lock(&peer->conn_gylock);
+-      if (atomic_read(&conn->usage)==0) {
++      if (atomic_read(&conn->usage) == 0) {
+               list_del_init(&conn->link);
+       }
+       else {
+@@ -357,12 +441,17 @@
+               return; /* resurrected */
+       }
+-      _debug("--- Destroying Connection %p ---",conn);
++      _debug("--- Destroying Connection %p{%08x} ---",
++             conn, htonl(conn->conn_id));
+       down_write(&rxrpc_conns_sem);
+       list_del(&conn->proc_link);
+       up_write(&rxrpc_conns_sem);
++      write_lock(&peer->conn_idlock);
++      list_del(&conn->id_link);
++      write_unlock(&peer->conn_idlock);
++
+       __RXACCT(atomic_dec(&rxrpc_connection_count));
+       kfree(conn);
+@@ -379,12 +468,12 @@
+  */
+ void rxrpc_conn_clearall(struct rxrpc_peer *peer)
+ {
+-      DECLARE_WAITQUEUE(myself,current);
++      DECLARE_WAITQUEUE(myself, current);
+       struct rxrpc_connection *conn;
+       int err;
+-      _enter("%p",peer);
++      _enter("%p", peer);
+       /* there shouldn't be any active conns remaining */
+       if (!list_empty(&peer->conn_active))
+@@ -393,11 +482,12 @@
+       /* manually timeout all conns in the graveyard */
+       spin_lock(&peer->conn_gylock);
+       while (!list_empty(&peer->conn_graveyard)) {
+-              conn = list_entry(peer->conn_graveyard.next,struct rxrpc_connection,link);
++              conn = list_entry(peer->conn_graveyard.next,
++                                struct rxrpc_connection, link);
+               err = rxrpc_krxtimod_del_timer(&conn->timeout);
+               spin_unlock(&peer->conn_gylock);
+-              if (err==0)
++              if (err == 0)
+                       rxrpc_conn_do_timeout(conn);
+               spin_lock(&peer->conn_gylock);
+@@ -406,27 +496,27 @@
+       /* wait for the the conn graveyard to be completely cleared */
+       set_current_state(TASK_UNINTERRUPTIBLE);
+-      add_wait_queue(&peer->conn_gy_waitq,&myself);
++      add_wait_queue(&peer->conn_gy_waitq, &myself);
+-      while (atomic_read(&peer->conn_count)!=0) {
++      while (atomic_read(&peer->conn_count) != 0) {
+               schedule();
+               set_current_state(TASK_UNINTERRUPTIBLE);
+       }
+-      remove_wait_queue(&peer->conn_gy_waitq,&myself);
++      remove_wait_queue(&peer->conn_gy_waitq, &myself);
+       set_current_state(TASK_RUNNING);
+       _leave("");
+-
+ } /* end rxrpc_conn_clearall() */
+ /*****************************************************************************/
+ /*
+- * allocate and prepare a message for sending out through the transport endpoint
++ * allocate and prepare a message for sending out through the transport
++ * endpoint
+  */
+ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
+                     struct rxrpc_call *call,
+-                    u8 type,
++                    uint8_t type,
+                     int dcount,
+                     struct iovec diov[],
+                     int alloc_flags,
+@@ -435,21 +525,21 @@
+       struct rxrpc_message *msg;
+       int loop;
+-      _enter("%p{%d},%p,%u",conn,ntohs(conn->addr.sin_port),call,type);
++      _enter("%p{%d},%p,%u", conn, ntohs(conn->addr.sin_port), call, type);
+-      if (dcount>3) {
++      if (dcount > 3) {
+               _leave(" = -EINVAL");
+               return -EINVAL;
+       }
+-      msg = kmalloc(sizeof(struct rxrpc_message),alloc_flags);
++      msg = kmalloc(sizeof(struct rxrpc_message), alloc_flags);
+       if (!msg) {
+               _leave(" = -ENOMEM");
+               return -ENOMEM;
+       }
+-      memset(msg,0,sizeof(*msg));
+-      atomic_set(&msg->usage,1);
++      memset(msg, 0, sizeof(*msg));
++      atomic_set(&msg->usage, 1);
+       INIT_LIST_HEAD(&msg->link);
+@@ -471,7 +561,8 @@
+                       msg->hdr.seq = htonl(msg->seq);
+                       break;
+               case RXRPC_PACKET_TYPE_ACK:
+-                      /* ACK sequence numbers are complicated. The following may be wrong:
++                      /* ACK sequence numbers are complicated. The following
++                       * may be wrong:
+                        * - jumbo packet ACKs should have a seq number
+                        * - normal ACKs should not
+                        */
+@@ -485,7 +576,7 @@
+       msg->data[0].iov_len = sizeof(msg->hdr);
+       msg->data[0].iov_base = &msg->hdr;
+-      for (loop=0; loop<dcount; loop++) {
++      for (loop=0; loop < dcount; loop++) {
+               msg->dsize += diov[loop].iov_len;
+               msg->data[loop+1].iov_len  = diov[loop].iov_len;
+               msg->data[loop+1].iov_base = diov[loop].iov_base;
+@@ -493,7 +584,7 @@
+       __RXACCT(atomic_inc(&rxrpc_message_count));
+       *_msg = msg;
+-      _leave(" = 0 (%p) #%d",msg,atomic_read(&rxrpc_message_count));
++      _leave(" = 0 (%p) #%d", msg, atomic_read(&rxrpc_message_count));
+       return 0;
+ } /* end rxrpc_conn_newmsg() */
+@@ -505,13 +596,14 @@
+ {
+       int loop;
+-      _enter("%p #%d",msg,atomic_read(&rxrpc_message_count));
++      _enter("%p #%d", msg, atomic_read(&rxrpc_message_count));
+-      if (msg->pkt) kfree_skb(msg->pkt);
+-      if (msg->conn) rxrpc_put_connection(msg->conn);
++      if (msg->pkt)
++              kfree_skb(msg->pkt);
++      rxrpc_put_connection(msg->conn);
+-      for (loop=0; loop<8; loop++)
+-              if (test_bit(loop,&msg->dfree))
++      for (loop = 0; loop < 8; loop++)
++              if (test_bit(loop, &msg->dfree))
+                       kfree(msg->data[loop].iov_base);
+       __RXACCT(atomic_dec(&rxrpc_message_count));
+@@ -524,13 +616,14 @@
+ /*
+  * send a message out through the transport endpoint
+  */
+-int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg)
++int rxrpc_conn_sendmsg(struct rxrpc_connection *conn,
++                     struct rxrpc_message *msg)
+ {
+       struct msghdr msghdr;
+       mm_segment_t oldfs;
+       int ret;
+-      _enter("%p{%d}",conn,ntohs(conn->addr.sin_port));
++      _enter("%p{%d}", conn, ntohs(conn->addr.sin_port));
+       /* fill in some fields in the header */
+       spin_lock(&conn->lock);
+@@ -545,7 +638,7 @@
+       msghdr.msg_iovlen       = msg->dcount;
+       msghdr.msg_control      = NULL;
+       msghdr.msg_controllen   = 0;
+-      msghdr.msg_flags        = MSG_CONFIRM|MSG_DONTWAIT;
++      msghdr.msg_flags        = MSG_CONFIRM | MSG_DONTWAIT;
+       _net("Sending message type %d of %Zd bytes to %08x:%d",
+            msg->hdr.type,
+@@ -556,10 +649,10 @@
+       /* send the message */
+       oldfs = get_fs();
+       set_fs(KERNEL_DS);
+-      ret = sock_sendmsg(conn->trans->socket,&msghdr,msg->dsize);
++      ret = sock_sendmsg(conn->trans->socket, &msghdr, msg->dsize);
+       set_fs(oldfs);
+-      if (ret<0) {
++      if (ret < 0) {
+               msg->state = RXRPC_MSG_ERROR;
+       }
+       else {
+@@ -572,7 +665,7 @@
+               spin_unlock(&conn->lock);
+       }
+-      _leave(" = %d",ret);
++      _leave(" = %d", ret);
+       return ret;
+ } /* end rxrpc_conn_sendmsg() */
+@@ -590,7 +683,7 @@
+       unsigned cix, seq;
+       int ret = 0;
+-      _enter("%p,%p,%p",conn,call,msg);
++      _enter("%p,%p,%p", conn, call, msg);
+       if (!call) {
+               cix = ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK;
+@@ -600,7 +693,7 @@
+               if (!call || call->call_id != msg->hdr.callNumber) {
+                       spin_unlock(&conn->lock);
+-                      rxrpc_trans_immediate_abort(conn->trans,msg,-ENOENT);
++                      rxrpc_trans_immediate_abort(conn->trans, msg, -ENOENT);
+                       goto out;
+               }
+               else {
+@@ -622,19 +715,21 @@
+       call->pkt_rcv_count++;
+       if (msg->pkt->dst && msg->pkt->dst->dev)
+-              conn->peer->if_mtu = msg->pkt->dst->dev->mtu - msg->pkt->dst->dev->hard_header_len;
++              conn->peer->if_mtu =
++                      msg->pkt->dst->dev->mtu -
++                      msg->pkt->dst->dev->hard_header_len;
+       /* queue on the call in seq order */
+       rxrpc_get_message(msg);
+       seq = msg->seq;
+       spin_lock(&call->lock);
+-      list_for_each(_p,&call->rcv_receiveq) {
+-              pmsg = list_entry(_p,struct rxrpc_message,link);
+-              if (pmsg->seq>seq)
++      list_for_each(_p, &call->rcv_receiveq) {
++              pmsg = list_entry(_p, struct rxrpc_message, link);
++              if (pmsg->seq > seq)
+                       break;
+       }
+-      list_add_tail(&msg->link,_p);
++      list_add_tail(&msg->link, _p);
+       /* reset the activity timeout */
+       call->flags |= RXRPC_CALL_RCV_PKT;
+@@ -646,8 +741,7 @@
+       rxrpc_put_call(call);
+  out:
+-      _leave(" = %d",ret);
+-
++      _leave(" = %d", ret);
+       return ret;
+ } /* end rxrpc_conn_receive_call_packet() */
+@@ -655,18 +749,19 @@
+ /*
+  * handle an ICMP error being applied to a connection
+  */
+-void rxrpc_conn_handle_error(struct rxrpc_connection *conn, int local, int errno)
++void rxrpc_conn_handle_error(struct rxrpc_connection *conn,
++                           int local, int errno)
+ {
+       struct rxrpc_call *calls[4];
+       int loop;
+-      _enter("%p{%d},%d",conn,ntohs(conn->addr.sin_port),errno);
++      _enter("%p{%d},%d", conn, ntohs(conn->addr.sin_port), errno);
+       /* get a ref to all my calls in one go */
+-      memset(calls,0,sizeof(calls));
++      memset(calls, 0, sizeof(calls));
+       spin_lock(&conn->lock);
+-      for (loop=3; loop>=0; loop--) {
++      for (loop = 3; loop >= 0; loop--) {
+               if (conn->channels[loop]) {
+                       calls[loop] = conn->channels[loop];
+                       rxrpc_get_call(calls[loop]);
+@@ -676,9 +771,9 @@
+       spin_unlock(&conn->lock);
+       /* now kick them all */
+-      for (loop=3; loop>=0; loop--) {
++      for (loop = 3; loop >= 0; loop--) {
+               if (calls[loop]) {
+-                      rxrpc_call_handle_error(calls[loop],local,errno);
++                      rxrpc_call_handle_error(calls[loop], local, errno);
+                       rxrpc_put_call(calls[loop]);
+               }
+       }
+Index: linux-2.6.0-test5/net/rxrpc/internal.h
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/internal.h        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/internal.h     2003-09-27 11:38:42.219110104 +0800
+@@ -55,7 +55,7 @@
+               siginfo_t sinfo;
+               spin_lock_irq(&current->sighand->siglock);
+-              dequeue_signal(current,&current->blocked,&sinfo);
++              dequeue_signal(current, &current->blocked, &sinfo);
+               spin_unlock_irq(&current->sighand->siglock);
+       }
+ }
+@@ -71,6 +71,7 @@
+  */
+ extern struct list_head rxrpc_conns;
+ extern struct rw_semaphore rxrpc_conns_sem;
++extern unsigned long rxrpc_conn_timeout;
+ extern void rxrpc_conn_do_timeout(struct rxrpc_connection *conn);
+ extern void rxrpc_conn_clearall(struct rxrpc_peer *peer);
+@@ -80,6 +81,7 @@
+  */
+ extern struct list_head rxrpc_peers;
+ extern struct rw_semaphore rxrpc_peers_sem;
++extern unsigned long rxrpc_peer_timeout;
+ extern void rxrpc_peer_calculate_rtt(struct rxrpc_peer *peer,
+                                    struct rxrpc_message *msg,
+Index: linux-2.6.0-test5/net/rxrpc/krxiod.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/krxiod.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/krxiod.c       2003-09-27 11:38:42.222109648 +0800
+@@ -44,6 +44,12 @@
+       daemonize("krxiod");
++      /* only certain signals are of interest */
++      spin_lock_irq(&current->sighand->siglock);
++      siginitsetinv(&current->blocked, 0);
++      recalc_sigpending();
++      spin_unlock_irq(&current->sighand->siglock);
++
+       /* loop around waiting for work to do */
+       do {
+               /* wait for work or to be told to exit */
+@@ -51,7 +57,7 @@
+               if (!atomic_read(&rxrpc_krxiod_qcount)) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+-                      add_wait_queue(&rxrpc_krxiod_sleepq,&krxiod);
++                      add_wait_queue(&rxrpc_krxiod_sleepq, &krxiod);
+                       for (;;) {
+                               set_current_state(TASK_INTERRUPTIBLE);
+@@ -63,7 +69,7 @@
+                               schedule();
+                       }
+-                      remove_wait_queue(&rxrpc_krxiod_sleepq,&krxiod);
++                      remove_wait_queue(&rxrpc_krxiod_sleepq, &krxiod);
+                       set_current_state(TASK_RUNNING);
+               }
+               _debug("### End Wait");
+@@ -78,12 +84,16 @@
+                       spin_lock_irq(&rxrpc_krxiod_transportq_lock);
+                       if (!list_empty(&rxrpc_krxiod_transportq)) {
+-                              trans = list_entry(rxrpc_krxiod_transportq.next,
+-                                                 struct rxrpc_transport,krxiodq_link);
++                              trans = list_entry(
++                                      rxrpc_krxiod_transportq.next,
++                                      struct rxrpc_transport,
++                                      krxiodq_link);
++
+                               list_del_init(&trans->krxiodq_link);
+                               atomic_dec(&rxrpc_krxiod_qcount);
+-                              /* make sure it hasn't gone away and doesn't go away */
++                              /* make sure it hasn't gone away and doesn't go
++                               * away */
+                               if (atomic_read(&trans->usage)>0)
+                                       rxrpc_get_transport(trans);
+                               else
+@@ -106,13 +116,16 @@
+                       if (!list_empty(&rxrpc_krxiod_callq)) {
+                               call = list_entry(rxrpc_krxiod_callq.next,
+-                                                 struct rxrpc_call,rcv_krxiodq_lk);
++                                                 struct rxrpc_call,
++                                                rcv_krxiodq_lk);
+                               list_del_init(&call->rcv_krxiodq_lk);
+                               atomic_dec(&rxrpc_krxiod_qcount);
+-                              /* make sure it hasn't gone away and doesn't go away */
+-                              if (atomic_read(&call->usage)>0) {
+-                                      _debug("@@@ KRXIOD Begin Attend Call %p",call);
++                              /* make sure it hasn't gone away and doesn't go
++                               * away */
++                              if (atomic_read(&call->usage) > 0) {
++                                      _debug("@@@ KRXIOD"
++                                             " Begin Attend Call %p",call);
+                                       rxrpc_get_call(call);
+                               }
+                               else {
+@@ -125,7 +138,7 @@
+                       if (call) {
+                               rxrpc_call_do_stuff(call);
+                               rxrpc_put_call(call);
+-                              _debug("@@@ KRXIOD End Attend Call %p",call);
++                              _debug("@@@ KRXIOD End Attend Call %p", call);
+                       }
+               }
+@@ -137,7 +150,7 @@
+       } while (!rxrpc_krxiod_die);
+       /* and that's all */
+-      complete_and_exit(&rxrpc_krxiod_dead,0);
++      complete_and_exit(&rxrpc_krxiod_dead, 0);
+ } /* end rxrpc_krxiod() */
+@@ -147,7 +160,7 @@
+  */
+ int __init rxrpc_krxiod_init(void)
+ {
+-      return kernel_thread(rxrpc_krxiod,NULL,0);
++      return kernel_thread(rxrpc_krxiod, NULL, 0);
+ } /* end rxrpc_krxiod_init() */
+@@ -174,16 +187,17 @@
+       _enter("");
+       if (list_empty(&trans->krxiodq_link)) {
+-              spin_lock_irqsave(&rxrpc_krxiod_transportq_lock,flags);
++              spin_lock_irqsave(&rxrpc_krxiod_transportq_lock, flags);
+               if (list_empty(&trans->krxiodq_link)) {
+-                      if (atomic_read(&trans->usage)>0) {
+-                              list_add_tail(&trans->krxiodq_link,&rxrpc_krxiod_transportq);
++                      if (atomic_read(&trans->usage) > 0) {
++                              list_add_tail(&trans->krxiodq_link,
++                                            &rxrpc_krxiod_transportq);
+                               atomic_inc(&rxrpc_krxiod_qcount);
+                       }
+               }
+-              spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock,flags);
++              spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock, flags);
+               wake_up_all(&rxrpc_krxiod_sleepq);
+       }
+@@ -201,12 +215,12 @@
+       _enter("");
+-      spin_lock_irqsave(&rxrpc_krxiod_transportq_lock,flags);
++      spin_lock_irqsave(&rxrpc_krxiod_transportq_lock, flags);
+       if (!list_empty(&trans->krxiodq_link)) {
+               list_del_init(&trans->krxiodq_link);
+               atomic_dec(&rxrpc_krxiod_qcount);
+       }
+-      spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock,flags);
++      spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock, flags);
+       _leave("");
+@@ -221,15 +235,16 @@
+       unsigned long flags;
+       if (list_empty(&call->rcv_krxiodq_lk)) {
+-              spin_lock_irqsave(&rxrpc_krxiod_callq_lock,flags);
+-              if (atomic_read(&call->usage)>0) {
+-                      list_add_tail(&call->rcv_krxiodq_lk,&rxrpc_krxiod_callq);
++              spin_lock_irqsave(&rxrpc_krxiod_callq_lock, flags);
++              if (atomic_read(&call->usage) > 0) {
++                      list_add_tail(&call->rcv_krxiodq_lk,
++                                    &rxrpc_krxiod_callq);
+                       atomic_inc(&rxrpc_krxiod_qcount);
+               }
+-              spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock,flags);
++              spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock, flags);
+       }
+       wake_up_all(&rxrpc_krxiod_sleepq);
+-      
++
+ } /* end rxrpc_krxiod_queue_call() */
+ /*****************************************************************************/
+@@ -240,11 +255,11 @@
+ {
+       unsigned long flags;
+-      spin_lock_irqsave(&rxrpc_krxiod_callq_lock,flags);
++      spin_lock_irqsave(&rxrpc_krxiod_callq_lock, flags);
+       if (!list_empty(&call->rcv_krxiodq_lk)) {
+               list_del_init(&call->rcv_krxiodq_lk);
+               atomic_dec(&rxrpc_krxiod_qcount);
+       }
+-      spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock,flags);
++      spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock, flags);
+ } /* end rxrpc_krxiod_dequeue_call() */
+Index: linux-2.6.0-test5/net/rxrpc/krxsecd.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/krxsecd.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/krxsecd.c      2003-09-27 11:38:42.225109192 +0800
+@@ -36,7 +36,8 @@
+ static atomic_t rxrpc_krxsecd_qcount;
+-/* queue of unprocessed inbound messages with seqno #1 and RXRPC_CLIENT_INITIATED flag set */
++/* queue of unprocessed inbound messages with seqno #1 and
++ * RXRPC_CLIENT_INITIATED flag set */
+ static LIST_HEAD(rxrpc_krxsecd_initmsgq);
+ static spinlock_t rxrpc_krxsecd_initmsgq_lock = SPIN_LOCK_UNLOCKED;
+@@ -48,14 +49,20 @@
+  */
+ static int rxrpc_krxsecd(void *arg)
+ {
+-      DECLARE_WAITQUEUE(krxsecd,current);
++      DECLARE_WAITQUEUE(krxsecd, current);
+       int die;
+-      printk("Started krxsecd %d\n",current->pid);
++      printk("Started krxsecd %d\n", current->pid);
+       daemonize("krxsecd");
++      /* only certain signals are of interest */
++      spin_lock_irq(&current->sighand->siglock);
++      siginitsetinv(&current->blocked, 0);
++      recalc_sigpending();
++      spin_unlock_irq(&current->sighand->siglock);
++
+       /* loop around waiting for work to do */
+       do {
+               /* wait for work or to be told to exit */
+@@ -63,7 +70,7 @@
+               if (!atomic_read(&rxrpc_krxsecd_qcount)) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+-                      add_wait_queue(&rxrpc_krxsecd_sleepq,&krxsecd);
++                      add_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
+                       for (;;) {
+                               set_current_state(TASK_INTERRUPTIBLE);
+@@ -75,7 +82,7 @@
+                               schedule();
+                       }
+-                      remove_wait_queue(&rxrpc_krxsecd_sleepq,&krxsecd);
++                      remove_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
+                       set_current_state(TASK_RUNNING);
+               }
+               die = rxrpc_krxsecd_die;
+@@ -91,7 +98,7 @@
+                       if (!list_empty(&rxrpc_krxsecd_initmsgq)) {
+                               msg = list_entry(rxrpc_krxsecd_initmsgq.next,
+-                                               struct rxrpc_message,link);
++                                               struct rxrpc_message, link);
+                               list_del_init(&msg->link);
+                               atomic_dec(&rxrpc_krxsecd_qcount);
+                       }
+@@ -112,7 +119,7 @@
+       } while (!die);
+       /* and that's all */
+-      complete_and_exit(&rxrpc_krxsecd_dead,0);
++      complete_and_exit(&rxrpc_krxsecd_dead, 0);
+ } /* end rxrpc_krxsecd() */
+@@ -122,7 +129,7 @@
+  */
+ int __init rxrpc_krxsecd_init(void)
+ {
+-      return kernel_thread(rxrpc_krxsecd,NULL,0);
++      return kernel_thread(rxrpc_krxsecd, NULL, 0);
+ } /* end rxrpc_krxsecd_init() */
+@@ -154,11 +161,11 @@
+       /* move all the messages for this transport onto a temp list */
+       spin_lock(&rxrpc_krxsecd_initmsgq_lock);
+-      list_for_each_safe(_p,_n,&rxrpc_krxsecd_initmsgq) {
+-              msg = list_entry(_p,struct rxrpc_message,link);
+-              if (msg->trans==trans) {
++      list_for_each_safe(_p, _n, &rxrpc_krxsecd_initmsgq) {
++              msg = list_entry(_p, struct rxrpc_message, link);
++              if (msg->trans == trans) {
+                       list_del(&msg->link);
+-                      list_add_tail(&msg->link,&tmp);
++                      list_add_tail(&msg->link, &tmp);
+                       atomic_dec(&rxrpc_krxsecd_qcount);
+               }
+       }
+@@ -167,7 +174,7 @@
+       /* zap all messages on the temp list */
+       while (!list_empty(&tmp)) {
+-              msg = list_entry(tmp.next,struct rxrpc_message,link);
++              msg = list_entry(tmp.next, struct rxrpc_message, link);
+               list_del_init(&msg->link);
+               rxrpc_put_message(msg);
+       }
+@@ -181,14 +188,14 @@
+  */
+ void rxrpc_krxsecd_queue_incoming_call(struct rxrpc_message *msg)
+ {
+-      _enter("%p",msg);
++      _enter("%p", msg);
+       /* queue for processing by krxsecd */
+       spin_lock(&rxrpc_krxsecd_initmsgq_lock);
+       if (!rxrpc_krxsecd_die) {
+               rxrpc_get_message(msg);
+-              list_add_tail(&msg->link,&rxrpc_krxsecd_initmsgq);
++              list_add_tail(&msg->link, &rxrpc_krxsecd_initmsgq);
+               atomic_inc(&rxrpc_krxsecd_qcount);
+       }
+@@ -212,10 +219,10 @@
+       unsigned short sid;
+       int ret;
+-      _enter("%p{tr=%p}",msg,trans);
++      _enter("%p{tr=%p}", msg, trans);
+-      ret = rxrpc_incoming_call(msg->conn,msg,&call);
+-      if (ret<0)
++      ret = rxrpc_incoming_call(msg->conn, msg, &call);
++      if (ret < 0)
+               goto out;
+       /* find the matching service on the transport */
+@@ -223,11 +230,11 @@
+       srv = NULL;
+       spin_lock(&trans->lock);
+-      list_for_each(_p,&trans->services) {
+-              srv = list_entry(_p,struct rxrpc_service,link);
+-              if (srv->service_id==sid && try_module_get(srv->owner)) {
++      list_for_each(_p, &trans->services) {
++              srv = list_entry(_p, struct rxrpc_service, link);
++              if (srv->service_id == sid && try_module_get(srv->owner)) {
+                       /* found a match (made sure it won't vanish) */
+-                      _debug("found service '%s'",srv->name);
++                      _debug("found service '%s'", srv->name);
+                       call->owner = srv->owner;
+                       break;
+               }
+@@ -238,7 +245,7 @@
+        * - the func must inc the call's usage count to keep it
+        */
+       ret = -ENOENT;
+-      if (_p!=&trans->services) {
++      if (_p != &trans->services) {
+               /* attempt to accept the call */
+               call->conn->service = srv;
+               call->app_attn_func = srv->attn_func;
+@@ -248,19 +255,20 @@
+               ret = srv->new_call(call);
+               /* send an abort if an error occurred */
+-              if (ret<0) {
+-                      rxrpc_call_abort(call,ret);
++              if (ret < 0) {
++                      rxrpc_call_abort(call, ret);
+               }
+               else {
+                       /* formally receive and ACK the new packet */
+-                      ret = rxrpc_conn_receive_call_packet(call->conn,call,msg);
++                      ret = rxrpc_conn_receive_call_packet(call->conn,
++                                                           call, msg);
+               }
+       }
+       rxrpc_put_call(call);
+  out:
+-      if (ret<0)
+-              rxrpc_trans_immediate_abort(trans,msg,ret);
++      if (ret < 0)
++              rxrpc_trans_immediate_abort(trans, msg, ret);
+-      _leave(" (%d)",ret);
++      _leave(" (%d)", ret);
+ } /* end rxrpc_krxsecd_process_incoming_call() */
+Index: linux-2.6.0-test5/net/rxrpc/krxtimod.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/krxtimod.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/krxtimod.c     2003-09-27 11:38:42.228108736 +0800
+@@ -36,8 +36,8 @@
+ {
+       int ret;
+-      ret = kernel_thread(krxtimod,NULL,0);
+-      if (ret<0)
++      ret = kernel_thread(krxtimod, NULL, 0);
++      if (ret < 0)
+               return ret;
+       wait_for_completion(&krxtimod_alive);
+@@ -64,30 +64,36 @@
+  */
+ static int krxtimod(void *arg)
+ {
+-      DECLARE_WAITQUEUE(myself,current);
++      DECLARE_WAITQUEUE(myself, current);
+       rxrpc_timer_t *timer;
+-      printk("Started krxtimod %d\n",current->pid);
++      printk("Started krxtimod %d\n", current->pid);
+       daemonize("krxtimod");
+       complete(&krxtimod_alive);
++      /* only certain signals are of interest */
++      spin_lock_irq(&current->sighand->siglock);
++      siginitsetinv(&current->blocked, 0);
++      recalc_sigpending();
++      spin_unlock_irq(&current->sighand->siglock);
++
+       /* loop around looking for things to attend to */
+  loop:
+       set_current_state(TASK_INTERRUPTIBLE);
+-      add_wait_queue(&krxtimod_sleepq,&myself);
++      add_wait_queue(&krxtimod_sleepq, &myself);
+       for (;;) {
+               unsigned long jif;
+-              unsigned long timeout;
++              signed long timeout;
+               /* deal with the server being asked to die */
+               if (krxtimod_die) {
+-                      remove_wait_queue(&krxtimod_sleepq,&myself);
++                      remove_wait_queue(&krxtimod_sleepq, &myself);
+                       _leave("");
+-                      complete_and_exit(&krxtimod_dead,0);
++                      complete_and_exit(&krxtimod_dead, 0);
+               }
+               /* discard pending signals */
+@@ -97,18 +103,19 @@
+               spin_lock(&krxtimod_lock);
+               if (list_empty(&krxtimod_list)) {
+                       timeout = MAX_SCHEDULE_TIMEOUT;
+-              } else {
+-                      unsigned long tmo;
+-
++              }
++              else {
+                       timer = list_entry(krxtimod_list.next,
+                                          rxrpc_timer_t, link);
+-                      tmo = timer->timo_jif;
++                      timeout = timer->timo_jif;
+                       jif = jiffies;
+-                      if (time_before_eq(tmo,jif))
++                      if (time_before_eq((unsigned long) timeout, jif))
+                               goto immediate;
+-                      timeout = (long)tmo - (long)jiffies;
++                      else {
++                              timeout = (long) timeout - (long) jiffies;
++                      }
+               }
+               spin_unlock(&krxtimod_lock);
+@@ -118,13 +125,14 @@
+       }
+       /* the thing on the front of the queue needs processing
+-       * - we come here with the lock held and timer pointing to the expired entry
++       * - we come here with the lock held and timer pointing to the expired
++       *   entry
+        */
+  immediate:
+-      remove_wait_queue(&krxtimod_sleepq,&myself);
++      remove_wait_queue(&krxtimod_sleepq, &myself);
+       set_current_state(TASK_RUNNING);
+-      _debug("@@@ Begin Timeout of %p",timer);
++      _debug("@@@ Begin Timeout of %p", timer);
+       /* dequeue the timer */
+       list_del_init(&timer->link);
+@@ -147,29 +155,30 @@
+       struct list_head *_p;
+       rxrpc_timer_t *ptimer;
+-      _enter("%p,%lu",timer,timeout);
++      _enter("%p,%lu", timer, timeout);
+       spin_lock(&krxtimod_lock);
+       list_del(&timer->link);
+-      /* the timer was deferred or reset - put it back in the queue at the right place */
++      /* the timer was deferred or reset - put it back in the queue at the
++       * right place */
+       timer->timo_jif = jiffies + timeout;
+-      list_for_each(_p,&krxtimod_list) {
+-              ptimer = list_entry(_p,rxrpc_timer_t,link);
+-              if (time_before(timer->timo_jif,ptimer->timo_jif))
++      list_for_each(_p, &krxtimod_list) {
++              ptimer = list_entry(_p, rxrpc_timer_t, link);
++              if (time_before(timer->timo_jif, ptimer->timo_jif))
+                       break;
+       }
+-      list_add_tail(&timer->link,_p); /* insert before stopping point */
++      list_add_tail(&timer->link, _p); /* insert before stopping point */
+       spin_unlock(&krxtimod_lock);
+       wake_up(&krxtimod_sleepq);
+       _leave("");
+-} /* end rxrpc_krxtimod_queue_vlocation() */
++} /* end rxrpc_krxtimod_add_timer() */
+ /*****************************************************************************/
+ /*
+@@ -180,7 +189,7 @@
+ {
+       int ret = 0;
+-      _enter("%p",timer);
++      _enter("%p", timer);
+       spin_lock(&krxtimod_lock);
+@@ -193,6 +202,6 @@
+       wake_up(&krxtimod_sleepq);
+-      _leave(" = %d",ret);
++      _leave(" = %d", ret);
+       return ret;
+ } /* end rxrpc_krxtimod_del_timer() */
+Index: linux-2.6.0-test5/net/rxrpc/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/main.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/main.c 2003-09-27 11:38:42.230108432 +0800
+@@ -32,7 +32,7 @@
+ MODULE_AUTHOR("Red Hat, Inc.");
+ MODULE_LICENSE("GPL");
+-u32 rxrpc_epoch;
++uint32_t rxrpc_epoch;
+ /*****************************************************************************/
+ /*
+@@ -101,11 +101,16 @@
+ {
+       kenter("");
+-      __RXACCT(printk("Outstanding Messages   : %d\n",atomic_read(&rxrpc_message_count)));
+-      __RXACCT(printk("Outstanding Calls      : %d\n",atomic_read(&rxrpc_call_count)));
+-      __RXACCT(printk("Outstanding Connections: %d\n",atomic_read(&rxrpc_connection_count)));
+-      __RXACCT(printk("Outstanding Peers      : %d\n",atomic_read(&rxrpc_peer_count)));
+-      __RXACCT(printk("Outstanding Transports : %d\n",atomic_read(&rxrpc_transport_count)));
++      __RXACCT(printk("Outstanding Messages   : %d\n",
++                      atomic_read(&rxrpc_message_count)));
++      __RXACCT(printk("Outstanding Calls      : %d\n",
++                      atomic_read(&rxrpc_call_count)));
++      __RXACCT(printk("Outstanding Connections: %d\n",
++                      atomic_read(&rxrpc_connection_count)));
++      __RXACCT(printk("Outstanding Peers      : %d\n",
++                      atomic_read(&rxrpc_peer_count)));
++      __RXACCT(printk("Outstanding Transports : %d\n",
++                      atomic_read(&rxrpc_transport_count)));
+       rxrpc_krxsecd_kill();
+       rxrpc_krxiod_kill();
+@@ -117,11 +122,61 @@
+       rxrpc_proc_cleanup();
+ #endif
+-      __RXACCT(printk("Outstanding Messages   : %d\n",atomic_read(&rxrpc_message_count)));
+-      __RXACCT(printk("Outstanding Calls      : %d\n",atomic_read(&rxrpc_call_count)));
+-      __RXACCT(printk("Outstanding Connections: %d\n",atomic_read(&rxrpc_connection_count)));
+-      __RXACCT(printk("Outstanding Peers      : %d\n",atomic_read(&rxrpc_peer_count)));
+-      __RXACCT(printk("Outstanding Transports : %d\n",atomic_read(&rxrpc_transport_count)));
++      __RXACCT(printk("Outstanding Messages   : %d\n",
++                      atomic_read(&rxrpc_message_count)));
++      __RXACCT(printk("Outstanding Calls      : %d\n",
++                      atomic_read(&rxrpc_call_count)));
++      __RXACCT(printk("Outstanding Connections: %d\n",
++                      atomic_read(&rxrpc_connection_count)));
++      __RXACCT(printk("Outstanding Peers      : %d\n",
++                      atomic_read(&rxrpc_peer_count)));
++      __RXACCT(printk("Outstanding Transports : %d\n",
++                      atomic_read(&rxrpc_transport_count)));
+       kleave("");
+ } /* end rxrpc_cleanup() */
++
++/*****************************************************************************/
++/*
++ * clear the dead space between task_struct and kernel stack
++ * - called by supplying -finstrument-functions to gcc
++ */
++#if 0
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_enter (void *this_fn, void *call_site)
++{
++       asm volatile("  movl    %%esp,%%edi     \n"
++                    "  andl    %0,%%edi        \n"
++                    "  addl    %1,%%edi        \n"
++                    "  movl    %%esp,%%ecx     \n"
++                    "  subl    %%edi,%%ecx     \n"
++                    "  shrl    $2,%%ecx        \n"
++                    "  movl    $0xedededed,%%eax     \n"
++                    "  rep stosl               \n"
++                    :
++                    : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++                    : "eax", "ecx", "edi", "memory", "cc"
++                    );
++}
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++__attribute__((no_instrument_function));
++
++void __cyg_profile_func_exit(void *this_fn, void *call_site)
++{
++       asm volatile("  movl    %%esp,%%edi     \n"
++                    "  andl    %0,%%edi        \n"
++                    "  addl    %1,%%edi        \n"
++                    "  movl    %%esp,%%ecx     \n"
++                    "  subl    %%edi,%%ecx     \n"
++                    "  shrl    $2,%%ecx        \n"
++                    "  movl    $0xdadadada,%%eax     \n"
++                    "  rep stosl               \n"
++                    :
++                    : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
++                    : "eax", "ecx", "edi", "memory", "cc"
++                    );
++}
++#endif
+Index: linux-2.6.0-test5/net/rxrpc/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/Makefile  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/Makefile       2003-09-27 11:38:42.231108280 +0800
+@@ -2,7 +2,9 @@
+ # Makefile for Linux kernel Rx RPC
+ #
+-rxrpc-y := \
++#CFLAGS += -finstrument-functions
++
++rxrpc-objs := \
+       call.o \
+       connection.o \
+       krxiod.o \
+@@ -13,7 +15,11 @@
+       rxrpc_syms.o \
+       transport.o
+-rxrpc-$(CONFIG_PROC_FS) += proc.o
+-rxrpc-$(CONFIG_SYSCTL)  += sysctl.o
++ifeq ($(CONFIG_PROC_FS),y)
++rxrpc-objs += proc.o
++endif
++ifeq ($(CONFIG_SYSCTL),y)
++rxrpc-objs += sysctl.o
++endif
+ obj-$(CONFIG_RXRPC) := rxrpc.o
+Index: linux-2.6.0-test5/net/rxrpc/peer.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/peer.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/peer.c 2003-09-27 11:38:42.235107672 +0800
+@@ -28,12 +28,14 @@
+ __RXACCT_DECL(atomic_t rxrpc_peer_count);
+ LIST_HEAD(rxrpc_peers);
+ DECLARE_RWSEM(rxrpc_peers_sem);
++unsigned long rxrpc_peer_timeout = 12 * 60 * 60;
+ static void __rxrpc_peer_timeout(rxrpc_timer_t *timer)
+ {
+-      struct rxrpc_peer *peer = list_entry(timer,struct rxrpc_peer,timeout);
++      struct rxrpc_peer *peer =
++              list_entry(timer, struct rxrpc_peer, timeout);
+-      _debug("Rx PEER TIMEOUT [%p{u=%d}]",peer,atomic_read(&peer->usage));
++      _debug("Rx PEER TIMEOUT [%p{u=%d}]", peer, atomic_read(&peer->usage));
+       rxrpc_peer_do_timeout(peer);
+ }
+@@ -46,32 +48,35 @@
+ /*
+  * create a peer record
+  */
+-static int __rxrpc_create_peer(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer **_peer)
++static int __rxrpc_create_peer(struct rxrpc_transport *trans, uint32_t addr,
++                             struct rxrpc_peer **_peer)
+ {
+       struct rxrpc_peer *peer;
+-      _enter("%p,%08x",trans,ntohl(addr));
++      _enter("%p,%08x", trans, ntohl(addr));
+       /* allocate and initialise a peer record */
+-      peer = kmalloc(sizeof(struct rxrpc_peer),GFP_KERNEL);
++      peer = kmalloc(sizeof(struct rxrpc_peer), GFP_KERNEL);
+       if (!peer) {
+               _leave(" = -ENOMEM");
+               return -ENOMEM;
+       }
+-      memset(peer,0,sizeof(struct rxrpc_peer));
+-      atomic_set(&peer->usage,1);
++      memset(peer, 0, sizeof(struct rxrpc_peer));
++      atomic_set(&peer->usage, 1);
+       INIT_LIST_HEAD(&peer->link);
+       INIT_LIST_HEAD(&peer->proc_link);
++      INIT_LIST_HEAD(&peer->conn_idlist);
+       INIT_LIST_HEAD(&peer->conn_active);
+       INIT_LIST_HEAD(&peer->conn_graveyard);
+       spin_lock_init(&peer->conn_gylock);
+       init_waitqueue_head(&peer->conn_gy_waitq);
++      rwlock_init(&peer->conn_idlock);
+       rwlock_init(&peer->conn_lock);
+-      atomic_set(&peer->conn_count,0);
++      atomic_set(&peer->conn_count, 0);
+       spin_lock_init(&peer->lock);
+-      rxrpc_timer_init(&peer->timeout,&rxrpc_peer_timer_ops);
++      rxrpc_timer_init(&peer->timeout, &rxrpc_peer_timer_ops);
+       peer->addr.s_addr = addr;
+@@ -80,7 +85,7 @@
+       __RXACCT(atomic_inc(&rxrpc_peer_count));
+       *_peer = peer;
+-      _leave(" = 0 (%p)",peer);
++      _leave(" = 0 (%p)", peer);
+       return 0;
+ } /* end __rxrpc_create_peer() */
+@@ -91,43 +96,45 @@
+  * - returns (if successful) with peer record usage incremented
+  * - resurrects it from the graveyard if found there
+  */
+-int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer **_peer)
++int rxrpc_peer_lookup(struct rxrpc_transport *trans, uint32_t addr,
++                    struct rxrpc_peer **_peer)
+ {
+       struct rxrpc_peer *peer, *candidate = NULL;
+       struct list_head *_p;
+       int ret;
+-      _enter("%p{%hu},%08x",trans,trans->port,ntohl(addr));
++      _enter("%p{%hu},%08x", trans, trans->port, ntohl(addr));
+       /* [common case] search the transport's active list first */
+       read_lock(&trans->peer_lock);
+-      list_for_each(_p,&trans->peer_active) {
+-              peer = list_entry(_p,struct rxrpc_peer,link);
+-              if (peer->addr.s_addr==addr)
++      list_for_each(_p, &trans->peer_active) {
++              peer = list_entry(_p, struct rxrpc_peer, link);
++              if (peer->addr.s_addr == addr)
+                       goto found_active;
+       }
+       read_unlock(&trans->peer_lock);
+       /* [uncommon case] not active - create a candidate for a new record */
+-      ret = __rxrpc_create_peer(trans,addr,&candidate);
+-      if (ret<0) {
+-              _leave(" = %d",ret);
++      ret = __rxrpc_create_peer(trans, addr, &candidate);
++      if (ret < 0) {
++              _leave(" = %d", ret);
+               return ret;
+       }
+-      /* search the active list again, just in case it appeared whilst we were busy */
++      /* search the active list again, just in case it appeared whilst we
++       * were busy */
+       write_lock(&trans->peer_lock);
+-      list_for_each(_p,&trans->peer_active) {
+-              peer = list_entry(_p,struct rxrpc_peer,link);
+-              if (peer->addr.s_addr==addr)
++      list_for_each(_p, &trans->peer_active) {
++              peer = list_entry(_p, struct rxrpc_peer, link);
++              if (peer->addr.s_addr == addr)
+                       goto found_active_second_chance;
+       }
+       /* search the transport's graveyard list */
+       spin_lock(&trans->peer_gylock);
+-      list_for_each(_p,&trans->peer_graveyard) {
+-              peer = list_entry(_p,struct rxrpc_peer,link);
+-              if (peer->addr.s_addr==addr)
++      list_for_each(_p, &trans->peer_graveyard) {
++              peer = list_entry(_p, struct rxrpc_peer, link);
++              if (peer->addr.s_addr == addr)
+                       goto found_in_graveyard;
+       }
+       spin_unlock(&trans->peer_gylock);
+@@ -141,12 +148,12 @@
+       if (peer->ops && peer->ops->adding) {
+               ret = peer->ops->adding(peer);
+-              if (ret<0) {
++              if (ret < 0) {
+                       write_unlock(&trans->peer_lock);
+                       __RXACCT(atomic_dec(&rxrpc_peer_count));
+                       kfree(peer);
+                       rxrpc_put_transport(trans);
+-                      _leave(" = %d",ret);
++                      _leave(" = %d", ret);
+                       return ret;
+               }
+       }
+@@ -154,7 +161,7 @@
+       atomic_inc(&trans->peer_count);
+  make_active:
+-      list_add_tail(&peer->link,&trans->peer_active);
++      list_add_tail(&peer->link, &trans->peer_active);
+  success_uwfree:
+       write_unlock(&trans->peer_lock);
+@@ -166,7 +173,7 @@
+       if (list_empty(&peer->proc_link)) {
+               down_write(&rxrpc_peers_sem);
+-              list_add_tail(&peer->proc_link,&rxrpc_peers);
++              list_add_tail(&peer->proc_link, &rxrpc_peers);
+               up_write(&rxrpc_peers_sem);
+       }
+@@ -174,7 +181,9 @@
+       *_peer = peer;
+       _leave(" = 0 (%p{u=%d cc=%d})",
+-             peer,atomic_read(&peer->usage),atomic_read(&peer->conn_count));
++             peer,
++             atomic_read(&peer->usage),
++             atomic_read(&peer->conn_count));
+       return 0;
+       /* handle the peer being found in the active list straight off */
+@@ -192,7 +201,8 @@
+       spin_unlock(&trans->peer_gylock);
+       goto make_active;
+-      /* handle finding the peer on the second time through the active list */
++      /* handle finding the peer on the second time through the active
++       * list */
+  found_active_second_chance:
+       rxrpc_get_peer(peer);
+       goto success_uwfree;
+@@ -202,16 +212,20 @@
+ /*****************************************************************************/
+ /*
+  * finish with a peer record
+- * - it gets sent to the graveyard from where it can be resurrected or timed out
++ * - it gets sent to the graveyard from where it can be resurrected or timed
++ *   out
+  */
+ void rxrpc_put_peer(struct rxrpc_peer *peer)
+ {
+       struct rxrpc_transport *trans = peer->trans;
+-      _enter("%p{cc=%d a=%08x}",peer,atomic_read(&peer->conn_count),ntohl(peer->addr.s_addr));
++      _enter("%p{cc=%d a=%08x}",
++             peer,
++             atomic_read(&peer->conn_count),
++             ntohl(peer->addr.s_addr));
+       /* sanity check */
+-      if (atomic_read(&peer->usage)<=0)
++      if (atomic_read(&peer->usage) <= 0)
+               BUG();
+       write_lock(&trans->peer_lock);
+@@ -227,12 +241,11 @@
+       list_del(&peer->link);
+       write_unlock(&trans->peer_lock);
+-      list_add_tail(&peer->link,&trans->peer_graveyard);
++      list_add_tail(&peer->link, &trans->peer_graveyard);
+-      if (!list_empty(&peer->conn_active)) BUG();
++      BUG_ON(!list_empty(&peer->conn_active));
+-      /* discard in 600 secs */
+-      rxrpc_krxtimod_add_timer(&peer->timeout,100*HZ);
++      rxrpc_krxtimod_add_timer(&peer->timeout, rxrpc_peer_timeout * HZ);
+       spin_unlock(&trans->peer_gylock);
+@@ -251,15 +264,16 @@
+       struct rxrpc_transport *trans = peer->trans;
+       _enter("%p{u=%d cc=%d a=%08x}",
+-             peer,atomic_read(&peer->usage),atomic_read(&peer->conn_count),
++             peer,
++             atomic_read(&peer->usage),
++             atomic_read(&peer->conn_count),
+              ntohl(peer->addr.s_addr));
+-      if (atomic_read(&peer->usage)<0)
+-              BUG();
++      BUG_ON(atomic_read(&peer->usage) < 0);
+       /* remove from graveyard if still dead */
+       spin_lock(&trans->peer_gylock);
+-      if (atomic_read(&peer->usage)==0)
++      if (atomic_read(&peer->usage) == 0)
+               list_del_init(&peer->link);
+       else
+               peer = NULL;
+@@ -273,8 +287,8 @@
+       /* clear all connections on this peer */
+       rxrpc_conn_clearall(peer);
+-      if (!list_empty(&peer->conn_active)) BUG();
+-      if (!list_empty(&peer->conn_graveyard)) BUG();
++      BUG_ON(!list_empty(&peer->conn_active));
++      BUG_ON(!list_empty(&peer->conn_graveyard));
+       /* inform the application layer */
+       if (peer->ops && peer->ops->discarding)
+@@ -310,18 +324,18 @@
+       _enter("%p",trans);
+       /* there shouldn't be any active peers remaining */
+-      if (!list_empty(&trans->peer_active))
+-              BUG();
++      BUG_ON(!list_empty(&trans->peer_active));
+       /* manually timeout all peers in the graveyard */
+       spin_lock(&trans->peer_gylock);
+       while (!list_empty(&trans->peer_graveyard)) {
+-              peer = list_entry(trans->peer_graveyard.next,struct rxrpc_peer,link);
+-              _debug("Clearing peer %p\n",peer);
++              peer = list_entry(trans->peer_graveyard.next,
++                                struct rxrpc_peer, link);
++              _debug("Clearing peer %p\n", peer);
+               err = rxrpc_krxtimod_del_timer(&peer->timeout);
+               spin_unlock(&trans->peer_gylock);
+-              if (err==0)
++              if (err == 0)
+                       rxrpc_peer_do_timeout(peer);
+               spin_lock(&trans->peer_gylock);
+@@ -330,18 +344,17 @@
+       /* wait for the the peer graveyard to be completely cleared */
+       set_current_state(TASK_UNINTERRUPTIBLE);
+-      add_wait_queue(&trans->peer_gy_waitq,&myself);
++      add_wait_queue(&trans->peer_gy_waitq, &myself);
+-      while (atomic_read(&trans->peer_count)!=0) {
++      while (atomic_read(&trans->peer_count) != 0) {
+               schedule();
+               set_current_state(TASK_UNINTERRUPTIBLE);
+       }
+-      remove_wait_queue(&trans->peer_gy_waitq,&myself);
++      remove_wait_queue(&trans->peer_gy_waitq, &myself);
+       set_current_state(TASK_RUNNING);
+       _leave("");
+-
+ } /* end rxrpc_peer_clearall() */
+ /*****************************************************************************/
+@@ -355,7 +368,7 @@
+       unsigned long long rtt;
+       int loop;
+-      _enter("%p,%p,%p",peer,msg,resp);
++      _enter("%p,%p,%p", peer, msg, resp);
+       /* calculate the latest RTT */
+       rtt = resp->stamp.tv_sec - msg->stamp.tv_sec;
+@@ -367,16 +380,18 @@
+       peer->rtt_point++;
+       peer->rtt_point %= RXRPC_RTT_CACHE_SIZE;
+-      if (peer->rtt_usage<RXRPC_RTT_CACHE_SIZE) peer->rtt_usage++;
++      if (peer->rtt_usage < RXRPC_RTT_CACHE_SIZE)
++              peer->rtt_usage++;
+       /* recalculate RTT */
+       rtt = 0;
+-      for (loop=peer->rtt_usage-1; loop>=0; loop--)
++      for (loop = peer->rtt_usage - 1; loop >= 0; loop--)
+               rtt += peer->rtt_cache[loop];
+-      do_div(rtt,peer->rtt_usage);
++      do_div(rtt, peer->rtt_usage);
+       peer->rtt = rtt;
+-      _leave(" RTT=%lu.%lums",(long)(peer->rtt/1000),(long)(peer->rtt%1000));
++      _leave(" RTT=%lu.%lums",
++             (long) (peer->rtt / 1000), (long) (peer->rtt % 1000));
+ } /* end rxrpc_peer_calculate_rtt() */
+Index: linux-2.6.0-test5/net/rxrpc/proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/proc.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/proc.c 2003-09-27 11:38:42.241106760 +0800
+@@ -38,7 +38,6 @@
+ };
+ static struct file_operations rxrpc_proc_transports_fops = {
+-      .owner          = THIS_MODULE,
+       .open           = rxrpc_proc_transports_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+@@ -59,7 +58,6 @@
+ };
+ static struct file_operations rxrpc_proc_peers_fops = {
+-      .owner          = THIS_MODULE,
+       .open           = rxrpc_proc_peers_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+@@ -80,7 +78,6 @@
+ };
+ static struct file_operations rxrpc_proc_conns_fops = {
+-      .owner          = THIS_MODULE,
+       .open           = rxrpc_proc_conns_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+@@ -101,7 +98,6 @@
+ };
+ static struct file_operations rxrpc_proc_calls_fops = {
+-      .owner          = THIS_MODULE,
+       .open           = rxrpc_proc_calls_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+@@ -137,30 +133,30 @@
+ {
+       struct proc_dir_entry *p;
+-      proc_rxrpc = proc_mkdir("rxrpc",proc_net);
++      proc_rxrpc = proc_mkdir("rxrpc", proc_net);
+       if (!proc_rxrpc)
+               goto error;
+       proc_rxrpc->owner = THIS_MODULE;
+-      p = create_proc_entry("calls",0,proc_rxrpc);
++      p = create_proc_entry("calls", 0, proc_rxrpc);
+       if (!p)
+               goto error_proc;
+       p->proc_fops = &rxrpc_proc_calls_fops;
+       p->owner = THIS_MODULE;
+-      p = create_proc_entry("connections",0,proc_rxrpc);
++      p = create_proc_entry("connections", 0, proc_rxrpc);
+       if (!p)
+               goto error_calls;
+       p->proc_fops = &rxrpc_proc_conns_fops;
+       p->owner = THIS_MODULE;
+-      p = create_proc_entry("peers",0,proc_rxrpc);
++      p = create_proc_entry("peers", 0, proc_rxrpc);
+       if (!p)
+               goto error_calls;
+       p->proc_fops = &rxrpc_proc_peers_fops;
+       p->owner = THIS_MODULE;
+-      p = create_proc_entry("transports",0,proc_rxrpc);
++      p = create_proc_entry("transports", 0, proc_rxrpc);
+       if (!p)
+               goto error_conns;
+       p->proc_fops = &rxrpc_proc_transports_fops;
+@@ -169,11 +165,11 @@
+       return 0;
+  error_conns:
+-      remove_proc_entry("conns",proc_rxrpc);
++      remove_proc_entry("connections", proc_rxrpc);
+  error_calls:
+-      remove_proc_entry("calls",proc_rxrpc);
++      remove_proc_entry("calls", proc_rxrpc);
+  error_proc:
+-      remove_proc_entry("rxrpc",proc_net);
++      remove_proc_entry("rxrpc", proc_net);
+  error:
+       return -ENOMEM;
+ } /* end rxrpc_proc_init() */
+@@ -184,12 +180,12 @@
+  */
+ void rxrpc_proc_cleanup(void)
+ {
+-      remove_proc_entry("transports",proc_rxrpc);
+-      remove_proc_entry("peers",proc_rxrpc);
+-      remove_proc_entry("connections",proc_rxrpc);
+-      remove_proc_entry("calls",proc_rxrpc);
++      remove_proc_entry("transports", proc_rxrpc);
++      remove_proc_entry("peers", proc_rxrpc);
++      remove_proc_entry("connections", proc_rxrpc);
++      remove_proc_entry("calls", proc_rxrpc);
+-      remove_proc_entry("rxrpc",proc_net);
++      remove_proc_entry("rxrpc", proc_net);
+ } /* end rxrpc_proc_cleanup() */
+@@ -202,8 +198,8 @@
+       struct seq_file *m;
+       int ret;
+-      ret = seq_open(file,&rxrpc_proc_transports_ops);
+-      if (ret<0)
++      ret = seq_open(file, &rxrpc_proc_transports_ops);
++      if (ret < 0)
+               return ret;
+       m = file->private_data;
+@@ -226,15 +222,15 @@
+       /* allow for the header line */
+       if (!pos)
+-              return (void *)1;
++              return SEQ_START_TOKEN;
+       pos--;
+       /* find the n'th element in the list */
+-      list_for_each(_p,&rxrpc_proc_transports)
++      list_for_each(_p, &rxrpc_proc_transports)
+               if (!pos--)
+                       break;
+-      return _p!=&rxrpc_proc_transports ? _p : NULL;
++      return _p != &rxrpc_proc_transports ? _p : NULL;
+ } /* end rxrpc_proc_transports_start() */
+ /*****************************************************************************/
+@@ -248,9 +244,9 @@
+       (*pos)++;
+       _p = v;
+-      _p = v==(void*)1 ? rxrpc_proc_transports.next : _p->next;
++      _p = (v == SEQ_START_TOKEN) ? rxrpc_proc_transports.next : _p->next;
+-      return _p!=&rxrpc_proc_transports ? _p : NULL;
++      return _p != &rxrpc_proc_transports ? _p : NULL;
+ } /* end rxrpc_proc_transports_next() */
+ /*****************************************************************************/
+@@ -269,16 +265,17 @@
+  */
+ static int rxrpc_proc_transports_show(struct seq_file *m, void *v)
+ {
+-      struct rxrpc_transport *trans = list_entry(v,struct rxrpc_transport,proc_link);
++      struct rxrpc_transport *trans =
++              list_entry(v, struct rxrpc_transport, proc_link);
+       /* display header on line 1 */
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(m, "LOCAL USE\n");
+               return 0;
+       }
+       /* display one transport per line on subsequent lines */
+-      seq_printf(m,"%5hu %3d\n",
++      seq_printf(m, "%5hu %3d\n",
+                  trans->port,
+                  atomic_read(&trans->usage)
+                  );
+@@ -295,8 +292,8 @@
+       struct seq_file *m;
+       int ret;
+-      ret = seq_open(file,&rxrpc_proc_peers_ops);
+-      if (ret<0)
++      ret = seq_open(file, &rxrpc_proc_peers_ops);
++      if (ret < 0)
+               return ret;
+       m = file->private_data;
+@@ -307,7 +304,8 @@
+ /*****************************************************************************/
+ /*
+- * set up the iterator to start reading from the peers list and return the first item
++ * set up the iterator to start reading from the peers list and return the
++ * first item
+  */
+ static void *rxrpc_proc_peers_start(struct seq_file *m, loff_t *_pos)
+ {
+@@ -319,15 +317,15 @@
+       /* allow for the header line */
+       if (!pos)
+-              return (void *)1;
++              return SEQ_START_TOKEN;
+       pos--;
+       /* find the n'th element in the list */
+-      list_for_each(_p,&rxrpc_peers)
++      list_for_each(_p, &rxrpc_peers)
+               if (!pos--)
+                       break;
+-      return _p!=&rxrpc_peers ? _p : NULL;
++      return _p != &rxrpc_peers ? _p : NULL;
+ } /* end rxrpc_proc_peers_start() */
+ /*****************************************************************************/
+@@ -341,9 +339,9 @@
+       (*pos)++;
+       _p = v;
+-      _p = v==(void*)1 ? rxrpc_peers.next : _p->next;
++      _p = (v == SEQ_START_TOKEN) ? rxrpc_peers.next : _p->next;
+-      return _p!=&rxrpc_peers ? _p : NULL;
++      return _p != &rxrpc_peers ? _p : NULL;
+ } /* end rxrpc_proc_peers_next() */
+ /*****************************************************************************/
+@@ -362,21 +360,23 @@
+  */
+ static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
+ {
+-      struct rxrpc_peer *peer = list_entry(v,struct rxrpc_peer,proc_link);
++      struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link);
+       signed long timeout;
+       /* display header on line 1 */
+-      if (v == (void *)1) {
+-              seq_puts(m,"LOCAL REMOTE   USAGE CONNS  TIMEOUT   MTU RTT(uS)\n");
++      if (v == SEQ_START_TOKEN) {
++              seq_puts(m, "LOCAL REMOTE   USAGE CONNS  TIMEOUT"
++                       "   MTU RTT(uS)\n");
+               return 0;
+       }
+       /* display one peer per line on subsequent lines */
+       timeout = 0;
+       if (!list_empty(&peer->timeout.link))
+-              timeout = (signed long)peer->timeout.timo_jif - (signed long)jiffies;
++              timeout = (signed long) peer->timeout.timo_jif -
++                      (signed long) jiffies;
+-      seq_printf(m,"%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
++      seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
+                  peer->trans->port,
+                  ntohl(peer->addr.s_addr),
+                  atomic_read(&peer->usage),
+@@ -391,15 +391,16 @@
+ /*****************************************************************************/
+ /*
+- * open "/proc/net/rxrpc/connections" which provides a summary of extant connections
++ * open "/proc/net/rxrpc/connections" which provides a summary of extant
++ * connections
+  */
+ static int rxrpc_proc_conns_open(struct inode *inode, struct file *file)
+ {
+       struct seq_file *m;
+       int ret;
+-      ret = seq_open(file,&rxrpc_proc_conns_ops);
+-      if (ret<0)
++      ret = seq_open(file, &rxrpc_proc_conns_ops);
++      if (ret < 0)
+               return ret;
+       m = file->private_data;
+@@ -410,7 +411,8 @@
+ /*****************************************************************************/
+ /*
+- * set up the iterator to start reading from the conns list and return the first item
++ * set up the iterator to start reading from the conns list and return the
++ * first item
+  */
+ static void *rxrpc_proc_conns_start(struct seq_file *m, loff_t *_pos)
+ {
+@@ -422,15 +424,15 @@
+       /* allow for the header line */
+       if (!pos)
+-              return (void *)1;
++              return SEQ_START_TOKEN;
+       pos--;
+       /* find the n'th element in the list */
+-      list_for_each(_p,&rxrpc_conns)
++      list_for_each(_p, &rxrpc_conns)
+               if (!pos--)
+                       break;
+-      return _p!=&rxrpc_conns ? _p : NULL;
++      return _p != &rxrpc_conns ? _p : NULL;
+ } /* end rxrpc_proc_conns_start() */
+ /*****************************************************************************/
+@@ -444,9 +446,9 @@
+       (*pos)++;
+       _p = v;
+-      _p = v==(void*)1 ? rxrpc_conns.next : _p->next;
++      _p = (v == SEQ_START_TOKEN) ? rxrpc_conns.next : _p->next;
+-      return _p!=&rxrpc_conns ? _p : NULL;
++      return _p != &rxrpc_conns ? _p : NULL;
+ } /* end rxrpc_proc_conns_next() */
+ /*****************************************************************************/
+@@ -465,13 +467,16 @@
+  */
+ static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
+ {
+-      struct rxrpc_connection *conn = list_entry(v,struct rxrpc_connection,proc_link);
++      struct rxrpc_connection *conn;
+       signed long timeout;
++      conn = list_entry(v, struct rxrpc_connection, proc_link);
++
+       /* display header on line 1 */
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(m,
+-                       "LOCAL REMOTE   RPORT SRVC CONN     END SERIALNO CALLNO     MTU  TIMEOUT"
++                       "LOCAL REMOTE   RPORT SRVC CONN     END SERIALNO "
++                       "CALLNO     MTU  TIMEOUT"
+                        "\n");
+               return 0;
+       }
+@@ -479,9 +484,11 @@
+       /* display one conn per line on subsequent lines */
+       timeout = 0;
+       if (!list_empty(&conn->timeout.link))
+-              timeout = (signed long)conn->timeout.timo_jif - (signed long)jiffies;
++              timeout = (signed long) conn->timeout.timo_jif -
++                      (signed long) jiffies;
+-      seq_printf(m,"%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
++      seq_printf(m,
++                 "%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
+                  conn->trans->port,
+                  ntohl(conn->addr.sin_addr.s_addr),
+                  ntohs(conn->addr.sin_port),
+@@ -506,8 +513,8 @@
+       struct seq_file *m;
+       int ret;
+-      ret = seq_open(file,&rxrpc_proc_calls_ops);
+-      if (ret<0)
++      ret = seq_open(file, &rxrpc_proc_calls_ops);
++      if (ret < 0)
+               return ret;
+       m = file->private_data;
+@@ -518,7 +525,8 @@
+ /*****************************************************************************/
+ /*
+- * set up the iterator to start reading from the calls list and return the first item
++ * set up the iterator to start reading from the calls list and return the
++ * first item
+  */
+ static void *rxrpc_proc_calls_start(struct seq_file *m, loff_t *_pos)
+ {
+@@ -530,15 +538,15 @@
+       /* allow for the header line */
+       if (!pos)
+-              return (void *)1;
++              return SEQ_START_TOKEN;
+       pos--;
+       /* find the n'th element in the list */
+-      list_for_each(_p,&rxrpc_calls)
++      list_for_each(_p, &rxrpc_calls)
+               if (!pos--)
+                       break;
+-      return _p!=&rxrpc_calls ? _p : NULL;
++      return _p != &rxrpc_calls ? _p : NULL;
+ } /* end rxrpc_proc_calls_start() */
+ /*****************************************************************************/
+@@ -552,9 +560,9 @@
+       (*pos)++;
+       _p = v;
+-      _p = v==(void*)1 ? rxrpc_calls.next : _p->next;
++      _p = (v == SEQ_START_TOKEN) ? rxrpc_calls.next : _p->next;
+-      return _p!=&rxrpc_calls ? _p : NULL;
++      return _p != &rxrpc_calls ? _p : NULL;
+ } /* end rxrpc_proc_calls_next() */
+ /*****************************************************************************/
+@@ -573,10 +581,10 @@
+  */
+ static int rxrpc_proc_calls_show(struct seq_file *m, void *v)
+ {
+-      struct rxrpc_call *call = list_entry(v,struct rxrpc_call,call_link);
++      struct rxrpc_call *call = list_entry(v, struct rxrpc_call, call_link);
+       /* display header on line 1 */
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(m,
+                        "LOCAL REMOT SRVC CONN     CALL     DIR USE "
+                        " L STATE   OPCODE ABORT    ERRNO\n"
+Index: linux-2.6.0-test5/net/rxrpc/sysctl.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/sysctl.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/sysctl.c       2003-09-27 11:38:42.242106608 +0800
+@@ -60,6 +60,22 @@
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
++        {
++              .ctl_name       = 5,
++              .procname       = "peertimo",
++              .data           = &rxrpc_peer_timeout,
++              .maxlen         = sizeof(unsigned long),
++              .mode           = 0644,
++              .proc_handler   = &proc_doulongvec_minmax
++      },
++        {
++              .ctl_name       = 6,
++              .procname       = "conntimo",
++              .data           = &rxrpc_conn_timeout,
++              .maxlen         = sizeof(unsigned long),
++              .mode           = 0644,
++              .proc_handler   = &proc_doulongvec_minmax
++      },
+       { .ctl_name = 0 }
+ };
+@@ -67,6 +83,7 @@
+       {
+               .ctl_name       = 1,
+               .procname       = "rxrpc",
++              .maxlen         = 0,
+               .mode           = 0555,
+               .child          = rxrpc_sysctl_table
+       },
+@@ -81,7 +98,7 @@
+ int rxrpc_sysctl_init(void)
+ {
+ #ifdef CONFIG_SYSCTL
+-      rxrpc_sysctl = register_sysctl_table(rxrpc_dir_sysctl_table,0);
++      rxrpc_sysctl = register_sysctl_table(rxrpc_dir_sysctl_table, 0);
+       if (!rxrpc_sysctl)
+               return -ENOMEM;
+ #endif /* CONFIG_SYSCTL */
+Index: linux-2.6.0-test5/net/rxrpc/transport.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/rxrpc/transport.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/rxrpc/transport.c    2003-09-27 11:38:42.265103112 +0800
+@@ -56,7 +56,8 @@
+ /*
+  * create a new transport endpoint using the specified UDP port
+  */
+-int rxrpc_create_transport(unsigned short port, struct rxrpc_transport **_trans)
++int rxrpc_create_transport(unsigned short port,
++                         struct rxrpc_transport **_trans)
+ {
+       struct rxrpc_transport *trans;
+       struct sockaddr_in sin;
+@@ -64,14 +65,14 @@
+       struct sock *sock;
+       int ret, opt;
+-      _enter("%hu",port);
++      _enter("%hu", port);
+-      trans = kmalloc(sizeof(struct rxrpc_transport),GFP_KERNEL);
++      trans = kmalloc(sizeof(struct rxrpc_transport), GFP_KERNEL);
+       if (!trans)
+               return -ENOMEM;
+-      memset(trans,0,sizeof(struct rxrpc_transport));
+-      atomic_set(&trans->usage,1);
++      memset(trans, 0, sizeof(struct rxrpc_transport));
++      atomic_set(&trans->usage, 1);
+       INIT_LIST_HEAD(&trans->services);
+       INIT_LIST_HEAD(&trans->link);
+       INIT_LIST_HEAD(&trans->krxiodq_link);
+@@ -81,58 +82,58 @@
+       spin_lock_init(&trans->peer_gylock);
+       init_waitqueue_head(&trans->peer_gy_waitq);
+       rwlock_init(&trans->peer_lock);
+-      atomic_set(&trans->peer_count,0);
++      atomic_set(&trans->peer_count, 0);
+       trans->port = port;
+       /* create a UDP socket to be my actual transport endpoint */
+-      ret = sock_create(PF_INET,SOCK_DGRAM,IPPROTO_UDP,&trans->socket);
+-      if (ret<0)
++      ret = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &trans->socket);
++      if (ret < 0)
+               goto error;
+       /* use the specified port */
+       if (port) {
+-              memset(&sin,0,sizeof(sin));
++              memset(&sin, 0, sizeof(sin));
+               sin.sin_family = AF_INET;
+               sin.sin_port = htons(port);
+-              ret = trans->socket->ops->bind(trans->socket,(struct sockaddr *)&sin,sizeof(sin));
+-              if (ret<0)
++              ret = trans->socket->ops->bind(trans->socket,
++                                             (struct sockaddr *) &sin,
++                                             sizeof(sin));
++              if (ret < 0)
+                       goto error;
+       }
+       opt = 1;
+       oldfs = get_fs();
+       set_fs(KERNEL_DS);
+-      ret = trans->socket->ops->setsockopt(trans->socket,SOL_IP,IP_RECVERR,
+-                                           (char*)&opt,sizeof(opt));
++      ret = trans->socket->ops->setsockopt(trans->socket, SOL_IP, IP_RECVERR,
++                                           (char *) &opt, sizeof(opt));
+       set_fs(oldfs);
+       spin_lock(&rxrpc_transports_lock);
+-      list_add(&trans->link,&rxrpc_transports);
++      list_add(&trans->link, &rxrpc_transports);
+       spin_unlock(&rxrpc_transports_lock);
+       /* set the socket up */
+       sock = trans->socket->sk;
+-      sock->sk_user_data = trans;
+-      sock->sk_data_ready = rxrpc_data_ready;
+-      sock->sk_error_report = rxrpc_error_report;
++      sock->sk_user_data      = trans;
++      sock->sk_data_ready     = rxrpc_data_ready;
++      sock->sk_error_report   = rxrpc_error_report;
+       down_write(&rxrpc_proc_transports_sem);
+-      list_add_tail(&trans->proc_link,&rxrpc_proc_transports);
++      list_add_tail(&trans->proc_link, &rxrpc_proc_transports);
+       up_write(&rxrpc_proc_transports_sem);
+       __RXACCT(atomic_inc(&rxrpc_transport_count));
+       *_trans = trans;
+-      _leave(" = 0 (%p)",trans);
++      _leave(" = 0 (%p)", trans);
+       return 0;
+  error:
+       rxrpc_put_transport(trans);
+-      _leave(" = %d",ret);
+-
++      _leave(" = %d", ret);
+       return ret;
+-
+ } /* end rxrpc_create_transport() */
+ /*****************************************************************************/
+@@ -151,12 +152,13 @@
+  */
+ void rxrpc_put_transport(struct rxrpc_transport *trans)
+ {
+-      _enter("%p{u=%d p=%hu}",trans,atomic_read(&trans->usage),trans->port);
++      _enter("%p{u=%d p=%hu}",
++             trans, atomic_read(&trans->usage), trans->port);
+-      if (atomic_read(&trans->usage)<=0)
+-              BUG();
++      BUG_ON(atomic_read(&trans->usage) <= 0);
+-      /* to prevent a race, the decrement and the dequeue must be effectively atomic */
++      /* to prevent a race, the decrement and the dequeue must be
++       * effectively atomic */
+       spin_lock(&rxrpc_transports_lock);
+       if (likely(!atomic_dec_and_test(&trans->usage))) {
+               spin_unlock(&rxrpc_transports_lock);
+@@ -169,7 +171,7 @@
+       /* finish cleaning up the transport */
+       if (trans->socket)
+-              trans->socket->ops->shutdown(trans->socket,2);
++              trans->socket->ops->shutdown(trans->socket, 2);
+       rxrpc_krxsecd_clear_transport(trans);
+       rxrpc_krxiod_dequeue_transport(trans);
+@@ -192,41 +194,41 @@
+       kfree(trans);
+       _leave("");
+-
+ } /* end rxrpc_put_transport() */
+ /*****************************************************************************/
+ /*
+  * add a service to a transport to be listened upon
+  */
+-int rxrpc_add_service(struct rxrpc_transport *trans, struct rxrpc_service *newsrv)
++int rxrpc_add_service(struct rxrpc_transport *trans,
++                    struct rxrpc_service *newsrv)
+ {
+       struct rxrpc_service *srv;
+       struct list_head *_p;
+       int ret = -EEXIST;
+-      _enter("%p{%hu},%p{%hu}",trans,trans->port,newsrv,newsrv->service_id);
++      _enter("%p{%hu},%p{%hu}",
++             trans, trans->port, newsrv, newsrv->service_id);
+       /* verify that the service ID is not already present */
+       spin_lock(&trans->lock);
+-      list_for_each(_p,&trans->services) {
+-              srv = list_entry(_p,struct rxrpc_service,link);
+-              if (srv->service_id==newsrv->service_id)
++      list_for_each(_p, &trans->services) {
++              srv = list_entry(_p, struct rxrpc_service, link);
++              if (srv->service_id == newsrv->service_id)
+                       goto out;
+       }
+       /* okay - add the transport to the list */
+-      list_add_tail(&newsrv->link,&trans->services);
++      list_add_tail(&newsrv->link, &trans->services);
+       rxrpc_get_transport(trans);
+       ret = 0;
+  out:
+       spin_unlock(&trans->lock);
+-      _leave("= %d",ret);
++      _leave("= %d", ret);
+       return ret;
+-
+ } /* end rxrpc_add_service() */
+ /*****************************************************************************/
+@@ -235,7 +237,7 @@
+  */
+ void rxrpc_del_service(struct rxrpc_transport *trans, struct rxrpc_service *srv)
+ {
+-      _enter("%p{%hu},%p{%hu}",trans,trans->port,srv,srv->service_id);
++      _enter("%p{%hu},%p{%hu}", trans, trans->port, srv, srv->service_id);
+       spin_lock(&trans->lock);
+       list_del(&srv->link);
+@@ -244,7 +246,6 @@
+       rxrpc_put_transport(trans);
+       _leave("");
+-
+ } /* end rxrpc_del_service() */
+ /*****************************************************************************/
+@@ -255,7 +256,7 @@
+ {
+       struct rxrpc_transport *trans;
+-      _enter("%p{t=%p},%d",sk,sk->sk_user_data,count);
++      _enter("%p{t=%p},%d", sk, sk->sk_user_data, count);
+       /* queue the transport for attention by krxiod */
+       trans = (struct rxrpc_transport *) sk->sk_user_data;
+@@ -267,7 +268,6 @@
+               wake_up_interruptible(sk->sk_sleep);
+       _leave("");
+-
+ } /* end rxrpc_data_ready() */
+ /*****************************************************************************/
+@@ -279,7 +279,7 @@
+ {
+       struct rxrpc_transport *trans;
+-      _enter("%p{t=%p}",sk,sk->sk_user_data);
++      _enter("%p{t=%p}", sk, sk->sk_user_data);
+       /* queue the transport for attention by krxiod */
+       trans = (struct rxrpc_transport *) sk->sk_user_data;
+@@ -293,13 +293,12 @@
+               wake_up_interruptible(sk->sk_sleep);
+       _leave("");
+-
+ } /* end rxrpc_error_report() */
+ /*****************************************************************************/
+ /*
+- * split a message up, allocating message records and filling them in from the contents of a
+- * socket buffer
++ * split a message up, allocating message records and filling them in
++ * from the contents of a socket buffer
+  */
+ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
+                             struct sk_buff *pkt,
+@@ -310,18 +309,19 @@
+       _enter("");
+-      msg = kmalloc(sizeof(struct rxrpc_message),GFP_KERNEL);
++      msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
+       if (!msg) {
+               _leave(" = -ENOMEM");
+               return -ENOMEM;
+       }
+-      memset(msg,0,sizeof(*msg));
+-      atomic_set(&msg->usage,1);
++      memset(msg, 0, sizeof(*msg));
++      atomic_set(&msg->usage, 1);
+       list_add_tail(&msg->link,msgq);
+       /* dig out the Rx routing parameters */
+-      if (skb_copy_bits(pkt,sizeof(struct udphdr),&msg->hdr,sizeof(msg->hdr))<0) {
++      if (skb_copy_bits(pkt, sizeof(struct udphdr),
++                        &msg->hdr, sizeof(msg->hdr)) < 0) {
+               ret = -EBADMSG;
+               goto error;
+       }
+@@ -352,7 +352,9 @@
+       __RXACCT(atomic_inc(&rxrpc_message_count));
+       /* split off jumbo packets */
+-      while (msg->hdr.type==RXRPC_PACKET_TYPE_DATA && msg->hdr.flags & RXRPC_JUMBO_PACKET) {
++      while (msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
++             msg->hdr.flags & RXRPC_JUMBO_PACKET
++             ) {
+               struct rxrpc_jumbo_header jumbo;
+               struct rxrpc_message *jumbomsg = msg;
+@@ -360,23 +362,25 @@
+               /* quick sanity check */
+               ret = -EBADMSG;
+-              if (msg->dsize < RXRPC_JUMBO_DATALEN+sizeof(struct rxrpc_jumbo_header))
++              if (msg->dsize <
++                  RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header))
+                       goto error;
+               if (msg->hdr.flags & RXRPC_LAST_PACKET)
+                       goto error;
+               /* dig out the secondary header */
+-              if (skb_copy_bits(pkt,msg->offset+RXRPC_JUMBO_DATALEN,&jumbo,sizeof(jumbo))<0)
++              if (skb_copy_bits(pkt, msg->offset + RXRPC_JUMBO_DATALEN,
++                                &jumbo, sizeof(jumbo)) < 0)
+                       goto error;
+               /* allocate a new message record */
+               ret = -ENOMEM;
+-              msg = kmalloc(sizeof(struct rxrpc_message),GFP_KERNEL);
++              msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
+               if (!msg)
+                       goto error;
+-              memcpy(msg,jumbomsg,sizeof(*msg));
+-              list_add_tail(&msg->link,msgq);
++              memcpy(msg, jumbomsg, sizeof(*msg));
++              list_add_tail(&msg->link, msgq);
+               /* adjust the jumbo packet */
+               jumbomsg->dsize = RXRPC_JUMBO_DATALEN;
+@@ -388,12 +392,15 @@
+               msg->seq++;
+               msg->hdr.seq = htonl(msg->seq);
+               msg->hdr.serial = htonl(ntohl(msg->hdr.serial) + 1);
+-              msg->offset += RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header);
+-              msg->dsize -= RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header);
++              msg->offset += RXRPC_JUMBO_DATALEN +
++                      sizeof(struct rxrpc_jumbo_header);
++              msg->dsize -= RXRPC_JUMBO_DATALEN +
++                      sizeof(struct rxrpc_jumbo_header);
+               msg->hdr.flags = jumbo.flags;
+               msg->hdr._rsvd = jumbo._rsvd;
+-              _net("Rx Split jumbo packet from %s (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
++              _net("Rx Split jumbo packet from %s"
++                   " (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
+                    msg->hdr.flags & RXRPC_CLIENT_INITIATED ? "client" : "server",
+                    ntohl(msg->hdr.epoch),
+                    (ntohl(msg->hdr.cid) & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT,
+@@ -407,18 +414,18 @@
+               __RXACCT(atomic_inc(&rxrpc_message_count));
+       }
+-      _leave(" = 0 #%d",atomic_read(&rxrpc_message_count));
++      _leave(" = 0 #%d", atomic_read(&rxrpc_message_count));
+       return 0;
+  error:
+       while (!list_empty(msgq)) {
+-              msg = list_entry(msgq->next,struct rxrpc_message,link);
++              msg = list_entry(msgq->next, struct rxrpc_message, link);
+               list_del_init(&msg->link);
+               rxrpc_put_message(msg);
+       }
+-      _leave(" = %d",ret);
++      _leave(" = %d", ret);
+       return ret;
+ } /* end rxrpc_incoming_msg() */
+@@ -438,7 +445,7 @@
+       LIST_HEAD(msgq);
+-      _enter("%p{%d}",trans,trans->port);
++      _enter("%p{%d}", trans, trans->port);
+       for (;;) {
+               /* deal with outstanting errors first */
+@@ -446,22 +453,25 @@
+                       rxrpc_trans_receive_error_report(trans);
+               /* attempt to receive a packet */
+-              pkt = skb_recv_datagram(trans->socket->sk,0,1,&ret);
++              pkt = skb_recv_datagram(trans->socket->sk, 0, 1, &ret);
+               if (!pkt) {
+-                      if (ret==-EAGAIN) {
++                      if (ret == -EAGAIN) {
+                               _leave(" EAGAIN");
+                               return;
+                       }
+                       /* an icmp error may have occurred */
+                       rxrpc_krxiod_queue_transport(trans);
+-                      _leave(" error %d\n",ret);
++                      _leave(" error %d\n", ret);
+                       return;
+               }
+-              /* we'll probably need to checksum it (didn't call sock_recvmsg) */
++              /* we'll probably need to checksum it (didn't call
++               * sock_recvmsg) */
+               if (pkt->ip_summed != CHECKSUM_UNNECESSARY) {
+-                      if ((unsigned short)csum_fold(skb_checksum(pkt,0,pkt->len,pkt->csum))) {
++                      if ((unsigned short)
++                          csum_fold(skb_checksum(pkt, 0, pkt->len,
++                                                 pkt->csum))) {
+                               kfree_skb(pkt);
+                               rxrpc_krxiod_queue_transport(trans);
+                               _leave(" CSUM failed");
+@@ -472,34 +482,36 @@
+               addr = pkt->nh.iph->saddr;
+               port = pkt->h.uh->source;
+-              _net("Rx Received UDP packet from %08x:%04hu",ntohl(addr),ntohs(port));
++              _net("Rx Received UDP packet from %08x:%04hu",
++                   ntohl(addr), ntohs(port));
+               /* unmarshall the Rx parameters and split jumbo packets */
+-              ret = rxrpc_incoming_msg(trans,pkt,&msgq);
+-              if (ret<0) {
++              ret = rxrpc_incoming_msg(trans, pkt, &msgq);
++              if (ret < 0) {
+                       kfree_skb(pkt);
+                       rxrpc_krxiod_queue_transport(trans);
+                       _leave(" bad packet");
+                       return;
+               }
+-              if (list_empty(&msgq)) BUG();
++              BUG_ON(list_empty(&msgq));
+-              msg = list_entry(msgq.next,struct rxrpc_message,link);
++              msg = list_entry(msgq.next, struct rxrpc_message, link);
+-              /* locate the record for the peer from which it originated */
+-              ret = rxrpc_peer_lookup(trans,addr,&peer);
+-              if (ret<0) {
++              /* locate the record for the peer from which it
++               * originated */
++              ret = rxrpc_peer_lookup(trans, addr, &peer);
++              if (ret < 0) {
+                       kdebug("Rx No connections from that peer");
+-                      rxrpc_trans_immediate_abort(trans,msg,-EINVAL);
++                      rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
+                       goto finished_msg;
+               }
+               /* try and find a matching connection */
+-              ret = rxrpc_connection_lookup(peer,msg,&msg->conn);
+-              if (ret<0) {
++              ret = rxrpc_connection_lookup(peer, msg, &msg->conn);
++              if (ret < 0) {
+                       kdebug("Rx Unknown Connection");
+-                      rxrpc_trans_immediate_abort(trans,msg,-EINVAL);
++                      rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
+                       rxrpc_put_peer(peer);
+                       goto finished_msg;
+               }
+@@ -507,23 +519,23 @@
+               /* deal with the first packet of a new call */
+               if (msg->hdr.flags & RXRPC_CLIENT_INITIATED &&
+-                  msg->hdr.type==RXRPC_PACKET_TYPE_DATA &&
+-                  ntohl(msg->hdr.seq)==1
++                  msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
++                  ntohl(msg->hdr.seq) == 1
+                   ) {
+                       _debug("Rx New server call");
+-                      rxrpc_trans_receive_new_call(trans,&msgq);
++                      rxrpc_trans_receive_new_call(trans, &msgq);
+                       goto finished_msg;
+               }
+               /* deal with subsequent packet(s) of call */
+               _debug("Rx Call packet");
+               while (!list_empty(&msgq)) {
+-                      msg = list_entry(msgq.next,struct rxrpc_message,link);
++                      msg = list_entry(msgq.next, struct rxrpc_message, link);
+                       list_del_init(&msg->link);
+-                      ret = rxrpc_conn_receive_call_packet(msg->conn,NULL,msg);
+-                      if (ret<0) {
+-                              rxrpc_trans_immediate_abort(trans,msg,ret);
++                      ret = rxrpc_conn_receive_call_packet(msg->conn, NULL, msg);
++                      if (ret < 0) {
++                              rxrpc_trans_immediate_abort(trans, msg, ret);
+                               rxrpc_put_message(msg);
+                               goto finished_msg;
+                       }
+@@ -536,7 +548,7 @@
+               /* dispose of the packets */
+       finished_msg:
+               while (!list_empty(&msgq)) {
+-                      msg = list_entry(msgq.next,struct rxrpc_message,link);
++                      msg = list_entry(msgq.next, struct rxrpc_message, link);
+                       list_del_init(&msg->link);
+                       rxrpc_put_message(msg);
+@@ -561,7 +573,7 @@
+       _enter("");
+       /* only bother with the first packet */
+-      msg = list_entry(msgq->next,struct rxrpc_message,link);
++      msg = list_entry(msgq->next, struct rxrpc_message, link);
+       list_del_init(&msg->link);
+       rxrpc_krxsecd_queue_incoming_call(msg);
+       rxrpc_put_message(msg);
+@@ -584,13 +596,13 @@
+       struct msghdr msghdr;
+       struct iovec iov[2];
+       mm_segment_t oldfs;
++      uint32_t _error;
+       int len, ret;
+-      u32 _error;
+-      _enter("%p,%p,%d",trans,msg,error);
++      _enter("%p,%p,%d", trans, msg, error);
+       /* don't abort an abort packet */
+-      if (msg->hdr.type==RXRPC_PACKET_TYPE_ABORT) {
++      if (msg->hdr.type == RXRPC_PACKET_TYPE_ABORT) {
+               _leave(" = 0");
+               return 0;
+       }
+@@ -598,12 +610,13 @@
+       _error = htonl(-error);
+       /* set up the message to be transmitted */
+-      memcpy(&ahdr,&msg->hdr,sizeof(ahdr));
++      memcpy(&ahdr, &msg->hdr, sizeof(ahdr));
+       ahdr.epoch      = msg->hdr.epoch;
+       ahdr.serial     = htonl(1);
+       ahdr.seq        = 0;
+       ahdr.type       = RXRPC_PACKET_TYPE_ABORT;
+-      ahdr.flags      = RXRPC_LAST_PACKET | (~msg->hdr.flags & RXRPC_CLIENT_INITIATED);
++      ahdr.flags      = RXRPC_LAST_PACKET;
++      ahdr.flags      |= ~msg->hdr.flags & RXRPC_CLIENT_INITIATED;
+       iov[0].iov_len  = sizeof(ahdr);
+       iov[0].iov_base = &ahdr;
+@@ -634,17 +647,17 @@
+       /* send the message */
+       oldfs = get_fs();
+       set_fs(KERNEL_DS);
+-      ret = sock_sendmsg(trans->socket,&msghdr,len);
++      ret = sock_sendmsg(trans->socket, &msghdr, len);
+       set_fs(oldfs);
+-      _leave(" = %d",ret);
++      _leave(" = %d", ret);
+       return ret;
+ } /* end rxrpc_trans_immediate_abort() */
+ /*****************************************************************************/
+ /*
+- * receive an ICMP error report and percolate it to all connections heading to the affected
+- * host or port
++ * receive an ICMP error report and percolate it to all connections
++ * heading to the affected host or port
+  */
+ static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
+ {
+@@ -655,10 +668,10 @@
+       struct errormsg emsg;
+       struct msghdr msg;
+       mm_segment_t oldfs;
++      uint16_t port;
+       int local, err;
+-      u16 port;
+-      _enter("%p",trans);
++      _enter("%p", trans);
+       for (;;) {
+               trans->error_rcvd = 0;
+@@ -674,48 +687,63 @@
+               oldfs = get_fs();
+               set_fs(KERNEL_DS);
+-              err = sock_recvmsg(trans->socket,&msg,0,MSG_ERRQUEUE|MSG_DONTWAIT|MSG_TRUNC);
++              err = sock_recvmsg(trans->socket, &msg, 0,
++                                 MSG_ERRQUEUE | MSG_DONTWAIT | MSG_TRUNC);
+               set_fs(oldfs);
+-              if (err==-EAGAIN) {
++              if (err == -EAGAIN) {
+                       _leave("");
+                       return;
+               }
+-              if (err<0) {
+-                      printk("%s: unable to recv an error report: %d\n",__FUNCTION__,err);
++              if (err < 0) {
++                      printk("%s: unable to recv an error report: %d\n",
++                             __FUNCTION__, err);
+                       _leave("");
+                       return;
+               }
+-              msg.msg_controllen = (char*)msg.msg_control - (char*)&emsg;
++              msg.msg_controllen = (char *) msg.msg_control - (char *) &emsg;
+-              if (msg.msg_controllen<sizeof(emsg.cmsg) || msg.msg_namelen<sizeof(sin)) {
+-                      printk("%s: short control message (nlen=%u clen=%Zu fl=%x)\n",
+-                             __FUNCTION__,msg.msg_namelen,msg.msg_controllen,msg.msg_flags);
++              if (msg.msg_controllen < sizeof(emsg.cmsg) ||
++                  msg.msg_namelen < sizeof(sin)) {
++                      printk("%s: short control message"
++                             " (nlen=%u clen=%Zu fl=%x)\n",
++                             __FUNCTION__,
++                             msg.msg_namelen,
++                             msg.msg_controllen,
++                             msg.msg_flags);
+                       continue;
+               }
+-              _net("Rx Received control message { len=%Zu level=%u type=%u }",
+-                   emsg.cmsg.cmsg_len,emsg.cmsg.cmsg_level,emsg.cmsg.cmsg_type);
+-
+-              if (sin.sin_family!=AF_INET) {
+-                      printk("Rx Ignoring error report with non-INET address (fam=%u)",
++              _net("Rx Received control message"
++                   " { len=%Zu level=%u type=%u }",
++                   emsg.cmsg.cmsg_len,
++                   emsg.cmsg.cmsg_level,
++                   emsg.cmsg.cmsg_type);
++
++              if (sin.sin_family != AF_INET) {
++                      printk("Rx Ignoring error report with non-INET address"
++                             " (fam=%u)",
+                              sin.sin_family);
+                       continue;
+               }
+               _net("Rx Received message pertaining to host addr=%x port=%hu",
+-                   ntohl(sin.sin_addr.s_addr),ntohs(sin.sin_port));
++                   ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+-              if (emsg.cmsg.cmsg_level!=SOL_IP || emsg.cmsg.cmsg_type!=IP_RECVERR) {
+-                      printk("Rx Ignoring unknown error report { level=%u type=%u }",
+-                             emsg.cmsg.cmsg_level,emsg.cmsg.cmsg_type);
++              if (emsg.cmsg.cmsg_level != SOL_IP ||
++                  emsg.cmsg.cmsg_type != IP_RECVERR) {
++                      printk("Rx Ignoring unknown error report"
++                             " { level=%u type=%u }",
++                             emsg.cmsg.cmsg_level,
++                             emsg.cmsg.cmsg_type);
+                       continue;
+               }
+-              if (msg.msg_controllen<sizeof(emsg.cmsg)+sizeof(emsg.ee)) {
+-                      printk("%s: short error message (%Zu)\n",__FUNCTION__,msg.msg_controllen);
++              if (msg.msg_controllen < sizeof(emsg.cmsg) + sizeof(emsg.ee)) {
++                      printk("%s: short error message (%Zu)\n",
++                             __FUNCTION__, msg.msg_controllen);
+                       _leave("");
+                       return;
+               }
+@@ -767,14 +795,15 @@
+                       default:
+                               _proto("Rx Received ICMP error { type=%u code=%u }",
+-                                     emsg.ee.ee_type,emsg.ee.ee_code);
++                                     emsg.ee.ee_type, emsg.ee.ee_code);
+                               err = emsg.ee.ee_errno;
+                               break;
+                       }
+                       break;
+               case SO_EE_ORIGIN_LOCAL:
+-                      _proto("Rx Received local error { error=%d }",emsg.ee.ee_errno);
++                      _proto("Rx Received local error { error=%d }",
++                             emsg.ee.ee_errno);
+                       local = 1;
+                       err = emsg.ee.ee_errno;
+                       break;
+@@ -782,35 +811,41 @@
+               case SO_EE_ORIGIN_NONE:
+               case SO_EE_ORIGIN_ICMP6:
+               default:
+-                      _proto("Rx Received error report { orig=%u }",emsg.ee.ee_origin);
++                      _proto("Rx Received error report { orig=%u }",
++                             emsg.ee.ee_origin);
+                       local = 0;
+                       err = emsg.ee.ee_errno;
+                       break;
+               }
+-              /* find all the connections between this transport and the affected destination */
++              /* find all the connections between this transport and the
++               * affected destination */
+               INIT_LIST_HEAD(&connq);
+-              if (rxrpc_peer_lookup(trans,sin.sin_addr.s_addr,&peer)==0) {
++              if (rxrpc_peer_lookup(trans, sin.sin_addr.s_addr,
++                                    &peer) == 0) {
+                       read_lock(&peer->conn_lock);
+-                      list_for_each(_p,&peer->conn_active) {
+-                              conn = list_entry(_p,struct rxrpc_connection,link);
+-                              if (port && conn->addr.sin_port!=port)
++                      list_for_each(_p, &peer->conn_active) {
++                              conn = list_entry(_p, struct rxrpc_connection,
++                                                link);
++                              if (port && conn->addr.sin_port != port)
+                                       continue;
+                               if (!list_empty(&conn->err_link))
+                                       continue;
+                               rxrpc_get_connection(conn);
+-                              list_add_tail(&conn->err_link,&connq);
++                              list_add_tail(&conn->err_link, &connq);
+                       }
+                       read_unlock(&peer->conn_lock);
+                       /* service all those connections */
+                       while (!list_empty(&connq)) {
+-                              conn = list_entry(connq.next,struct rxrpc_connection,err_link);
++                              conn = list_entry(connq.next,
++                                                struct rxrpc_connection,
++                                                err_link);
+                               list_del(&conn->err_link);
+-                              rxrpc_conn_handle_error(conn,local,err);
++                              rxrpc_conn_handle_error(conn, local, err);
+                               rxrpc_put_connection(conn);
+                       }
+Index: linux-2.6.0-test5/net/sched/estimator.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/estimator.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/estimator.c    2003-09-27 11:38:42.267102808 +0800
+@@ -26,7 +26,6 @@
+ #include <linux/skbuff.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/init.h>
+-#include <linux/proc_fs.h>
+ #include <net/sock.h>
+ #include <net/pkt_sched.h>
+Index: linux-2.6.0-test5/net/sched/police.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/police.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/police.c       2003-09-27 11:38:42.270102352 +0800
+@@ -27,7 +27,6 @@
+ #include <linux/skbuff.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/init.h>
+-#include <linux/proc_fs.h>
+ #include <net/sock.h>
+ #include <net/pkt_sched.h>
+Index: linux-2.6.0-test5/net/sched/sch_api.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_api.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_api.c      2003-09-27 11:38:42.278101136 +0800
+@@ -32,6 +32,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/init.h>
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/kmod.h>
+ #include <net/sock.h>
+@@ -1059,27 +1060,27 @@
+ int psched_tick_per_us = 1;
+ #ifdef CONFIG_PROC_FS
+-static int psched_read_proc(char *buffer, char **start, off_t offset,
+-                           int length, int *eof, void *data)
++static int psched_show(struct seq_file *seq, void *v)
+ {
+-      int len;
+-
+-      len = sprintf(buffer, "%08x %08x %08x %08x\n",
++      seq_printf(seq, "%08x %08x %08x %08x\n",
+                     psched_tick_per_us, psched_us_per_tick,
+                     1000000, HZ);
+-      len -= offset;
+-
+-      if (len > length)
+-              len = length;
+-      if(len < 0)
+-              len = 0;
+-
+-      *start = buffer + offset;
+-      *eof = 1;
++      return 0;
++}
+-      return len;
++static int psched_open(struct inode *inode, struct file *file)
++{
++      return single_open(file, psched_show, PDE(inode)->data);
+ }
++
++static struct file_operations psched_fops = {
++      .owner = THIS_MODULE,
++      .open = psched_open,
++      .read  = seq_read,
++      .llseek = seq_lseek,
++      .release = single_release,
++};    
+ #endif
+ #if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
+@@ -1250,9 +1251,7 @@
+       tc_filter_init();
+ #endif
+-#ifdef CONFIG_PROC_FS
+-      create_proc_read_entry("net/psched", 0, 0, psched_read_proc, NULL);
+-#endif
++      proc_net_fops_create("psched", 0, &psched_fops);
+       return 0;
+ }
+Index: linux-2.6.0-test5/net/sched/sch_atm.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_atm.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_atm.c      2003-09-27 11:38:42.283100376 +0800
+@@ -216,6 +216,13 @@
+       tasklet_schedule(&p->task);
+ }
++static const u8 llc_oui_ip[] = {
++      0xaa,           /* DSAP: non-ISO */
++      0xaa,           /* SSAP: non-ISO */
++      0x03,           /* Ctrl: Unnumbered Information Command PDU */
++      0x00,           /* OUI: EtherType */
++      0x00, 0x00,
++      0x08, 0x00 };   /* Ethertype IP (0800) */
+ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
+     struct rtattr **tca, unsigned long *arg)
+@@ -322,11 +329,10 @@
+       flow->next = p->link.next;
+       p->link.next = flow;
+       flow->hdr_len = hdr_len;
+-      if (hdr) memcpy(flow->hdr,hdr,hdr_len);
+-      else {
+-              memcpy(flow->hdr,llc_oui,sizeof(llc_oui));
+-              ((u16 *) flow->hdr)[3] = htons(ETH_P_IP);
+-      }
++      if (hdr)
++              memcpy(flow->hdr,hdr,hdr_len);
++      else
++              memcpy(flow->hdr,llc_oui_ip,sizeof(llc_oui_ip));
+       *arg = (unsigned long) flow;
+       return 0;
+ err_out:
+Index: linux-2.6.0-test5/net/sched/sch_generic.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_generic.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_generic.c  2003-09-27 11:38:42.287099768 +0800
+@@ -7,7 +7,7 @@
+  *            2 of the License, or (at your option) any later version.
+  *
+  * Authors:   Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+- *              Jamal Hadi Salim, <hadi@nortelnetworks.com> 990601
++ *              Jamal Hadi Salim, <hadi@cyberus.ca> 990601
+  *              - Ingress support
+  */
+@@ -278,6 +278,8 @@
+       if (list->qlen <= qdisc->dev->tx_queue_len) {
+               __skb_queue_tail(list, skb);
+               qdisc->q.qlen++;
++              qdisc->stats.bytes += skb->len;
++              qdisc->stats.packets++;
+               return 0;
+       }
+       qdisc->stats.drops++;
+@@ -326,6 +328,21 @@
+       qdisc->q.qlen = 0;
+ }
++static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
++{
++      unsigned char    *b = skb->tail;
++      struct tc_prio_qopt opt;
++
++      opt.bands = 3; 
++      memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1);
++      RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
++      return skb->len;
++
++rtattr_failure:
++      skb_trim(skb, b - skb->data);
++      return -1;
++}
++
+ static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt)
+ {
+       int i;
+@@ -349,6 +366,7 @@
+       .requeue        =       pfifo_fast_requeue,
+       .init           =       pfifo_fast_init,
+       .reset          =       pfifo_fast_reset,
++      .dump           =       pfifo_fast_dump,
+       .owner          =       THIS_MODULE,
+ };
+@@ -438,6 +456,12 @@
+                               printk(KERN_INFO "%s: activation failed\n", dev->name);
+                               return;
+                       }
++
++                      write_lock(&qdisc_tree_lock);
++                      qdisc->next = dev->qdisc_list;
++                      dev->qdisc_list = qdisc;
++                      write_unlock(&qdisc_tree_lock);
++
+               } else {
+                       qdisc =  &noqueue_qdisc;
+               }
+Index: linux-2.6.0-test5/net/sched/sch_htb.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sched/sch_htb.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sched/sch_htb.c      2003-09-27 11:38:42.301097640 +0800
+@@ -32,7 +32,6 @@
+ #include <asm/bitops.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-#include <linux/version.h>
+ #include <linux/sched.h>
+ #include <linux/string.h>
+ #include <linux/mm.h>
+Index: linux-2.6.0-test5/net/sunrpc/cache.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/sunrpc/cache.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/sunrpc/cache.c       2003-09-27 11:38:42.308096576 +0800
+@@ -1035,7 +1035,7 @@
+       read_lock(&cd->hash_lock);
+       if (!n--)
+-              return (void *)1;
++              return SEQ_START_TOKEN;
+       hash = n >> 32;
+       entry = n & ((1LL<<32) - 1);
+@@ -1060,7 +1060,7 @@
+       int hash = (*pos >> 32);
+       struct cache_detail *cd = ((struct handle*)m->private)->cd;
+-      if (p == (void *)1)
++      if (p == SEQ_START_TOKEN)
+               hash = 0;
+       else if (ch->next == NULL) {
+               hash++;
+@@ -1092,7 +1092,7 @@
+       struct cache_head *cp = p;
+       struct cache_detail *cd = ((struct handle*)m->private)->cd;
+-      if (p == (void *)1)
++      if (p == SEQ_START_TOKEN)
+               return cd->cache_show(m, cd, NULL);
+       ifdebug(CACHE)
+Index: linux-2.6.0-test5/net/wanrouter/af_wanpipe.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/wanrouter/af_wanpipe.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/wanrouter/af_wanpipe.c       2003-09-27 11:38:42.326093840 +0800
+@@ -32,7 +32,6 @@
+ *
+ ******************************************************************************/
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/sched.h>
+Index: linux-2.6.0-test5/net/wanrouter/wanmain.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/wanrouter/wanmain.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/wanrouter/wanmain.c  2003-09-27 11:38:42.332092928 +0800
+@@ -42,7 +42,6 @@
+ * Jun 02, 1999  Gideon Hack   Updates for Linux 2.0.X and 2.2.X kernels.
+ *****************************************************************************/
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/stddef.h>     /* offsetof(), etc. */
+ #include <linux/errno.h>      /* return codes */
+Index: linux-2.6.0-test5/net/wanrouter/wanproc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/wanrouter/wanproc.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/wanrouter/wanproc.c  2003-09-27 11:38:42.336092320 +0800
+@@ -86,7 +86,7 @@
+       lock_kernel();
+       if (!l--)
+-              return (void *)1;
++              return SEQ_START_TOKEN;
+       for (wandev = wanrouter_router_devlist; l-- && wandev;
+            wandev = wandev->next)
+               ;
+@@ -97,7 +97,7 @@
+ {
+       struct wan_device *wandev = v;
+       (*pos)++;
+-      return (v == (void *)1) ? wanrouter_router_devlist : wandev->next;
++      return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next;
+ }
+ static void r_stop(struct seq_file *m, void *v)
+@@ -108,7 +108,7 @@
+ static int config_show(struct seq_file *m, void *v)
+ {
+       struct wan_device *p = v;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(m, "Device name    | port |IRQ|DMA|  mem.addr  |"
+                           "mem.size|option1|option2|option3|option4\n");
+               return 0;
+@@ -124,7 +124,7 @@
+ static int status_show(struct seq_file *m, void *v)
+ {
+       struct wan_device *p = v;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(m, "Device name    |protocol|station|interface|"
+                           "clocking|baud rate| MTU |ndev|link state\n");
+               return 0;
+Index: linux-2.6.0-test5/net/x25/x25_proc.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/x25/x25_proc.c  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/x25/x25_proc.c       2003-09-27 11:38:42.338092016 +0800
+@@ -44,7 +44,7 @@
+       loff_t l = *pos;
+       read_lock_bh(&x25_route_list_lock);
+-      return l ? x25_get_route_idx(--l) : (void *)1;
++      return l ? x25_get_route_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -52,7 +52,7 @@
+       struct x25_route *rt;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               rt = NULL;
+               if (!list_empty(&x25_route_list))
+                       rt = list_entry(x25_route_list.next,
+@@ -77,7 +77,7 @@
+ {
+       struct x25_route *rt;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_puts(seq, "Address          Digits  Device\n");
+               goto out;
+       }
+@@ -108,7 +108,7 @@
+       loff_t l = *pos;
+       read_lock_bh(&x25_list_lock);
+-      return l ? x25_get_socket_idx(--l) : (void *)1;
++      return l ? x25_get_socket_idx(--l) : SEQ_START_TOKEN;
+ }
+ static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -116,7 +116,7 @@
+       struct sock *s;
+       ++*pos;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               s = sk_head(&x25_list);
+               goto out;
+       }
+@@ -137,7 +137,7 @@
+       struct net_device *dev;
+       const char *devname;
+-      if (v == (void *)1) {
++      if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, "dest_addr  src_addr   dev   lci st vs vr "
+                               "va   t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
+               goto out;
+Index: linux-2.6.0-test5/net/xfrm/xfrm_user.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/xfrm/xfrm_user.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/net/xfrm/xfrm_user.c     2003-09-27 11:38:42.346090800 +0800
+@@ -433,9 +433,9 @@
+       case IPPROTO_COMP:
+               /* IPCOMP spi is 16-bits. */
+-              if (p->min >= 0x10000 ||
+-                  p->max >= 0x10000)
++              if (p->max >= 0x10000)
+                       return -EINVAL;
++              break;
+       default:
+               return -EINVAL;
+@@ -470,7 +470,7 @@
+       spin_lock_bh(&x->lock);
+       if (x->km.state != XFRM_STATE_DEAD) {
+-              xfrm_alloc_spi(x, p->min, p->max);
++              xfrm_alloc_spi(x, htonl(p->min), htonl(p->max));
+               if (x->id.spi)
+                       resp_skb = xfrm_state_netlink(skb, x, nlh->nlmsg_seq);
+       }
+Index: linux-2.6.0-test5/README
+===================================================================
+--- linux-2.6.0-test5.orig/README      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/README   2003-09-27 11:38:42.350090192 +0800
+@@ -108,11 +108,26 @@
+    you can just update packages when obvious problems arise during
+    build or operation.
+-CONFIGURING the kernel:
++BUILD directory for the kernel:
++
++   When compiling the kernel all output files will per default be
++   stored together with the kernel source code.
++   Using the option "make O=output/dir" allow you to specify an alternate
++   place for the output files (including .config).
++   Example:
++     kernel source code:      /usr/src/linux-2.6.N
++     build directory:         /home/name/build/kernel
++
++   To configure and build the kernel use:
++   cd /usr/src/linux-2.6.N
++   make O=/home/name/build/kernel menuconfig
++   make O=/home/name/build/kernel
++   sudo make O=/home/name/build/kernel install_modules install
+- - Do a "make config" to configure the basic kernel.  "make config" needs
+-   bash to work: it will search for bash in $BASH, /bin/bash and /bin/sh
+-   (in that order), so one of those must be correct for it to work. 
++   Please note: If the 'O=output/dir' option is used then it must be
++   used for all invocations of make.
++
++CONFIGURING the kernel:
+    Do not skip this step even if you are only upgrading one minor
+    version.  New configuration options are added in each release, and
+Index: linux-2.6.0-test5/scripts/bin2c.c
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/bin2c.c     2003-09-27 11:38:18.495716608 +0800
++++ linux-2.6.0-test5/scripts/bin2c.c  2003-09-27 11:38:42.351090040 +0800
+@@ -0,0 +1,27 @@
++#include <stdio.h>
++
++int main(int argc, char *argv[])
++{
++      int ch, total=0;
++
++      if (argc > 1)
++              printf("const char %s[] %s=\n",
++                      argv[1], argc > 2 ? argv[2] : "");
++
++      do {
++              printf("\t\"");
++              while ((ch = getchar()) != EOF)
++              {
++                      total++;
++                      printf("\\x%02x",ch);
++                      if (total % 16 == 0)
++                              break;
++              }
++              printf("\"\n");
++      } while (ch != EOF);
++
++      if (argc > 1)
++              printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total);
++
++      return 0;
++}
+Index: linux-2.6.0-test5/scripts/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile 2003-09-27 11:38:42.352089888 +0800
+@@ -9,7 +9,7 @@
+ # conmakehash:         Create arrays for initializing the kernel console tables
+ host-progs    := fixdep split-include conmakehash docproc kallsyms modpost \
+-                 mk_elfconfig pnmtologo
++                 mk_elfconfig pnmtologo bin2c
+ always                := $(host-progs) empty.o
+ modpost-objs  := modpost.o file2alias.o
+Index: linux-2.6.0-test5/scripts/Makefile.build
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.build      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.build   2003-09-27 11:38:42.355089432 +0800
+@@ -14,6 +14,16 @@
+ include scripts/Makefile.lib
++ifneq ($(KBUILD_SRC),)
++# Create output directory if not already present
++_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
++
++# Create directories for object files if directory does not exist
++# Needed when obj-y := dir/file.o syntax is used
++_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
++endif
++
++
+ ifdef EXTRA_TARGETS
+ $(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.5. Please fix!)
+ endif
+Index: linux-2.6.0-test5/scripts/Makefile.clean
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.clean      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.clean   2003-09-27 11:38:42.357089128 +0800
+@@ -63,4 +63,4 @@
+ # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
+ # Usage:
+ # $(Q)$(MAKE) $(clean)=dir
+-clean := -f scripts/Makefile.clean obj
++clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+Index: linux-2.6.0-test5/scripts/Makefile.lib
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.lib        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.lib     2003-09-27 11:38:42.361088520 +0800
+@@ -58,6 +58,11 @@
+ # in the local directory
+ subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
++# $(obj-dirs) is a list of directories that contain object files
++obj-dirs := $(dir $(multi-objs) $(subdir-obj-y))
++obj-dirs += $(foreach f,$(host-progs), $(if $(dir $(f)),$(dir $(f))))
++obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs))))
++
+ # Replace multi-part objects by their individual parts, look at local dir only
+ real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y)
+ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
+@@ -107,6 +112,7 @@
+ multi-objs-y  := $(addprefix $(obj)/,$(multi-objs-y))
+ multi-objs-m  := $(addprefix $(obj)/,$(multi-objs-m))
+ subdir-ym     := $(addprefix $(obj)/,$(subdir-ym))
++obj-dirs      := $(addprefix $(obj)/,$(obj-dirs))
+ host-progs      := $(addprefix $(obj)/,$(host-progs))
+ host-csingle  := $(addprefix $(obj)/,$(host-csingle))
+ host-cmulti   := $(addprefix $(obj)/,$(host-cmulti))
+@@ -129,15 +135,46 @@
+ #       where foo and bar are the name of the modules.
+ basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
+ modname_flags  = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
+-c_flags        = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
+-               $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
+-               $(basename_flags) $(modname_flags)
+-a_flags        = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS)\
+-               $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+-hostc_flags    = -Wp,-MD,$(depfile) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS)\
+-               $(HOSTCFLAGS_$(*F).o)
+-hostcxx_flags  = -Wp,-MD,$(depfile) $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS)\
+-               $(HOSTCXXFLAGS_$(*F).o)
++
++
++_c_flags       = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
++_a_flags       = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
++_hostc_flags   = $(HOSTCFLAGS)   $(HOST_EXTRACFLAGS)   $(HOSTCFLAGS_$(*F).o)
++_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o)
++
++
++# If building the kernel in a separate objtree expand all occurrences
++# of -Idir to -Idir -I$(srctree)/dir.
++# hereby allowing gcc to locate files in both trees. Local tree first.
++
++ifeq ($(KBUILD_SRC),)
++__c_flags     = $(_c_flags)
++__a_flags     = $(_a_flags)
++__hostc_flags = $(_hostc_flags)
++__hostcxx_flags       = $(_hostcxx_flags)
++else
++flags = $(foreach o,$($(1)),\
++      $(if $(filter -I%,$(o)),$(patsubst -I%,-I$(srctree)/%,$(o)),$(o)))
++
++# -I$(obj) locate generated .h files
++# -I$(srctree)/$(src) locate .h files in srctree, from generated .c files
++# FIXME: Replace both with specific EXTRA_CFLAGS statements
++__c_flags     = -I$(obj) -I$(srctree)/$(src) $(call flags,_c_flags)
++__a_flags     =                              $(call flags,_a_flags)
++__hostc_flags = -I$(obj)                     $(call flags,_hostc_flags)
++__hostcxx_flags       =                              $(call flags,_hostcxx_flags)
++endif
++
++c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
++               $(__c_flags) $(modkern_cflags) \
++               $(basename_flags) $(modname_flags)
++
++a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
++               $(__a_flags) $(modkern_aflags)
++
++hostc_flags    = -Wp,-MD,$(depfile) $(__hostc_flags)
++hostcxx_flags  = -Wp,-MD,$(depfile) $(__hostcxx_flags)
++
+ ld_flags       = $(LDFLAGS) $(EXTRA_LDFLAGS)
+ # Finds the multi-part object the current object will be linked into
+@@ -230,9 +267,9 @@
+ #     $(call descend,<dir>,<target>)
+ #     Recursively call a sub-make in <dir> with target <target> 
+ # Usage is deprecated, because make do not see this as an invocation of make.
+-descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
++descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
+ # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
+ # Usage:
+ # $(Q)$(MAKE) $(build)=dir
+-build := -f scripts/Makefile.build obj
++build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
+Index: linux-2.6.0-test5/scripts/Makefile.modpost
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/Makefile.modpost    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/Makefile.modpost 2003-09-27 11:38:42.362088368 +0800
+@@ -35,7 +35,7 @@
+ # Compile version info for unresolved symbols
+ quiet_cmd_cc_o_c = CC      $@
+-      cmd_cc_o_c = $(CC) -Wp,-MD,$(depfile) $(CFLAGS) $(CFLAGS_MODULE)        \
++      cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE)  \
+                  -c -o $@ $<
+ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
+Index: linux-2.6.0-test5/scripts/mkcompile_h
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/mkcompile_h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/mkcompile_h      2003-09-27 11:38:42.363088216 +0800
+@@ -27,7 +27,7 @@
+ UTS_VERSION="#$VERSION"
+ if [ -n "$SMP" ] ; then UTS_VERSION="$UTS_VERSION SMP"; fi
+-UTS_VERSION="$UTS_VERSION `LANG=C date`"
++UTS_VERSION="$UTS_VERSION `LC_ALL=C LANG=C date`"
+ # Truncate to maximum length
+@@ -42,7 +42,7 @@
+   echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"
+-  echo \#define LINUX_COMPILE_TIME \"`LANG=C date +%T`\"
++  echo \#define LINUX_COMPILE_TIME \"`LC_ALL=C LANG=C date +%T`\"
+   echo \#define LINUX_COMPILE_BY \"`whoami`\"
+   echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
+Index: linux-2.6.0-test5/scripts/mkconfigs
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/mkconfigs   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/mkconfigs        2003-09-27 11:38:42.365087912 +0800
+@@ -25,12 +25,6 @@
+ #     - Retain lines that begin with "# CONFIG_"
+ #     - lines that use double-quotes must \\-escape-quote them
+-
+-kernel_version()
+-{
+-      KERNVER="`grep VERSION $1 | head -1 | cut -f3 -d' '`.`grep PATCHLEVEL $1 | head -1 | cut -f3 -d' '`.`grep SUBLEVEL $1 | head -1 | cut -f3 -d' '``grep EXTRAVERSION $1 | head -1 | cut -f3 -d' '`"
+-}
+-
+ if [ $# -lt 2 ]
+ then
+       echo "Usage: `basename $0` <configuration_file> <Makefile>"
+@@ -66,15 +60,7 @@
+  *
+  */"
+-echo "static char *ikconfig_built_with ="
+-echo "    \"`uname -s` `uname -r` `uname -v` `uname -m`\";"
+-echo
+-kernel_version $makefile
+-echo "#ifdef CONFIG_IKCONFIG_PROC"
+-echo "static char *ikconfig_config = "
+-echo "#else"
+-echo "static char *ikconfig_config __initdata __attribute__((unused)) = "
+-echo "#endif"
++echo "static char const ikconfig_config[] __attribute__((unused)) = "
+ echo "\"CONFIG_BEGIN=n\\n\\"
+ echo "`cat $config | sed 's/\"/\\\\\"/g' | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `"
+ echo "CONFIG_END=n\\n\";"
+Index: linux-2.6.0-test5/scripts/mkspec
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/mkspec      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/mkspec   2003-09-27 11:38:42.366087760 +0800
+@@ -27,7 +27,7 @@
+ echo "Version: "$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION | sed -e "s/-//g"
+ # we need to determine the NEXT version number so that uname and
+ # rpm -q will agree
+-echo "Release: `. scripts/mkversion`"
++echo "Release: `. $srctree/scripts/mkversion`"
+ echo "License: GPL"
+ echo "Group: System Environment/Kernel"
+ echo "Vendor: The Linux Community"
+@@ -45,7 +45,7 @@
+ echo "%setup -q"
+ echo ""
+ echo "%build"
+-echo "make clean oldconfig all"
++echo "make clean all"
+ echo ""
+ echo "%install"
+ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules'
+Index: linux-2.6.0-test5/scripts/modpost.c
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/modpost.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/scripts/modpost.c        2003-09-27 11:38:42.370087152 +0800
+@@ -193,7 +193,7 @@
+       *size = st.st_size;
+       map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+-      if (mmap == MAP_FAILED) {
++      if (map == MAP_FAILED) {
+               perror(filename);
+               abort();
+       }
+Index: linux-2.6.0-test5/security/capability.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/capability.c       2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/capability.c    2003-09-27 11:38:42.374086544 +0800
+@@ -23,334 +23,6 @@
+ #include <linux/netlink.h>
+ #include <linux/ptrace.h>
+-int cap_capable (struct task_struct *tsk, int cap)
+-{
+-      /* Derived from include/linux/sched.h:capable. */
+-      if (cap_raised (tsk->cap_effective, cap))
+-              return 0;
+-      else
+-              return -EPERM;
+-}
+-
+-int cap_ptrace (struct task_struct *parent, struct task_struct *child)
+-{
+-      /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
+-      if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
+-          !capable (CAP_SYS_PTRACE))
+-              return -EPERM;
+-      else
+-              return 0;
+-}
+-
+-int cap_capget (struct task_struct *target, kernel_cap_t *effective,
+-              kernel_cap_t *inheritable, kernel_cap_t *permitted)
+-{
+-      /* Derived from kernel/capability.c:sys_capget. */
+-      *effective = cap_t (target->cap_effective);
+-      *inheritable = cap_t (target->cap_inheritable);
+-      *permitted = cap_t (target->cap_permitted);
+-      return 0;
+-}
+-
+-int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
+-                    kernel_cap_t *inheritable, kernel_cap_t *permitted)
+-{
+-      /* Derived from kernel/capability.c:sys_capset. */
+-      /* verify restrictions on target's new Inheritable set */
+-      if (!cap_issubset (*inheritable,
+-                         cap_combine (target->cap_inheritable,
+-                                      current->cap_permitted))) {
+-              return -EPERM;
+-      }
+-
+-      /* verify restrictions on target's new Permitted set */
+-      if (!cap_issubset (*permitted,
+-                         cap_combine (target->cap_permitted,
+-                                      current->cap_permitted))) {
+-              return -EPERM;
+-      }
+-
+-      /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
+-      if (!cap_issubset (*effective, *permitted)) {
+-              return -EPERM;
+-      }
+-
+-      return 0;
+-}
+-
+-void cap_capset_set (struct task_struct *target, kernel_cap_t *effective,
+-                   kernel_cap_t *inheritable, kernel_cap_t *permitted)
+-{
+-      target->cap_effective = *effective;
+-      target->cap_inheritable = *inheritable;
+-      target->cap_permitted = *permitted;
+-}
+-
+-int cap_bprm_set_security (struct linux_binprm *bprm)
+-{
+-      /* Copied from fs/exec.c:prepare_binprm. */
+-
+-      /* We don't have VFS support for capabilities yet */
+-      cap_clear (bprm->cap_inheritable);
+-      cap_clear (bprm->cap_permitted);
+-      cap_clear (bprm->cap_effective);
+-
+-      /*  To support inheritance of root-permissions and suid-root
+-       *  executables under compatibility mode, we raise all three
+-       *  capability sets for the file.
+-       *
+-       *  If only the real uid is 0, we only raise the inheritable
+-       *  and permitted sets of the executable file.
+-       */
+-
+-      if (!issecure (SECURE_NOROOT)) {
+-              if (bprm->e_uid == 0 || current->uid == 0) {
+-                      cap_set_full (bprm->cap_inheritable);
+-                      cap_set_full (bprm->cap_permitted);
+-              }
+-              if (bprm->e_uid == 0)
+-                      cap_set_full (bprm->cap_effective);
+-      }
+-      return 0;
+-}
+-
+-/* Copied from fs/exec.c */
+-static inline int must_not_trace_exec (struct task_struct *p)
+-{
+-      return (p->ptrace & PT_PTRACED) && !(p->ptrace & PT_PTRACE_CAP);
+-}
+-
+-void cap_bprm_compute_creds (struct linux_binprm *bprm)
+-{
+-      /* Derived from fs/exec.c:compute_creds. */
+-      kernel_cap_t new_permitted, working;
+-
+-      new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
+-      working = cap_intersect (bprm->cap_inheritable,
+-                               current->cap_inheritable);
+-      new_permitted = cap_combine (new_permitted, working);
+-
+-      task_lock(current);
+-      if (!cap_issubset (new_permitted, current->cap_permitted)) {
+-              current->mm->dumpable = 0;
+-
+-              if (must_not_trace_exec (current)
+-                  || atomic_read (&current->fs->count) > 1
+-                  || atomic_read (&current->files->count) > 1
+-                  || atomic_read (&current->sighand->count) > 1) {
+-                      if (!capable (CAP_SETPCAP)) {
+-                              new_permitted = cap_intersect (new_permitted,
+-                                                             current->
+-                                                             cap_permitted);
+-                      }
+-              }
+-      }
+-
+-      /* For init, we want to retain the capabilities set
+-       * in the init_task struct. Thus we skip the usual
+-       * capability rules */
+-      if (current->pid != 1) {
+-              current->cap_permitted = new_permitted;
+-              current->cap_effective =
+-                  cap_intersect (new_permitted, bprm->cap_effective);
+-      }
+-
+-      /* AUD: Audit candidate if current->cap_effective is set */
+-      task_unlock(current);
+-
+-      current->keep_capabilities = 0;
+-}
+-
+-int cap_bprm_secureexec (struct linux_binprm *bprm)
+-{
+-      /* If/when this module is enhanced to incorporate capability
+-         bits on files, the test below should be extended to also perform a 
+-         test between the old and new capability sets.  For now,
+-         it simply preserves the legacy decision algorithm used by
+-         the old userland. */
+-      return (current->euid != current->uid ||
+-              current->egid != current->gid);
+-}
+-
+-/* moved from kernel/sys.c. */
+-/* 
+- * cap_emulate_setxuid() fixes the effective / permitted capabilities of
+- * a process after a call to setuid, setreuid, or setresuid.
+- *
+- *  1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
+- *  {r,e,s}uid != 0, the permitted and effective capabilities are
+- *  cleared.
+- *
+- *  2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
+- *  capabilities of the process are cleared.
+- *
+- *  3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
+- *  capabilities are set to the permitted capabilities.
+- *
+- *  fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should 
+- *  never happen.
+- *
+- *  -astor 
+- *
+- * cevans - New behaviour, Oct '99
+- * A process may, via prctl(), elect to keep its capabilities when it
+- * calls setuid() and switches away from uid==0. Both permitted and
+- * effective sets will be retained.
+- * Without this change, it was impossible for a daemon to drop only some
+- * of its privilege. The call to setuid(!=0) would drop all privileges!
+- * Keeping uid 0 is not an option because uid 0 owns too many vital
+- * files..
+- * Thanks to Olaf Kirch and Peter Benie for spotting this.
+- */
+-static inline void cap_emulate_setxuid (int old_ruid, int old_euid,
+-                                      int old_suid)
+-{
+-      if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
+-          (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
+-          !current->keep_capabilities) {
+-              cap_clear (current->cap_permitted);
+-              cap_clear (current->cap_effective);
+-      }
+-      if (old_euid == 0 && current->euid != 0) {
+-              cap_clear (current->cap_effective);
+-      }
+-      if (old_euid != 0 && current->euid == 0) {
+-              current->cap_effective = current->cap_permitted;
+-      }
+-}
+-
+-int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
+-                        int flags)
+-{
+-      switch (flags) {
+-      case LSM_SETID_RE:
+-      case LSM_SETID_ID:
+-      case LSM_SETID_RES:
+-              /* Copied from kernel/sys.c:setreuid/setuid/setresuid. */
+-              if (!issecure (SECURE_NO_SETUID_FIXUP)) {
+-                      cap_emulate_setxuid (old_ruid, old_euid, old_suid);
+-              }
+-              break;
+-      case LSM_SETID_FS:
+-              {
+-                      uid_t old_fsuid = old_ruid;
+-
+-                      /* Copied from kernel/sys.c:setfsuid. */
+-
+-                      /*
+-                       * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
+-                       *          if not, we might be a bit too harsh here.
+-                       */
+-
+-                      if (!issecure (SECURE_NO_SETUID_FIXUP)) {
+-                              if (old_fsuid == 0 && current->fsuid != 0) {
+-                                      cap_t (current->cap_effective) &=
+-                                          ~CAP_FS_MASK;
+-                              }
+-                              if (old_fsuid != 0 && current->fsuid == 0) {
+-                                      cap_t (current->cap_effective) |=
+-                                          (cap_t (current->cap_permitted) &
+-                                           CAP_FS_MASK);
+-                              }
+-                      }
+-                      break;
+-              }
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-void cap_task_reparent_to_init (struct task_struct *p)
+-{
+-      p->cap_effective = CAP_INIT_EFF_SET;
+-      p->cap_inheritable = CAP_INIT_INH_SET;
+-      p->cap_permitted = CAP_FULL_SET;
+-      p->keep_capabilities = 0;
+-      return;
+-}
+-
+-int cap_syslog (int type)
+-{
+-      if ((type != 3) && !capable(CAP_SYS_ADMIN))
+-              return -EPERM;
+-      return 0;
+-}
+-
+-/*
+- * 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.
+- */
+-int cap_vm_enough_memory(long pages)
+-{
+-      unsigned long free, allowed;
+-
+-      vm_acct_memory(pages);
+-
+-      /* We estimate memory ourselves (common case) */
+-      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 root
+-               */
+-              if (!capable(CAP_SYS_ADMIN))
+-                      free -= free / 32;
+-
+-              if (free > pages)
+-                      return 0;
+-
+-              vm_unacct_memory(pages);
+-              return -ENOMEM;
+-      }
+-
+-      /* Kernel assumes allocation */
+-      if (sysctl_overcommit_memory == 1)
+-              return 0;
+-
+-      /* sysctl_overcommit_memory must be 2 which means strict_overcommit*/
+-      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;
+-}
+-
+-EXPORT_SYMBOL(cap_capable);
+-EXPORT_SYMBOL(cap_ptrace);
+-EXPORT_SYMBOL(cap_capget);
+-EXPORT_SYMBOL(cap_capset_check);
+-EXPORT_SYMBOL(cap_capset_set);
+-EXPORT_SYMBOL(cap_bprm_set_security);
+-EXPORT_SYMBOL(cap_bprm_compute_creds);
+-EXPORT_SYMBOL(cap_bprm_secureexec);
+-EXPORT_SYMBOL(cap_task_post_setuid);
+-EXPORT_SYMBOL(cap_task_reparent_to_init);
+-EXPORT_SYMBOL(cap_syslog);
+-EXPORT_SYMBOL(cap_vm_enough_memory);
+-
+ #ifdef CONFIG_SECURITY
+Index: linux-2.6.0-test5/security/commoncap.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/commoncap.c        2003-09-27 11:38:18.495716608 +0800
++++ linux-2.6.0-test5/security/commoncap.c     2003-09-27 11:38:42.375086392 +0800
+@@ -0,0 +1,353 @@
++/* Common capabilities, needed by capability.o and root_plug.o 
++ *
++ *    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/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/security.h>
++#include <linux/file.h>
++#include <linux/mm.h>
++#include <linux/mman.h>
++#include <linux/pagemap.h>
++#include <linux/swap.h>
++#include <linux/smp_lock.h>
++#include <linux/skbuff.h>
++#include <linux/netlink.h>
++#include <linux/ptrace.h>
++
++int cap_capable (struct task_struct *tsk, int cap)
++{
++      /* Derived from include/linux/sched.h:capable. */
++      if (cap_raised (tsk->cap_effective, cap))
++              return 0;
++      else
++              return -EPERM;
++}
++
++int cap_ptrace (struct task_struct *parent, struct task_struct *child)
++{
++      /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
++      if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
++          !capable (CAP_SYS_PTRACE))
++              return -EPERM;
++      else
++              return 0;
++}
++
++int cap_capget (struct task_struct *target, kernel_cap_t *effective,
++              kernel_cap_t *inheritable, kernel_cap_t *permitted)
++{
++      /* Derived from kernel/capability.c:sys_capget. */
++      *effective = cap_t (target->cap_effective);
++      *inheritable = cap_t (target->cap_inheritable);
++      *permitted = cap_t (target->cap_permitted);
++      return 0;
++}
++
++int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
++                    kernel_cap_t *inheritable, kernel_cap_t *permitted)
++{
++      /* Derived from kernel/capability.c:sys_capset. */
++      /* verify restrictions on target's new Inheritable set */
++      if (!cap_issubset (*inheritable,
++                         cap_combine (target->cap_inheritable,
++                                      current->cap_permitted))) {
++              return -EPERM;
++      }
++
++      /* verify restrictions on target's new Permitted set */
++      if (!cap_issubset (*permitted,
++                         cap_combine (target->cap_permitted,
++                                      current->cap_permitted))) {
++              return -EPERM;
++      }
++
++      /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
++      if (!cap_issubset (*effective, *permitted)) {
++              return -EPERM;
++      }
++
++      return 0;
++}
++
++void cap_capset_set (struct task_struct *target, kernel_cap_t *effective,
++                   kernel_cap_t *inheritable, kernel_cap_t *permitted)
++{
++      target->cap_effective = *effective;
++      target->cap_inheritable = *inheritable;
++      target->cap_permitted = *permitted;
++}
++
++int cap_bprm_set_security (struct linux_binprm *bprm)
++{
++      /* Copied from fs/exec.c:prepare_binprm. */
++
++      /* We don't have VFS support for capabilities yet */
++      cap_clear (bprm->cap_inheritable);
++      cap_clear (bprm->cap_permitted);
++      cap_clear (bprm->cap_effective);
++
++      /*  To support inheritance of root-permissions and suid-root
++       *  executables under compatibility mode, we raise all three
++       *  capability sets for the file.
++       *
++       *  If only the real uid is 0, we only raise the inheritable
++       *  and permitted sets of the executable file.
++       */
++
++      if (!issecure (SECURE_NOROOT)) {
++              if (bprm->e_uid == 0 || current->uid == 0) {
++                      cap_set_full (bprm->cap_inheritable);
++                      cap_set_full (bprm->cap_permitted);
++              }
++              if (bprm->e_uid == 0)
++                      cap_set_full (bprm->cap_effective);
++      }
++      return 0;
++}
++
++/* Copied from fs/exec.c */
++static inline int must_not_trace_exec (struct task_struct *p)
++{
++      return (p->ptrace & PT_PTRACED) && !(p->ptrace & PT_PTRACE_CAP);
++}
++
++void cap_bprm_compute_creds (struct linux_binprm *bprm)
++{
++      /* Derived from fs/exec.c:compute_creds. */
++      kernel_cap_t new_permitted, working;
++
++      new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
++      working = cap_intersect (bprm->cap_inheritable,
++                               current->cap_inheritable);
++      new_permitted = cap_combine (new_permitted, working);
++
++      task_lock(current);
++      if (!cap_issubset (new_permitted, current->cap_permitted)) {
++              current->mm->dumpable = 0;
++
++              if (must_not_trace_exec (current)
++                  || atomic_read (&current->fs->count) > 1
++                  || atomic_read (&current->files->count) > 1
++                  || atomic_read (&current->sighand->count) > 1) {
++                      if (!capable (CAP_SETPCAP)) {
++                              new_permitted = cap_intersect (new_permitted,
++                                                             current->
++                                                             cap_permitted);
++                      }
++              }
++      }
++
++      /* For init, we want to retain the capabilities set
++       * in the init_task struct. Thus we skip the usual
++       * capability rules */
++      if (current->pid != 1) {
++              current->cap_permitted = new_permitted;
++              current->cap_effective =
++                  cap_intersect (new_permitted, bprm->cap_effective);
++      }
++
++      /* AUD: Audit candidate if current->cap_effective is set */
++      task_unlock(current);
++
++      current->keep_capabilities = 0;
++}
++
++int cap_bprm_secureexec (struct linux_binprm *bprm)
++{
++      /* If/when this module is enhanced to incorporate capability
++         bits on files, the test below should be extended to also perform a 
++         test between the old and new capability sets.  For now,
++         it simply preserves the legacy decision algorithm used by
++         the old userland. */
++      return (current->euid != current->uid ||
++              current->egid != current->gid);
++}
++
++/* moved from kernel/sys.c. */
++/* 
++ * cap_emulate_setxuid() fixes the effective / permitted capabilities of
++ * a process after a call to setuid, setreuid, or setresuid.
++ *
++ *  1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
++ *  {r,e,s}uid != 0, the permitted and effective capabilities are
++ *  cleared.
++ *
++ *  2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
++ *  capabilities of the process are cleared.
++ *
++ *  3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
++ *  capabilities are set to the permitted capabilities.
++ *
++ *  fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should 
++ *  never happen.
++ *
++ *  -astor 
++ *
++ * cevans - New behaviour, Oct '99
++ * A process may, via prctl(), elect to keep its capabilities when it
++ * calls setuid() and switches away from uid==0. Both permitted and
++ * effective sets will be retained.
++ * Without this change, it was impossible for a daemon to drop only some
++ * of its privilege. The call to setuid(!=0) would drop all privileges!
++ * Keeping uid 0 is not an option because uid 0 owns too many vital
++ * files..
++ * Thanks to Olaf Kirch and Peter Benie for spotting this.
++ */
++static inline void cap_emulate_setxuid (int old_ruid, int old_euid,
++                                      int old_suid)
++{
++      if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
++          (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
++          !current->keep_capabilities) {
++              cap_clear (current->cap_permitted);
++              cap_clear (current->cap_effective);
++      }
++      if (old_euid == 0 && current->euid != 0) {
++              cap_clear (current->cap_effective);
++      }
++      if (old_euid != 0 && current->euid == 0) {
++              current->cap_effective = current->cap_permitted;
++      }
++}
++
++int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
++                        int flags)
++{
++      switch (flags) {
++      case LSM_SETID_RE:
++      case LSM_SETID_ID:
++      case LSM_SETID_RES:
++              /* Copied from kernel/sys.c:setreuid/setuid/setresuid. */
++              if (!issecure (SECURE_NO_SETUID_FIXUP)) {
++                      cap_emulate_setxuid (old_ruid, old_euid, old_suid);
++              }
++              break;
++      case LSM_SETID_FS:
++              {
++                      uid_t old_fsuid = old_ruid;
++
++                      /* Copied from kernel/sys.c:setfsuid. */
++
++                      /*
++                       * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
++                       *          if not, we might be a bit too harsh here.
++                       */
++
++                      if (!issecure (SECURE_NO_SETUID_FIXUP)) {
++                              if (old_fsuid == 0 && current->fsuid != 0) {
++                                      cap_t (current->cap_effective) &=
++                                          ~CAP_FS_MASK;
++                              }
++                              if (old_fsuid != 0 && current->fsuid == 0) {
++                                      cap_t (current->cap_effective) |=
++                                          (cap_t (current->cap_permitted) &
++                                           CAP_FS_MASK);
++                              }
++                      }
++                      break;
++              }
++      default:
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++void cap_task_reparent_to_init (struct task_struct *p)
++{
++      p->cap_effective = CAP_INIT_EFF_SET;
++      p->cap_inheritable = CAP_INIT_INH_SET;
++      p->cap_permitted = CAP_FULL_SET;
++      p->keep_capabilities = 0;
++      return;
++}
++
++int cap_syslog (int type)
++{
++      if ((type != 3) && !capable(CAP_SYS_ADMIN))
++              return -EPERM;
++      return 0;
++}
++
++/*
++ * 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.
++ */
++int cap_vm_enough_memory(long pages)
++{
++      unsigned long free, allowed;
++
++      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 root
++               */
++              if (!capable(CAP_SYS_ADMIN))
++                      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;
++}
++
++EXPORT_SYMBOL(cap_capable);
++EXPORT_SYMBOL(cap_ptrace);
++EXPORT_SYMBOL(cap_capget);
++EXPORT_SYMBOL(cap_capset_check);
++EXPORT_SYMBOL(cap_capset_set);
++EXPORT_SYMBOL(cap_bprm_set_security);
++EXPORT_SYMBOL(cap_bprm_compute_creds);
++EXPORT_SYMBOL(cap_bprm_secureexec);
++EXPORT_SYMBOL(cap_task_post_setuid);
++EXPORT_SYMBOL(cap_task_reparent_to_init);
++EXPORT_SYMBOL(cap_syslog);
++EXPORT_SYMBOL(cap_vm_enough_memory);
++
++MODULE_DESCRIPTION("Standard Linux Common Capabilities Security Module");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.0-test5/security/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/security/Makefile   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/Makefile        2003-09-27 11:38:42.376086240 +0800
+@@ -6,7 +6,7 @@
+ # if we don't select a security model, use the default capabilities
+ ifneq ($(CONFIG_SECURITY),y)
+-obj-y         += capability.o
++obj-y         += commoncap.o capability.o
+ endif
+ # Object file lists
+@@ -15,5 +15,5 @@
+ 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
++obj-$(CONFIG_SECURITY_CAPABILITIES)   += commoncap.o capability.o
++obj-$(CONFIG_SECURITY_ROOTPLUG)               += commoncap.o root_plug.o
+Index: linux-2.6.0-test5/security/security.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/security.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/security.c      2003-09-27 11:38:42.379085784 +0800
+@@ -79,9 +79,8 @@
+  * value passed to this function.  A call to unregister_security() should be
+  * done to remove this security_options structure from the kernel.
+  *
+- * If the @ops structure does not contain function pointers for all hooks in
+- * the structure, or there is already a security module registered with the
+- * kernel, an error will be returned.  Otherwise 0 is returned on success.
++ * If there is already a security module registered with the kernel,
++ * an error will be returned.  Otherwise 0 is returned on success.
+  */
+ int register_security (struct security_operations *ops)
+ {
+Index: linux-2.6.0-test5/security/selinux/hooks.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/hooks.c    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/hooks.c 2003-09-27 11:38:42.400082592 +0800
+@@ -73,7 +73,8 @@
+ __setup("enforcing=", enforcing_setup);
+ #endif
+-int selinux_enabled = 0;
++#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
++int selinux_enabled = 1;
+ static int __init selinux_enabled_setup(char *str)
+ {
+@@ -81,6 +82,7 @@
+       return 1;
+ }
+ __setup("selinux=", selinux_enabled_setup);
++#endif
+ /* Original (dummy) security module. */
+ static struct security_operations *original_ops = NULL;
+@@ -3357,7 +3359,7 @@
+       struct task_security_struct *tsec;
+       if (!selinux_enabled) {
+-              printk(KERN_INFO "SELinux:  Not enabled at boot.\n");
++              printk(KERN_INFO "SELinux:  Disabled at boot.\n");
+               return 0;
+       }
+Index: linux-2.6.0-test5/security/selinux/include/security.h
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/include/security.h 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/include/security.h      2003-09-27 11:38:42.402082288 +0800
+@@ -14,6 +14,12 @@
+ #define SELINUX_MAGIC 0xf97cff8c
++#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
++extern int selinux_enabled;
++#else
++#define selinux_enabled 1
++#endif
++
+ int security_load_policy(void * data, size_t len);
+ struct av_decision {
+Index: linux-2.6.0-test5/security/selinux/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/Kconfig    2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/Kconfig 2003-09-27 11:38:42.403082136 +0800
+@@ -8,9 +8,20 @@
+         You can obtain the policy compiler (checkpolicy), the utility for
+         labeling filesystems (setfiles), and an example policy configuration
+         from http://www.nsa.gov/selinux.
+-        SELinux needs to be explicitly enabled on the kernel command line with
+-        selinux=1.  If you specify selinux=0 or do not use this parameter,
+-        SELinux will not be enabled.
++        If you are unsure how to answer this question, answer N.
++
++config SECURITY_SELINUX_BOOTPARAM
++      bool "NSA SELinux boot parameter"
++      depends on SECURITY_SELINUX
++      default n
++      help
++        This option adds a kernel parameter 'selinux', which allows SELinux
++        to be disabled at boot.  If this option is selected, SELinux
++        functionality can be disabled with selinux=0 on the kernel
++        command line.  The purpose of this option is to allow a single
++        kernel image to be distributed with SELinux built in, but not
++        necessarily enabled.
++
+         If you are unsure how to answer this question, answer N.
+ config SECURITY_SELINUX_DEVELOP
+Index: linux-2.6.0-test5/security/selinux/selinuxfs.c
+===================================================================
+--- linux-2.6.0-test5.orig/security/selinux/selinuxfs.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/security/selinux/selinuxfs.c     2003-09-27 11:38:42.408081376 +0800
+@@ -17,8 +17,6 @@
+ #include "security.h"
+ #include "objsec.h"
+-extern int selinux_enabled;
+-
+ /* Check whether a task is allowed to use a security operation. */
+ int task_has_security(struct task_struct *tsk,
+                     u32 perms)
+Index: linux-2.6.0-test5/sound/core/ioctl32/ioctl32.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/core/ioctl32/ioctl32.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/core/ioctl32/ioctl32.c     2003-09-27 11:38:42.411080920 +0800
+@@ -25,7 +25,6 @@
+ #include <linux/time.h>
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+-#include <linux/init.h>
+ #include <sound/core.h>
+ #include <sound/control.h>
+ #include <asm/uaccess.h>
+Index: linux-2.6.0-test5/sound/oss/ac97_codec.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/ac97_codec.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/ac97_codec.c   2003-09-27 11:38:42.422079248 +0800
+@@ -1078,6 +1078,10 @@
+ /* WM9711, WM9712 */
+ static int wolfson_init11(struct ac97_codec * codec)
+ {
++      /* stop pop's during suspend/resume */
++      codec->codec_write(codec, AC97_WM97XX_TEST,
++              codec->codec_read(codec, AC97_WM97XX_TEST) & 0xffbf);
++
+       /* set out3 volume */
+       codec->codec_write(codec, AC97_WM9711_OUT3VOL, 0x0808);
+       return 0;
+Index: linux-2.6.0-test5/sound/oss/dmasound/awacs_defs.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/awacs_defs.h     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/awacs_defs.h  2003-09-27 11:38:42.426078640 +0800
+@@ -71,17 +71,20 @@
+ /* ------- - --- ----- - ------ */
+ #define MASK_GAINRIGHT        (0xf)           /* Gain Right Mask */
+ #define MASK_GAINLEFT (0xf << 4)      /* Gain Left Mask */
+-#define MASK_GAINLINE (0x1 << 8)      /* Change Gain for Line??? */
+-#define MASK_GAINMIC  (0x0 << 8)      /* Change Gain for Mic??? */
++#define MASK_GAINLINE (0x1 << 8)      /* Disable Mic preamp */
++#define MASK_GAINMIC  (0x0 << 8)      /* Enable Mic preamp */
+ #define MASK_MUX_CD   (0x1 << 9)      /* Select CD in MUX */
+-#define MASK_MUX_AUDIN        (0x1 << 10)     /* Select Audio In in MUX */
+-#define MASK_MUX_MIC  (0x1 << 11)     /* Select Mic in MUX */
++#define MASK_MUX_MIC  (0x1 << 10)     /* Select Mic in MUX */
++#define MASK_MUX_AUDIN        (0x1 << 11)     /* Select Audio In in MUX */
+ #define MASK_MUX_LINE MASK_MUX_AUDIN
+ #define GAINRIGHT(x)  ((x) & MASK_GAINRIGHT)
+ #define GAINLEFT(x)   (((x) << 4) & MASK_GAINLEFT)
++#define DEF_CD_GAIN 0x00bb
++#define DEF_MIC_GAIN 0x00cc
++
+ /* Address 1 Bit Masks */
+ /* ------- - --- ----- */
+ #define MASK_ADDR1RES1        (0x3)           /* Reserved */
+@@ -93,7 +96,10 @@
+ #define MASK_ADDR1RES2        (0x1 << 8)      /* Reserved */
+ #define MASK_AMUTE    (0x1 << 9)      /* Output A (Headphone) Mute when 1 */
+ #define MASK_HDMUTE   MASK_AMUTE
+-#define MASK_PAROUT   (0x3 << 10)     /* Parallel Out (???) */
++#define MASK_PAROUT0  (0x1 << 10)     /* Parallel Output 0 */
++#define MASK_PAROUT1  (0x2 << 10)     /* Parallel Output 1 */
++
++#define MASK_MIC_BOOST  (0x4)           /* screamer mic boost */
+ #define SAMPLERATE_48000      (0x0 << 3)      /* 48 or 44.1 kHz */
+ #define SAMPLERATE_32000      (0x1 << 3)      /* 32 or 29.4 kHz */
+@@ -162,8 +168,9 @@
+ #define RATE_LOW      1       /* HIGH = 48kHz, etc;  LOW = 44.1kHz, etc. */
+-
++/*******************/
+ /* Burgundy values */
++/*******************/
+ #define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
+ #define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
+@@ -226,4 +233,19 @@
+ #define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
+ #define DEF_BURGUNDY_ATTENHP (0xCC)
++/*********************/
++/* i2s layout values */
++/*********************/
++
++#define I2S_REG_INT_CTL                       0x00
++#define I2S_REG_SERIAL_FORMAT         0x10
++#define I2S_REG_CODEC_MSG_OUT         0x20
++#define I2S_REG_CODEC_MSG_IN          0x30
++#define I2S_REG_FRAME_COUNT           0x40
++#define I2S_REG_FRAME_MATCH           0x50
++#define I2S_REG_DATAWORD_SIZES                0x60
++#define I2S_REG_PEAKLEVEL_SEL         0x70
++#define I2S_REG_PEAKLEVEL_IN0         0x80
++#define I2S_REG_PEAKLEVEL_IN1         0x90
++
+ #endif /* _AWACS_DEFS_H_ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/dac3550a.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/dac3550a.c       2003-09-27 11:38:18.495716608 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/dac3550a.c    2003-09-27 11:38:42.427078488 +0800
+@@ -0,0 +1,222 @@
++/*
++ * Driver for the i2c/i2s based DAC3550a sound chip used
++ * on some Apple iBooks. Also known as "DACA".
++ *
++ *  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/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++
++#include "dmasound.h"
++
++/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
++ * control code, as well as info derived from the AppleDACAAudio driver
++ * from Darwin CVS (main thing I derived being register numbers and 
++ * values, as well as when to make the calls). */
++
++#define I2C_DRIVERID_DACA (0xFDCB)
++
++#define DACA_VERSION  "0.1"
++#define DACA_DATE "20010930"
++
++static int cur_left_vol;
++static int cur_right_vol;
++static struct i2c_client *daca_client;
++
++static int daca_attach_adapter(struct i2c_adapter *adapter);
++static int daca_detect_client(struct i2c_adapter *adapter, int address);
++static int daca_detach_client(struct i2c_client *client);
++
++/* Unique ID allocation */
++static int daca_id;
++
++struct daca_data
++{
++      int arf; /* place holder for furture use */
++};
++
++struct i2c_driver daca_driver = {  
++      .owner                  = THIS_MODULE,
++      .name                   = "DAC3550A driver  V " DACA_VERSION,
++      .id                     = I2C_DRIVERID_DACA,
++      .flags                  = I2C_DF_NOTIFY,
++      .attach_adapter         = daca_attach_adapter,
++      .detach_client          = daca_detach_client,
++};
++
++#define VOL_MAX ((1<<20) - 1)
++
++void daca_get_volume(uint * left_vol, uint  *right_vol)
++{
++      *left_vol = cur_left_vol >> 5;
++      *right_vol = cur_right_vol >> 5;
++}
++
++int daca_set_volume(uint left_vol, uint right_vol)
++{
++      unsigned short voldata;
++  
++      if (!daca_client)
++              return -1;
++
++      /* Derived from experience, not from any specific values */
++      left_vol <<= 5;
++      right_vol <<= 5;
++
++      if (left_vol > VOL_MAX)
++              left_vol = VOL_MAX;
++      if (right_vol > VOL_MAX)
++              right_vol = VOL_MAX;
++
++      voldata = ((left_vol >> 14)  & 0x3f) << 8;
++      voldata |= (right_vol >> 14)  & 0x3f;
++  
++      if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
++              printk("daca: failed to set volume \n");
++              return -1; 
++      }
++
++      cur_left_vol = left_vol;
++      cur_right_vol = right_vol;
++  
++      return 0;
++}
++
++int daca_leave_sleep(void)
++{
++      if (!daca_client)
++              return -1;
++  
++      /* Do a short sleep, just to make sure I2C bus is awake and paying
++       * attention to us
++       */
++      wait_ms(20);
++      /* Write the sample rate reg the value it needs */
++      i2c_smbus_write_byte_data(daca_client, 1, 8);
++      daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
++      /* Another short delay, just to make sure the other I2C bus writes
++       * have taken...
++       */
++      wait_ms(20);
++      /* Write the global config reg - invert right power amp,
++       * DAC on, use 5-volt mode */
++      i2c_smbus_write_byte_data(daca_client, 3, 0x45);
++
++      return 0;
++}
++
++int daca_enter_sleep(void)
++{
++      if (!daca_client)
++              return -1;
++
++      i2c_smbus_write_byte_data(daca_client, 1, 8);
++      daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
++
++      /* Write the global config reg - invert right power amp,
++       * DAC on, enter low-power mode, use 5-volt mode
++       */
++      i2c_smbus_write_byte_data(daca_client, 3, 0x65);
++
++      return 0;
++}
++
++static int daca_attach_adapter(struct i2c_adapter *adapter)
++{
++      if (!strncmp(adapter->name, "mac-io", 6))
++              daca_detect_client(adapter, 0x4d);
++      return 0;
++}
++
++static int daca_init_client(struct i2c_client * new_client)
++{
++      /* 
++       * Probe is not working with the current i2c-keywest
++       * driver. We try to use addr 0x4d on each adapters
++       * instead, by setting the format register.
++       * 
++       * FIXME: I'm sure that can be obtained from the
++       * device-tree. --BenH.
++       */
++  
++      /* Write the global config reg - invert right power amp,
++       * DAC on, use 5-volt mode
++       */
++      if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
++              return -1;
++
++      i2c_smbus_write_byte_data(new_client, 1, 8);
++      daca_client = new_client;
++      daca_set_volume(15000, 15000);
++
++      return 0;
++}
++
++static int daca_detect_client(struct i2c_adapter *adapter, int address)
++{
++      const char *client_name = "DAC 3550A Digital Equalizer";
++      struct i2c_client *new_client;
++      struct daca_data *data;
++      int rc = -ENODEV;
++
++      new_client = kmalloc(sizeof(*new_client) + sizeof(*data), GFP_KERNEL);
++      if (!new_client)
++              return -ENOMEM;
++
++      new_client->addr = address;
++      new_client->adapter = adapter;
++      new_client->driver = &daca_driver;
++      new_client->flags = 0;
++      strcpy(new_client->name, client_name);
++      new_client->id = daca_id++; /* racy... */
++
++      data = (struct daca_data *)(new_client+1);
++      dev_set_drvdata(&new_client->dev, data);
++
++      if (daca_init_client(new_client))
++              goto bail;
++
++      /* Tell the i2c layer a new client has arrived */
++      if (i2c_attach_client(new_client))
++              goto bail;
++
++      return 0;
++ bail:
++      kfree(new_client);
++      return rc;
++}
++
++
++static int daca_detach_client(struct i2c_client *client)
++{
++      if (client == daca_client)
++              daca_client = NULL;
++
++      i2c_detach_client(client);
++      kfree(client);
++      return 0;
++}
++
++void daca_cleanup(void)
++{
++      i2c_del_driver(&daca_driver);
++}
++
++int daca_init(void)
++{
++      printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);
++      return i2c_add_driver(&daca_driver);
++}
+Index: linux-2.6.0-test5/sound/oss/dmasound/dmasound_awacs.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/dmasound_awacs.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/dmasound_awacs.c      2003-09-27 11:38:42.451074840 +0800
+@@ -45,7 +45,14 @@
+  *      01/02/2002 [0.7] - BenH
+  *            - all sort of minor bits went in since the latest update, I
+  *              bumped the version number for that reason
+-*/
++ *
++ *      07/26/2002 [0.8] - BenH
++ *            - More minor bits since last changelog (I should be more careful
++ *              with those)
++ *            - Support for snapper & better tumbler integration by Toby Sargeant
++ *            - Headphone detect for scremer by Julien Blache
++ *            - More tumbler fixed by Andreas Schwab
++ */
+ /* GENERAL FIXME/TODO: check that the assumptions about what is written to
+    mac-io is valid for DACA & Tumbler.
+@@ -68,6 +75,7 @@
+ #include <linux/irq.h>
+ #include <linux/spinlock.h>
+ #include <linux/kmod.h>
++#include <linux/interrupt.h>
+ #include <asm/semaphore.h>
+ #ifdef CONFIG_ADB_CUDA
+ #include <linux/cuda.h>
+@@ -89,10 +97,14 @@
+ #include "awacs_defs.h"
+ #include "dmasound.h"
++#include "tas3001c.h"
++#include "tas3004.h"
++#include "tas_common.h"
+ #define DMASOUND_AWACS_REVISION       0
+ #define DMASOUND_AWACS_EDITION        7
++#define AWACS_SNAPPER   110   /* fake revision # for snapper */
+ #define AWACS_BURGUNDY        100     /* fake revision # for burgundy */
+ #define AWACS_TUMBLER    90   /* fake revision # for tumbler */
+ #define AWACS_DACA     80     /* fake revision # for daca (ibook) */
+@@ -103,11 +115,13 @@
+  */
+ static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
+ static volatile struct awacs_regs *awacs;
++static volatile u32 *i2s;
+ static volatile struct dbdma_regs *awacs_txdma, *awacs_rxdma;
+ static int awacs_rate_index;
+ static int awacs_subframe;
+ static int awacs_spkr_vol;
+ static struct device_node* awacs_node;
++static struct device_node* i2s_node;
+ static char awacs_name[64];
+ static int awacs_revision;
+@@ -164,6 +178,8 @@
+ static int cd_lev = 0x6363 ; /* 99 % */
+ static int line_lev;
++static int hdp_connected;
++
+ /*
+  * Stuff for outputting a beep.  The values range from -327 to +327
+  * so we can multiply by an amplitude in the range 0..100 to get a
+@@ -215,7 +231,6 @@
+ static short *beep_buf;
+ static void *beep_dbdma_cmd_space;
+ static volatile struct dbdma_cmd *beep_dbdma_cmd;
+-static void (*orig_mksound)(unsigned int, unsigned int);
+ /* Burgundy functions */
+ static void awacs_burgundy_wcw(unsigned addr,unsigned newval);
+@@ -286,25 +301,12 @@
+ extern TRANS transAwacsNormalRead ;
+ extern int daca_init(void);
+-extern int daca_cleanup(void);
++extern void daca_cleanup(void);
+ extern int daca_set_volume(uint left_vol, uint right_vol);
+ extern void daca_get_volume(uint * left_vol, uint  *right_vol);
+ extern int daca_enter_sleep(void);
+ extern int daca_leave_sleep(void);
+-extern int tas_init(void);
+-extern int tas_cleanup(void);
+-extern int tumbler_set_volume(uint left_vol, uint right_vol);
+-extern void tumbler_get_volume(uint * left_vol, uint  *right_vol);
+-extern void tumbler_set_treble(int treble);
+-extern void tumbler_get_treble(int *treble);
+-extern void tumbler_set_bass(int bass);
+-extern void tumbler_get_bass(int *bass);
+-extern void tumbler_set_pcm_lvl(int pcm_lvl);
+-extern void tumbler_get_pcm_lvl(int *pcm_lvl);
+-extern int tumbler_enter_sleep(void);
+-extern int tumbler_leave_sleep(void);
+-
+ #define TRY_LOCK()    \
+       if ((rc = down_interruptible(&dmasound_sem)) != 0)      \
+               return rc;
+@@ -331,7 +333,7 @@
+ }
+-/*** AE - TUMBLER START *********************************************************/
++/*** AE - TUMBLER / SNAPPER START ************************************************/
+ int gpio_audio_reset, gpio_audio_reset_pol;
+@@ -393,31 +395,35 @@
+       return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
+ }
++/*
++ * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
++ */
+ static irqreturn_t
+ headphone_intr(int irq, void *devid, struct pt_regs *regs)
+ {
+-      int handled = 0;
+-      spin_lock(&dmasound.lock);
++      unsigned long flags;
++
++      spin_lock_irqsave(&dmasound.lock, flags);
+       if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
+-              handled = 1;
+               printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
+-              write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
+               write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
++              write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
++              tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
+       } else {
+-              handled = 1;
+               printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
+               write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
+               write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
++              tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
+       }
+-      spin_unlock(&dmasound.lock);
+-      return IRQ_RETVAL(handled);
++      spin_unlock_irqrestore(&dmasound.lock, flags);
++      return IRQ_HANDLED;
+ }
+ /* Initialize tumbler */
+ static int
+-awacs_tumbler_init(void)
++tas_dmasound_init(void)
+ {
+       setup_audio_gpio(
+               "audio-hw-reset",
+@@ -474,15 +480,124 @@
+ static int
+-awacs_tumbler_cleanup(void)
++tas_dmasound_cleanup(void)
+ {
+       if (gpio_headphone_irq)
+               free_irq(gpio_headphone_irq, 0);
+       return 0;
+ }
++/* We don't support 48k yet */
++static int tas_freqs[1] = { 44100 } ;
++static int tas_freqs_ok[1] = { 1 } ;
++
++/* don't know what to do really - just have to leave it where
++ * OF left things
++*/
++
++static int
++tas_set_frame_rate(void)
++{
++      if (i2s) {
++              out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
++              out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
++      }
++      dmasound.hard.speed = 44100 ;
++      awacs_rate_index = 0 ;
++      return 44100 ;
++}
++
++static int
++tas_mixer_ioctl(u_int cmd, u_long arg)
++{
++      int data;
++      int rc;
++
++        rc=tas_device_ioctl(cmd, arg);
++        if (rc != -EINVAL) {
++              return rc;
++        }
++
++        if ((cmd & ~0xff) == MIXER_WRITE(0) &&
++            tas_supported_mixers() & (1<<(cmd & 0xff))) {
++              rc = get_user(data, (int *)(arg));
++                if (rc<0) return rc;
++              tas_set_mixer_level(cmd & 0xff, data);
++              tas_get_mixer_level(cmd & 0xff, &data);
++              return ioctl_return2((int *)(arg), data);
++        }
++        if ((cmd & ~0xff) == MIXER_READ(0) &&
++            tas_supported_mixers() & (1<<(cmd & 0xff))) {
++              tas_get_mixer_level(cmd & 0xff, &data);
++              return ioctl_return2((int *)(arg), data);
++        }
++
++      switch(cmd) {
++      case SOUND_MIXER_READ_DEVMASK:
++              data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
++              rc = IOCTL_OUT(arg, data);
++              break;
++      case SOUND_MIXER_READ_STEREODEVS:
++              data = tas_stereo_mixers();
++              rc = IOCTL_OUT(arg, data);
++              break;
++      case SOUND_MIXER_READ_CAPS:
++              rc = IOCTL_OUT(arg, 0);
++              break;
++      case SOUND_MIXER_READ_RECMASK:
++              data = 0;
++              rc = IOCTL_OUT(arg, data);
++              break;
++      case SOUND_MIXER_READ_RECSRC:
++              data = 0;
++              rc = IOCTL_OUT(arg, data);
++              break;
++      case SOUND_MIXER_WRITE_RECSRC:
++              IOCTL_IN(arg, data);
++              data =0;
++              rc = IOCTL_OUT(arg, data);
++              break;
++      case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */
++              IOCTL_IN(arg, data);
++              beep_vol = data & 0xff;
++              /* fall through */
++      case SOUND_MIXER_READ_SPEAKER:
++              rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
++              break;
++      case SOUND_MIXER_OUTMASK:
++      case SOUND_MIXER_OUTSRC:
++      default:
++              rc = -EINVAL;
++      }
++
++      return rc;
++}
++
++static void __init
++tas_init_frame_rates(unsigned int *prop, unsigned int l)
++{
++      int i ;
++      if (prop) {
++              for (i=0; i<1; i++)
++                      tas_freqs_ok[i] = 0;
++              for (l /= sizeof(int); l > 0; --l) {
++                      unsigned int r = *prop++;
++                      /* Apple 'Fixed' format */
++                      if (r >= 0x10000)
++                              r >>= 16;
++                      for (i = 0; i < 1; ++i) {
++                              if (r == tas_freqs[i]) {
++                                      tas_freqs_ok[i] = 1;
++                                      break;
++                              }
++                      }
++              }
++      }
++      /* else we assume that all the rates are available */
++}
++
+-/*** AE - TUMBLER END *********************************************************/
++/*** AE - TUMBLER / SNAPPER END ************************************************/
+@@ -503,8 +618,10 @@
+ static int __init PMacIrqInit(void)
+ {
+-      if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", 0)
+-          || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", 0)
++      if (awacs)
++              if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", 0))
++                      return 0;
++      if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", 0)
+           || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", 0))
+               return 0;
+       return 1;
+@@ -517,23 +634,28 @@
+       DBDMA_DO_STOP(awacs_txdma);
+       DBDMA_DO_STOP(awacs_rxdma);
+-      /* disable interrupts from awacs interface */
+-      out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
+-
++      if (awacs)
++              /* disable interrupts from awacs interface */
++              out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
++      
+       /* Switch off the sound clock */
+       pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
+       /* Make sure proper bits are set on pismo & tipb */
+-      if (machine_is_compatible("PowerBook3,1") ||
+-          machine_is_compatible("PowerBook3,2")) {
++      if ((machine_is_compatible("PowerBook3,1") ||
++          machine_is_compatible("PowerBook3,2")) && awacs) {
+               awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
+               awacs_write(MASK_ADDR1 | awacs_reg[1]);
+               wait_ms(200);
+       }
+-      free_irq(awacs_irq, 0);
++      if (awacs)
++              free_irq(awacs_irq, 0);
+       free_irq(awacs_tx_irq, 0);
+       free_irq(awacs_rx_irq, 0);
+-      /* all OF versions I've seen use this value */
+-      iounmap((void *)awacs);
++      
++      if (awacs)
++              iounmap((void *)awacs);
++      if (i2s)
++              iounmap((void *)i2s);
+       iounmap((void *)awacs_txdma);
+       iounmap((void *)awacs_rxdma);
+@@ -547,10 +669,8 @@
+               kfree(awacs_rx_cmd_space);
+       if (beep_dbdma_cmd_space)
+               kfree(beep_dbdma_cmd_space);
+-      if (beep_buf) {
++      if (beep_buf)
+               kfree(beep_buf);
+-              kd_mksound = orig_mksound;
+-      }
+ #ifdef CONFIG_PMAC_PBOOK
+       pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
+ #endif
+@@ -563,26 +683,16 @@
+       DBDMA_DO_STOP(awacs_txdma);
+ }
+-static int tumbler_freqs[2] = { 48000, 44100 } ;
+-static int tumbler_freqs_ok[2] = { 1, 1 } ;
+-
+-/* don't know what to do really - just have to leave it where
+- * OF left things
+-*/
+-
+-static int tumbler_set_frame_rate(void)
+-{
+-      dmasound.hard.speed = 44100 ;
+-      awacs_rate_index = 0 ;
+-      return 44100 ;
+-}
+-
+ /* don't know what to do really - just have to leave it where
+  * OF left things
+ */
+ static int daca_set_frame_rate(void)
+ {
++      if (i2s) {
++              out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
++              out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
++      }
+       dmasound.hard.speed = 44100 ;
+       awacs_rate_index = 0 ;
+       return 44100 ;
+@@ -593,7 +703,8 @@
+ };
+ static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
+-static int awacs_set_frame_rate(int desired, int catch_r)
++static int
++awacs_set_frame_rate(int desired, int catch_r)
+ {
+       int tolerance, i = 8 ;
+       /*
+@@ -617,13 +728,9 @@
+       return dmasound.hard.speed;
+ }
+-static int burgundy_frame_rates = 1 ;
+-static int burgundy_set_frame_rate(void)
++static int
++burgundy_set_frame_rate(void)
+ {
+-#ifdef DEBUG_DMASOUND
+-if (burgundy_frame_rates > 1)
+-      printk("dmasound_pmac: warning Burgundy had more than one frame rate\n");
+-#endif
+       awacs_rate_index = 0 ;
+       awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
+       /* XXX disable error interrupt on burgundy for now */
+@@ -631,24 +738,24 @@
+       return 44100 ;
+ }
+-static int set_frame_rate(int desired, int catch_r)
++static int
++set_frame_rate(int desired, int catch_r)
+ {
+       switch (awacs_revision) {
+               case AWACS_BURGUNDY:
+-                      dmasound.hard.speed =
+-                        burgundy_set_frame_rate();
++                      dmasound.hard.speed = burgundy_set_frame_rate();
+                       break ;
+               case AWACS_TUMBLER:
+-                      dmasound.hard.speed =
+-                        tumbler_set_frame_rate();
++              case AWACS_SNAPPER:
++                      dmasound.hard.speed = tas_set_frame_rate();
+                       break ;
+               case AWACS_DACA:
+                       dmasound.hard.speed =
+                         daca_set_frame_rate();
+                       break ;
+               default:
+-                      dmasound.hard.speed =
+-                        awacs_set_frame_rate(desired, catch_r);
++                      dmasound.hard.speed = awacs_set_frame_rate(desired,
++                                              catch_r);
+                       break ;
+       }
+       return dmasound.hard.speed ;
+@@ -698,11 +805,13 @@
+               dmasound.trans_write = &transAwacsExpand;
+       dmasound.trans_read = &transAwacsNormalRead;
+-      if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+-              out_le32(&awacs->byteswap, BS_VAL);
+-      else
+-              out_le32(&awacs->byteswap, 0);
+-
++      if (awacs) {
++              if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
++                      out_le32(&awacs->byteswap, BS_VAL);
++              else
++                      out_le32(&awacs->byteswap, 0);
++      }
++      
+       expand_bal = -dmasound.soft.speed;
+ }
+@@ -787,18 +896,28 @@
+ static int PMacSetVolume(int volume)
+ {
+-      return awacs_volume_setter(volume, 2, MASK_AMUTE, 6);
++      printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
++      return 0;
++}
++
++static void awacs_setup_for_beep(int speed)
++{
++      out_le32(&awacs->control,
++               (in_le32(&awacs->control) & ~0x1f00)
++               | ((speed > 0 ? speed : awacs_rate_index) << 8));
++
++      if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
++              out_le32(&awacs->byteswap, BS_VAL);
++      else
++              out_le32(&awacs->byteswap, 0);
+ }
++/* CHECK: how much of this *really* needs IRQs masked? */
+ static void __PMacPlay(void)
+ {
+       volatile struct dbdma_cmd *cp;
+       int next_frg, count;
+-      unsigned long flags;
+-
+-      /* CHECK: how much of this *really* needs IRQs masked? */
+-      spin_lock_irqsave(&dmasound.lock, flags);
+       count = 300 ; /* > two cycles at the lowest sample rate */
+       /* what we want to send next */
+@@ -810,15 +929,8 @@
+               out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
+               while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
+                       udelay(1);
+-              /* FIXME: check that this is OK for other chip sets */
+-              out_le32(&awacs->control,
+-                       (in_le32(&awacs->control) & ~0x1f00)
+-                       | (awacs_rate_index << 8));
+-
+-              if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+-                      out_le32(&awacs->byteswap, BS_VAL);
+-              else
+-                      out_le32(&awacs->byteswap, 0);
++              if (awacs)
++                      awacs_setup_for_beep(-1);
+               out_le32(&awacs_txdma->cmdptr,
+                        virt_to_bus(&(awacs_tx_cmds[next_frg])));
+@@ -865,14 +977,18 @@
+               out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
+               ++write_sq.active;
+       }
+-      spin_unlock_irqrestore(&dmasound.lock, flags);
+ }
+ static void PMacPlay(void)
+ {
+       LOCK();
+-      if (!awacs_sleeping)
++      if (!awacs_sleeping) {
++              unsigned long flags;
++
++              spin_lock_irqsave(&dmasound.lock, flags);
+               __PMacPlay();
++              spin_unlock_irqrestore(&dmasound.lock, flags);
++      }
+       UNLOCK();
+ }
+@@ -919,6 +1035,7 @@
+ {
+       int i = write_sq.front;
+       int stat;
++      int i_nowrap = write_sq.front;
+       volatile struct dbdma_cmd *cp;
+       /* != 0 when we are dealing with a DEAD xfer */
+       static int emergency_in_use;
+@@ -976,6 +1093,7 @@
+                       emergency_in_use = 0 ; /* done that */
+               --write_sq.count;
+               --write_sq.active;
++              i_nowrap++;
+               if (++i >= write_sq.max_count)
+                       i = 0;
+       }
+@@ -988,7 +1106,7 @@
+       }
+       /* if we used some data up then wake the writer to supply some more*/
+-      if (i != write_sq.front)
++      if (i_nowrap != write_sq.front)
+               WAKE_UP(write_sq.action_queue);
+       write_sq.front = i;
+@@ -1091,11 +1209,30 @@
+ pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs)
+ {
+       int ctrl;
++      int status;
++      int r1;
++
+       spin_lock(&dmasound.lock);
+       ctrl = in_le32(&awacs->control);
++      status = in_le32(&awacs->codec_stat);
+       if (ctrl & MASK_PORTCHG) {
+-              /* do something when headphone is plugged/unplugged? */
++              /* tested on Screamer, should work on others too */
++              if (awacs_revision == AWACS_SCREAMER) {
++                      if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
++                              hdp_connected = 1;
++                              
++                              r1 = awacs_reg[1] | MASK_SPKMUTE;
++                              awacs_reg[1] = r1;
++                              awacs_write(r1 | MASK_ADDR_MUTE);
++                      } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
++                              hdp_connected = 0;
++                              
++                              r1 = awacs_reg[1] & ~MASK_SPKMUTE;
++                              awacs_reg[1] = r1;
++                              awacs_write(r1 | MASK_ADDR_MUTE);
++                      }
++              }
+       }
+       if (ctrl & MASK_CNTLERR) {
+               int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
+@@ -1113,7 +1250,7 @@
+ awacs_write(int val)
+ {
+       int count = 300 ;
+-      if (awacs_revision >= AWACS_DACA)
++      if (awacs_revision >= AWACS_DACA || !awacs)
+               return ;
+       while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
+@@ -1136,22 +1273,16 @@
+               out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
+               while ((in_le32(&awacs_txdma->status) & RUN) && count--)
+                       udelay(1);
+-              /* FIXME: check this is OK for DACA, Tumbler */
+-              out_le32(&awacs->control,
+-                       (in_le32(&awacs->control) & ~0x1f00)
+-                       | (awacs_rate_index << 8));
+-              if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+-                      out_le32(&awacs->byteswap, BS_VAL);
+-              else
+-                      out_le32(&awacs->byteswap, 0);
++              if (awacs)
++                      awacs_setup_for_beep(-1);
+               beep_playing = 0;
+       }
+       spin_unlock_irqrestore(&dmasound.lock, flags);
+ }
+ static struct timer_list beep_timer = TIMER_INITIALIZER(awacs_nosound, 0, 0);
+-};
++#if 0 /* would need to go through the input layer in 2.6, later..  --hch */
+ /* we generate the beep with a single dbdma command that loops a buffer
+    forever - without generating interrupts.
+    So, to stop it you have to stop dma output as per awacs_nosound.
+@@ -1237,17 +1368,15 @@
+               out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
+               while ((in_le32(&awacs_txdma->status) & RUN) && count--)
+                       udelay(1); /* timeout > 2 samples at lowest rate*/
+-              /* FIXME: check this is OK on DACA, Tumbler */
+-              out_le32(&awacs->control,
+-                       (in_le32(&awacs->control) & ~0x1f00)
+-                       | (beep_speed << 8));
+-              out_le32(&awacs->byteswap, 0); /* force BE */
++              if (awacs)
++                      awacs_setup_for_beep(beep_speed);
+               out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
+               (void)in_le32(&awacs_txdma->status);
+               out_le32(&awacs_txdma->control, RUN | (RUN << 16));
+       }
+       spin_unlock_irqrestore(&dmasound.lock, flags);
+ }
++#endif
+ /* used in init and for wake-up */
+@@ -1267,10 +1396,12 @@
+               awacs_write(awacs_reg[1] + MASK_ADDR1);
+               awacs_write(awacs_reg[7] + MASK_ADDR7);
+       }
+-      if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+-              out_le32(&awacs->byteswap, BS_VAL);
+-      else
+-              out_le32(&awacs->byteswap, 0);
++      if (awacs) {
++              if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
++                      out_le32(&awacs->byteswap, BS_VAL);
++              else
++                      out_le32(&awacs->byteswap, 0);
++      }
+ }
+ #ifdef CONFIG_PMAC_PBOOK
+@@ -1280,6 +1411,8 @@
+ /* FIXME: sort out disabling/re-enabling of read stuff as well */
+ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
+ {
++      unsigned long flags;
++
+       switch (when) {
+       case PBOOK_SLEEP_NOW:           
+               LOCK();
+@@ -1297,9 +1430,18 @@
+               /* stop rx - if going - a bit of a daft user... but */
+               out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
+               /* deny interrupts */
++              if (awacs)
++                      disable_irq(awacs_irq);
++              disable_irq(awacs_tx_irq);
++              disable_irq(awacs_rx_irq);
++              /* Chip specific sleep code */
+               switch (awacs_revision) {
+                       case AWACS_TUMBLER:
+-                              tumbler_enter_sleep(); /* Stub for now */
++                      case AWACS_SNAPPER:
++                              write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
++                              write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
++                              tas_enter_sleep();
++                              write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
+                               break ;
+                       case AWACS_DACA:
+                               daca_enter_sleep();
+@@ -1312,17 +1454,14 @@
+                               out_le32(&awacs->control, 0x11) ;
+                               break ;
+               }
+-              disable_irq(awacs_irq);
+-              disable_irq(awacs_tx_irq);
+-              disable_irq(awacs_rx_irq);
+               /* Disable sound clock */
+               pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
+               /* According to Darwin, we do that after turning off the sound
+                * chip clock. All this will have to be cleaned up once we properly
+                * parse the OF sound-objects
+                */
+-              if (machine_is_compatible("PowerBook3,1") ||
+-                  machine_is_compatible("PowerBook3,2")) {
++              if ((machine_is_compatible("PowerBook3,1") ||
++                  machine_is_compatible("PowerBook3,2")) && awacs) {
+                       awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
+                       awacs_write(MASK_ADDR1 | awacs_reg[1]);
+                       wait_ms(200);
+@@ -1331,8 +1470,8 @@
+       case PBOOK_WAKE:
+               /* Enable sound clock */
+               pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
+-              if (machine_is_compatible("PowerBook3,1") ||
+-                  machine_is_compatible("PowerBook3,2")) {
++              if ((machine_is_compatible("PowerBook3,1") ||
++                  machine_is_compatible("PowerBook3,2")) && awacs) {
+                       wait_ms(100);
+                       awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
+                       awacs_write(MASK_ADDR1 | awacs_reg[1]);
+@@ -1342,13 +1481,20 @@
+               /* restore settings */
+               switch (awacs_revision) {
+                       case AWACS_TUMBLER:
++                      case AWACS_SNAPPER:
++                              write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
++                              write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
++                              write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
++                              wait_ms(100);
++                              write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
++                              wait_ms(150);
++                              tas_leave_sleep(); /* Stub for now */
+                               headphone_intr(0,0,0);
+-                              tumbler_leave_sleep(); /* Stub for now */
+                               break;
+                       case AWACS_DACA:
+                               wait_ms(10); /* Check this !!! */
+                               daca_leave_sleep();
+-                              break ;         /* don't know how yet */
++                              break ;         /* dont know how yet */
+                       case AWACS_BURGUNDY:
+                               break ;
+                       case AWACS_SCREAMER:
+@@ -1358,17 +1504,20 @@
+                               break ;
+               }
+               /* Recalibrate chip */
+-              if (awacs_revision == AWACS_SCREAMER)
++              if (awacs_revision == AWACS_SCREAMER && awacs)
+                       awacs_recalibrate();
+               /* Make sure dma is stopped */
+               PMacSilence();
+-              enable_irq(awacs_irq);
++              if (awacs)
++                      enable_irq(awacs_irq);
+               enable_irq(awacs_tx_irq);
+               enable_irq(awacs_rx_irq);
+-              /* OK, allow ints back again */
+-              out_le32(&awacs->control, MASK_IEPC
+-                      | (awacs_rate_index << 8) | 0x11
+-                       | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
++              if (awacs) {
++                      /* OK, allow ints back again */
++                      out_le32(&awacs->control, MASK_IEPC
++                              | (awacs_rate_index << 8) | 0x11
++                               | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
++              }
+               if (macio_base && is_pbook_g3) {
+                       /* FIXME: should restore the setup we had...*/
+                       out_8(macio_base + 0x37, 3);
+@@ -1384,7 +1533,9 @@
+               awacs_sleeping = 0;
+               /* Resume pending sounds. */
+               /* we don't try to restart input... */
++              spin_lock_irqsave(&dmasound.lock, flags);
+               __PMacPlay();
++              spin_unlock_irqrestore(&dmasound.lock, flags);
+               UNLOCK();
+       }
+       return PBOOK_SLEEP_OK;
+@@ -1956,7 +2107,7 @@
+       case SOUND_MIXER_READ_SPEAKER:
+               data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
+               data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
+-              rc = IOCTL_OUT(arg, ~data);
++              rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
+               break;
+       case SOUND_MIXER_WRITE_ALTPCM:  /* really bell volume */
+               IOCTL_IN(arg, data);
+@@ -2011,89 +2162,6 @@
+       return rc;
+ }
+-static int tumbler_mixer_ioctl(u_int cmd, u_long arg)
+-{
+-      int data;
+-      int rc;
+-
+-      /* We are, we are, we are... Tumbler (and very dumb) */
+-      /* Ok, we're not THAT dumb anymore, but still pretty dumb :-) */
+-
+-      switch(cmd) {
+-      case SOUND_MIXER_READ_DEVMASK:
+-              data =  SOUND_MASK_VOLUME | SOUND_MASK_ALTPCM |
+-                      SOUND_MASK_BASS | SOUND_MASK_TREBLE |
+-                      SOUND_MASK_PCM;
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_READ_RECMASK:
+-              data = 0;
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_READ_RECSRC:
+-              data = 0;
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_WRITE_RECSRC:
+-              IOCTL_IN(arg, data);
+-              data =0;
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_READ_STEREODEVS:
+-              data = SOUND_MASK_VOLUME | SOUND_MASK_PCM;
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_READ_CAPS:
+-              rc = IOCTL_OUT(arg, 0);
+-              break;
+-      case SOUND_MIXER_WRITE_BASS:
+-              IOCTL_IN(arg, data);
+-              tumbler_set_bass(data);
+-              /* Fall through */
+-      case SOUND_MIXER_READ_BASS:
+-              tumbler_get_bass(&data);
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_WRITE_TREBLE:
+-              IOCTL_IN(arg, data);
+-              tumbler_set_treble(data);
+-              /* Fall through */
+-      case SOUND_MIXER_READ_TREBLE:
+-              tumbler_get_treble(&data);
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_WRITE_PCM:
+-              IOCTL_IN(arg, data);
+-              tumbler_set_pcm_lvl(data);
+-              /* Fall through */
+-      case SOUND_MIXER_READ_PCM:
+-              tumbler_get_pcm_lvl(&data);
+-              IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_WRITE_VOLUME:
+-              IOCTL_IN(arg, data);
+-              tumbler_set_volume(data, data);
+-              /* Fall through */
+-      case SOUND_MIXER_READ_VOLUME:
+-              tumbler_get_volume(& data, &data);
+-              rc = IOCTL_OUT(arg, data);
+-              break;
+-      case SOUND_MIXER_WRITE_ALTPCM:  /* really bell volume */
+-              IOCTL_IN(arg, data);
+-              beep_vol = data & 0xff;
+-              /* fall through */
+-      case SOUND_MIXER_READ_ALTPCM:
+-              rc = IOCTL_OUT(arg, beep_vol);
+-              break;
+-      case SOUND_MIXER_OUTMASK:
+-      case SOUND_MIXER_OUTSRC:
+-      default:
+-              rc = -EINVAL;
+-      }
+-
+-      return rc;
+-}
+-
+ static int daca_mixer_ioctl(u_int cmd, u_long arg)
+ {
+       int data;
+@@ -2158,7 +2226,8 @@
+                       rc = daca_mixer_ioctl(cmd, arg);
+                       break;
+               case AWACS_TUMBLER:
+-                      rc = tumbler_mixer_ioctl(cmd, arg);
++              case AWACS_SNAPPER:
++                      rc = tas_mixer_ioctl(cmd, arg);
+                       break ;
+               default: /* ;-)) */
+                       rc = awacs_mixer_ioctl(cmd, arg);
+@@ -2175,7 +2244,9 @@
+               case AWACS_TUMBLER:
+                 printk("AE-Init tumbler mixer\n");
+                 break ;
+-                
++              case AWACS_SNAPPER:
++                printk("AE-Init snapper mixer\n");
++                break ;
+               case AWACS_DACA:
+               case AWACS_BURGUNDY:
+                       break ; /* don't know yet */
+@@ -2366,12 +2437,12 @@
+                       len += sprintf(b,"44100 ") ;
+                       break ;
+               case AWACS_TUMBLER:
+-                      for (i=0; i<2; i++){
+-                              if (tumbler_freqs_ok[i])
+-                                      len += sprintf(b+len,"%d ", tumbler_freqs[i]) ;
++              case AWACS_SNAPPER:
++                      for (i=0; i<1; i++){
++                              if (tas_freqs_ok[i])
++                                      len += sprintf(b+len,"%d ", tas_freqs[i]) ;
+                       }
+                       break ;
+-
+               case AWACS_AWACS:
+               case AWACS_SCREAMER:
+               default:
+@@ -2472,8 +2543,8 @@
+   code that looks for chip properties knows how to go about it.
+ */
+-static struct device_node
+-__init *get_snd_io_node(void)
++static struct device_node* __init
++get_snd_io_node(void)
+ {
+       struct device_node *np = NULL;
+@@ -2494,7 +2565,7 @@
+        * this seems to be what iBooks (& Tumbler) have.
+        */
+       if (np == NULL)
+-              np = find_devices("i2s-a");
++              np = i2s_node = find_devices("i2s-a");
+       /* if we didn't find this - perhaps we are on an early model
+        * which _only_ has an 'awacs' node
+@@ -2514,23 +2585,22 @@
+    we have to deduce the info other ways for these.
+ */
+-static struct device_node
+-__init *get_snd_info_node(struct device_node *io)
++static struct device_node* __init
++get_snd_info_node(struct device_node *io)
+ {
+       struct device_node *info;
+       info = find_devices("sound");
+-      while (info != 0 && info->parent != io)
++      while (info && info->parent != io)
+               info = info->next;
+-
+-      return info ;
++      return info;
+ }
+ /* Find out what type of codec we have.
+ */
+-static int
+-__init get_codec_type(struct device_node *info)
++static int __init
++get_codec_type(struct device_node *info)
+ {
+       /* already set if pre-davbus model and info will be NULL */
+       int codec = awacs_revision ;
+@@ -2547,14 +2617,16 @@
+                       codec = AWACS_DACA;
+               if (device_is_compatible(info, "tumbler"))
+                       codec = AWACS_TUMBLER;
++              if (device_is_compatible(info, "snapper"))
++                      codec = AWACS_SNAPPER;
+       }
+       return codec ;
+ }
+ /* find out what type, if any, of expansion card we have
+ */
+-static void
+-__init get_expansion_type(void)
++static void __init
++get_expansion_type(void)
+ {
+       if (find_devices("perch") != NULL)
+               has_perch = 1;
+@@ -2572,8 +2644,8 @@
+  *       Set dmasound.mach.max_dsp_rate on the basis of these routines.
+ */
+-static void
+-__init init_awacs_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++awacs_init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+       int i ;
+       if (prop) {
+@@ -2595,31 +2667,8 @@
+       /* else we assume that all the rates are available */
+ }
+-static void
+-__init init_tumbler_frame_rates(unsigned int *prop, unsigned int l)
+-{
+-      int i ;
+-      if (prop) {
+-              for (i=0; i<2; i++)
+-                      tumbler_freqs_ok[i] = 0;
+-              for (l /= sizeof(int); l > 0; --l) {
+-                      unsigned int r = *prop++;
+-                      /* Apple 'Fixed' format */
+-                      if (r >= 0x10000)
+-                              r >>= 16;
+-                      for (i = 0; i < 2; ++i) {
+-                              if (r == tumbler_freqs[i]) {
+-                                      tumbler_freqs_ok[i] = 1;
+-                                      break;
+-                              }
+-                      }
+-              }
+-      }
+-      /* else we assume that all the rates are available */
+-}
+-
+-static void
+-__init init_burgundy_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++burgundy_init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+       int temp[9] ;
+       int i = 0 ;
+@@ -2644,8 +2693,8 @@
+ #endif
+ }
+-static void
+-__init init_daca_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++daca_init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+       int temp[9] ;
+       int i = 0 ;
+@@ -2671,21 +2720,22 @@
+ #endif
+ }
+-static void
+-__init init_frame_rates(unsigned int *prop, unsigned int l)
++static void __init
++init_frame_rates(unsigned int *prop, unsigned int l)
+ {
+-      switch (awacs_revision){
++      switch (awacs_revision) {
+               case AWACS_TUMBLER:
+-                      init_tumbler_frame_rates(prop, l);
++              case AWACS_SNAPPER:
++                      tas_init_frame_rates(prop, l);
+                       break ;
+               case AWACS_DACA:
+-                      init_daca_frame_rates(prop, l);
++                      daca_init_frame_rates(prop, l);
+                       break ;
+               case AWACS_BURGUNDY:
+-                      init_burgundy_frame_rates(prop, l);
++                      burgundy_init_frame_rates(prop, l);
+                       break ;
+-              default: /* ;-))) */
+-                      init_awacs_frame_rates(prop, l);
++              default:
++                      awacs_init_frame_rates(prop, l);
+                       break ;
+       }
+ }
+@@ -2693,11 +2743,11 @@
+ /* find things/machines that can't do mac-io byteswap
+ */
+-static void
+-__init set_hw_byteswap(struct device_node *io)
++static void __init
++set_hw_byteswap(struct device_node *io)
+ {
+       struct device_node *mio ;
+-      unsigned int *p, kl = 0 ;
++      unsigned int kl = 0 ;
+       /* if seems that Keylargo can't byte-swap  */
+@@ -2744,9 +2794,6 @@
+               if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ;
+               return -ENOMEM ;
+       }
+-      /* OK, we should be safe to claim the mksound vector now */
+-      orig_mksound = kd_mksound;
+-      kd_mksound = awacs_mksound;
+       return 0 ;
+ }
+@@ -2842,23 +2889,26 @@
+       }
+       /* all OF versions I've seen use this value */
+-      awacs = (volatile struct awacs_regs *)
+-              ioremap(io->addrs[0].address, 0x1000);
++      if (i2s_node)
++              i2s = (u32 *)ioremap(io->addrs[0].address, 0x1000);
++      else
++              awacs = (volatile struct awacs_regs *)
++                      ioremap(io->addrs[0].address, 0x1000);
+       awacs_txdma = (volatile struct dbdma_regs *)
+               ioremap(io->addrs[1].address, 0x100);
+       awacs_rxdma = (volatile struct dbdma_regs *)
+               ioremap(io->addrs[2].address, 0x100);
+-#ifdef CONFIG_PMAC_PBOOK
+       /* first of all make sure that the chip is powered up....*/
+       pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
+-      if (awacs_revision == AWACS_SCREAMER)
++      if (awacs_revision == AWACS_SCREAMER && awacs)
+               awacs_recalibrate();
+-#endif
++
+       awacs_irq = io->intrs[0].line;
+       awacs_tx_irq = io->intrs[1].line;
+       awacs_rx_irq = io->intrs[2].line;
++      /* Hack for legacy crap that will be killed someday */
+       awacs_node = io;
+       /* if we have an awacs or screamer - probe the chip to make
+@@ -2909,8 +2959,9 @@
+               /* if it's there use it to set up frame rates */
+               init_frame_rates(prop, l) ;
+       }
+-      
+-      out_le32(&awacs->control, 0x11); /* set everything quiesent */
++
++      if (awacs)
++              out_le32(&awacs->control, 0x11); /* set everything quiesent */
+       set_hw_byteswap(io) ; /* figure out if the h/w can do it */
+@@ -2942,25 +2993,27 @@
+       switch (awacs_revision) {
+               case AWACS_TUMBLER:
+-#ifdef CONFIG_KMOD
+-                      request_module("i2c-keywest");
+-#endif /* CONFIG_KMOD */      
+-                      awacs_tumbler_init();
+-                      tas_init();
+-                      break ;
++                        tas_register_driver(&tas3001c_hooks);
++                      tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
++                      tas_dmasound_init();
++                      tas_post_init();
++                      break ;
++              case AWACS_SNAPPER:
++                        tas_register_driver(&tas3004_hooks);
++                      tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
++                      tas_dmasound_init();
++                      tas_post_init();
++                      break;
+               case AWACS_DACA:
+-#ifdef CONFIG_KMOD
+-                      request_module("i2c-keywest");
+-#endif /* CONFIG_KMOD */
+                       daca_init();
+-                      break ;         /* don't know how yet */
++                      break;  
+               case AWACS_BURGUNDY:
+                       awacs_burgundy_init();
+                       break ;
+               case AWACS_SCREAMER:
+               case AWACS_AWACS:
+               default:
+-                      load_awacs() ;
++                      load_awacs();
+                       break ;
+       }
+@@ -3031,11 +3084,15 @@
+               dmasound.mach.hardware_afmts = AFMT_S16_BE ;
+       /* shut out chips that do output only.
+-         may need to extend this to machines which have no inputs - even tho'
+-         they use screamer - IIRC one of the powerbooks is like this.
+-      */
++       * may need to extend this to machines which have no inputs - even tho'
++       * they use screamer - IIRC one of the powerbooks is like this.
++       *
++       * FIXME: Actually, some TUMBLER and SNAPPER do have inputs...  
++       */
+-      if (awacs_revision != AWACS_TUMBLER && awacs_revision != AWACS_DACA) {
++      if (awacs_revision != AWACS_TUMBLER &&
++            awacs_revision != AWACS_SNAPPER &&
++            awacs_revision != AWACS_DACA) {
+               dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
+               dmasound.mach.record = PMacRecord ;
+       }
+@@ -3053,6 +3110,9 @@
+               case AWACS_TUMBLER:
+                       sprintf(awacs_name, "PowerMac Tumbler ") ;
+                       break ;
++              case AWACS_SNAPPER:
++                      sprintf(awacs_name, "PowerMac Snapper ") ;
++                      break ;
+               case AWACS_SCREAMER:
+                       sprintf(awacs_name, "PowerMac Screamer ") ;
+                       break ;
+@@ -3069,7 +3129,8 @@
+ {
+       switch (awacs_revision) {
+               case AWACS_TUMBLER:
+-                      awacs_tumbler_cleanup();
++              case AWACS_SNAPPER:
++                      tas_dmasound_cleanup();
+                       tas_cleanup();
+                       break ;
+               case AWACS_DACA:
+Index: linux-2.6.0-test5/sound/oss/dmasound/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/Kconfig  2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/Kconfig       2003-09-27 11:38:42.454074384 +0800
+@@ -12,9 +12,9 @@
+         want). If you want to compile it as a module, say M here and read
+         <file:Documentation/modules.txt>.
+-config DMASOUND_AWACS
++config DMASOUND_PMAC
+       tristate "PowerMac DMA sound support"
+-      depends on PPC_PMAC && SOUND
++      depends on PPC_PMAC && SOUND && I2C
+       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,
+Index: linux-2.6.0-test5/sound/oss/dmasound/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/Makefile 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/Makefile      2003-09-27 11:38:42.455074232 +0800
+@@ -2,7 +2,12 @@
+ # Makefile for the DMA sound driver
+ #
+-obj-$(CONFIG_DMASOUND_ATARI)  += dmasound_core.o dmasound_atari.o
+-obj-$(CONFIG_DMASOUND_AWACS)  += dmasound_core.o dmasound_awacs.o
+-obj-$(CONFIG_DMASOUND_PAULA)  += dmasound_core.o dmasound_paula.o
+-obj-$(CONFIG_DMASOUND_Q40)    += dmasound_core.o dmasound_q40.o
++dmasound_pmac-y                       += dmasound_awacs.o \
++                                 trans_16.o dac3550a.o tas_common.o \
++                                 tas3001c.o tas3001c_tables.o \
++                                 tas3004.o tas3004_tables.o
++
++obj-$(CONFIG_DMASOUND_ATARI)  += dmasound_core.o dmasound_atari.o
++obj-$(CONFIG_DMASOUND_PMAC)   += dmasound_core.o dmasound_pmac.o
++obj-$(CONFIG_DMASOUND_PAULA)  += dmasound_core.o dmasound_paula.o
++obj-$(CONFIG_DMASOUND_Q40)    += dmasound_core.o dmasound_q40.o
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3001c.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3001c.c       2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3001c.c    2003-09-27 11:38:42.457073928 +0800
+@@ -0,0 +1,861 @@
++/*
++ * Driver for the i2c/i2s based TA3004 sound chip used
++ * on some Apple hardware. Also known as "snapper".
++ *
++ * Tobias Sargeant <tobias.sargeant@bigpond.com>
++ * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
++ *
++ *   TODO:
++ *   -----
++ *   * Enable control over input line 2 (is this connected?)
++ *   * Implement sleep support (at least mute everything and
++ *   * set gains to minimum during sleep)
++ *   * Look into some of Darwin's tweaks regarding the mute
++ *   * lines (delays & different behaviour on some HW)
++ *
++ */
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/soundcard.h>
++#include <linux/workqueue.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++
++#include "dmasound.h"
++#include "tas_common.h"
++#include "tas3001c.h"
++
++#include "tas_ioctl.h"
++
++#define TAS3001C_BIQUAD_FILTER_COUNT  6
++#define TAS3001C_BIQUAD_CHANNEL_COUNT 2
++
++#define VOL_DEFAULT   (100 * 4 / 5)
++#define INPUT_DEFAULT (100 * 4 / 5)
++#define BASS_DEFAULT  (100 / 2)
++#define TREBLE_DEFAULT        (100 / 2)
++
++struct tas3001c_data_t {
++      struct tas_data_t super;
++      int device_id;
++      int output_id;
++      int speaker_id;
++      struct tas_drce_t drce_state;
++};
++
++
++static const union tas_biquad_t
++tas3001c_eq_unity={
++      buf: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
++};
++
++
++static inline unsigned char db_to_regval(short db) {
++      int r=0;
++
++      r=(db+0x59a0) / 0x60;
++
++      if (r < 0x91) return 0x91;
++      if (r > 0xef) return 0xef;
++      return r;
++}
++
++static inline short quantize_db(short db) {
++      return db_to_regval(db) * 0x60 - 0x59a0;
++}
++
++
++static inline int
++register_width(enum tas3001c_reg_t r)
++{
++      switch(r) {
++      case TAS3001C_REG_MCR:
++      case TAS3001C_REG_TREBLE:
++      case TAS3001C_REG_BASS:
++              return 1;
++
++      case TAS3001C_REG_DRC:
++              return 2;
++
++      case TAS3001C_REG_MIXER1:
++      case TAS3001C_REG_MIXER2:
++              return 3;
++
++      case TAS3001C_REG_VOLUME:
++              return 6;
++
++      case TAS3001C_REG_LEFT_BIQUAD0:
++      case TAS3001C_REG_LEFT_BIQUAD1:
++      case TAS3001C_REG_LEFT_BIQUAD2:
++      case TAS3001C_REG_LEFT_BIQUAD3:
++      case TAS3001C_REG_LEFT_BIQUAD4:
++      case TAS3001C_REG_LEFT_BIQUAD5:
++      case TAS3001C_REG_LEFT_BIQUAD6:
++
++      case TAS3001C_REG_RIGHT_BIQUAD0:
++      case TAS3001C_REG_RIGHT_BIQUAD1:
++      case TAS3001C_REG_RIGHT_BIQUAD2:
++      case TAS3001C_REG_RIGHT_BIQUAD3:
++      case TAS3001C_REG_RIGHT_BIQUAD4:
++      case TAS3001C_REG_RIGHT_BIQUAD5:
++      case TAS3001C_REG_RIGHT_BIQUAD6:
++              return 15;
++
++      default:
++              return 0;
++      }
++}
++
++static int
++tas3001c_write_register(      struct tas3001c_data_t *self,
++                              enum tas3001c_reg_t reg_num,
++                              char *data,
++                              uint write_mode)
++{
++      if (reg_num==TAS3001C_REG_MCR ||
++          reg_num==TAS3001C_REG_BASS ||
++          reg_num==TAS3001C_REG_TREBLE) {
++              return tas_write_byte_register(&self->super,
++                                             (uint)reg_num,
++                                             *data,
++                                             write_mode);
++      } else {
++              return tas_write_register(&self->super,
++                                        (uint)reg_num,
++                                        register_width(reg_num),
++                                        data,
++                                        write_mode);
++      }
++}
++
++static int
++tas3001c_sync_register(       struct tas3001c_data_t *self,
++                      enum tas3001c_reg_t reg_num)
++{
++      if (reg_num==TAS3001C_REG_MCR ||
++          reg_num==TAS3001C_REG_BASS ||
++          reg_num==TAS3001C_REG_TREBLE) {
++              return tas_sync_byte_register(&self->super,
++                                            (uint)reg_num,
++                                            register_width(reg_num));
++      } else {
++              return tas_sync_register(&self->super,
++                                       (uint)reg_num,
++                                       register_width(reg_num));
++      }
++}
++
++static int
++tas3001c_read_register(       struct tas3001c_data_t *self,
++                      enum tas3001c_reg_t reg_num,
++                      char *data,
++                      uint write_mode)
++{
++      return tas_read_register(&self->super,
++                               (uint)reg_num,
++                               register_width(reg_num),
++                               data);
++}
++
++static inline int
++tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
++{
++      if (fast)
++              self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
++      else
++              self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
++      return tas3001c_sync_register(self,TAS3001C_REG_MCR);
++}
++
++static uint
++tas3001c_supported_mixers(struct tas3001c_data_t *self)
++{
++      return SOUND_MASK_VOLUME |
++              SOUND_MASK_PCM |
++              SOUND_MASK_ALTPCM |
++              SOUND_MASK_TREBLE |
++              SOUND_MASK_BASS;
++}
++
++static int
++tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
++{
++      switch(mixer) {
++      case SOUND_MIXER_VOLUME:
++              return 1;
++      default:
++              return 0;
++      }
++}
++
++static uint
++tas3001c_stereo_mixers(struct tas3001c_data_t *self)
++{
++      uint r=tas3001c_supported_mixers(self);
++      uint i;
++      
++      for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
++              if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
++                      r &= ~(1<<i);
++      return r;
++}
++
++static int
++tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
++{
++      if (!self)
++              return -1;
++              
++      *level=self->super.mixer[mixer];
++      
++      return 0;
++}
++
++static int
++tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
++{
++      int rc;
++      tas_shadow_t *shadow;
++
++      uint temp;
++      uint offset=0;
++
++      if (!self)
++              return -1;
++              
++      shadow=self->super.shadow;
++
++      if (!tas3001c_mixer_is_stereo(self,mixer))
++              level = tas_mono_to_stereo(level);
++
++      switch(mixer) {
++      case SOUND_MIXER_VOLUME:
++              temp = tas3001c_gain.master[level&0xff];
++              shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
++              shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8)  & 0xff;
++              shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0)  & 0xff;
++              temp = tas3001c_gain.master[(level>>8)&0xff];
++              shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
++              shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8)  & 0xff;
++              shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0)  & 0xff;
++              rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++              break;
++      case SOUND_MIXER_ALTPCM:
++              /* tas3001c_fast_load(self, 1); */
++              level = tas_mono_to_stereo(level);
++              temp = tas3001c_gain.mixer[level&0xff];
++              shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
++              shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8)  & 0xff;
++              shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0)  & 0xff;
++              rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++              /* tas3001c_fast_load(self, 0); */
++              break;
++      case SOUND_MIXER_PCM:
++              /* tas3001c_fast_load(self, 1); */
++              level = tas_mono_to_stereo(level);
++              temp = tas3001c_gain.mixer[level&0xff];
++              shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
++              shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8)  & 0xff;
++              shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0)  & 0xff;
++              rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++              /* tas3001c_fast_load(self, 0); */
++              break;
++      case SOUND_MIXER_TREBLE:
++              temp = tas3001c_gain.treble[level&0xff];
++              shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
++              rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++              break;
++      case SOUND_MIXER_BASS:
++              temp = tas3001c_gain.bass[level&0xff];
++              shadow[TAS3001C_REG_BASS][0]=temp&0xff;
++              rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
++              break;
++      default:
++              rc = -1;
++              break;
++      }
++      if (rc < 0)
++              return rc;
++      self->super.mixer[mixer]=level;
++      return 0;
++}
++
++static int
++tas3001c_leave_sleep(struct tas3001c_data_t *self)
++{
++      unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++      if (!self)
++              return -1;
++
++      /* Make sure something answers on the i2c bus */
++      if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
++          WRITE_NORMAL|FORCE_WRITE) < 0)
++              return -1;
++
++      tas3001c_fast_load(self, 1);
++
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
++
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
++
++      tas3001c_fast_load(self, 0);
++
++      (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++
++      return 0;
++}
++
++static int
++tas3001c_enter_sleep(struct tas3001c_data_t *self)
++{
++      /* Stub for now, but I have the details on low-power mode */
++      if (!self)
++              return -1; 
++      return 0;
++}
++
++static int
++tas3001c_sync_biquad( struct tas3001c_data_t *self,
++                      u_int channel,
++                      u_int filter)
++{
++      enum tas3001c_reg_t reg;
++
++      if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
++          filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++      reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
++
++      return tas3001c_sync_register(self,reg);
++}
++
++static int
++tas3001c_write_biquad_shadow( struct tas3001c_data_t *self,
++                              u_int channel,
++                              u_int filter,
++                              const union tas_biquad_t *biquad)
++{
++      tas_shadow_t *shadow=self->super.shadow;
++      enum tas3001c_reg_t reg;
++
++      if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
++          filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++      reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
++
++      SET_4_20(shadow[reg], 0,biquad->coeff.b0);
++      SET_4_20(shadow[reg], 3,biquad->coeff.b1);
++      SET_4_20(shadow[reg], 6,biquad->coeff.b2);
++      SET_4_20(shadow[reg], 9,biquad->coeff.a1);
++      SET_4_20(shadow[reg],12,biquad->coeff.a2);
++
++      return 0;
++}
++
++static int
++tas3001c_write_biquad(        struct tas3001c_data_t *self,
++                      u_int channel,
++                      u_int filter,
++                      const union tas_biquad_t *biquad)
++{
++      int rc;
++
++      rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
++      if (rc < 0) return rc;
++
++      return tas3001c_sync_biquad(self, channel, filter);
++}
++
++static int
++tas3001c_write_biquad_list(   struct tas3001c_data_t *self,
++                              u_int filter_count,
++                              u_int flags,
++                              struct tas_biquad_ctrl_t *biquads)
++{
++      int i;
++      int rc;
++
++      if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
++
++      for (i=0; i<filter_count; i++) {
++              rc=tas3001c_write_biquad(self,
++                                       biquads[i].channel,
++                                       biquads[i].filter,
++                                       &biquads[i].data);
++              if (rc < 0) break;
++      }
++
++      if (flags & TAS_BIQUAD_FAST_LOAD) {
++              tas3001c_fast_load(self,0);
++
++              (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++      }
++
++      return rc;
++}
++
++static int
++tas3001c_read_biquad( struct tas3001c_data_t *self,
++                      u_int channel,
++                      u_int filter,
++                      union tas_biquad_t *biquad)
++{
++      tas_shadow_t *shadow=self->super.shadow;
++      enum tas3001c_reg_t reg;
++
++      if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
++          filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++      reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
++
++      biquad->coeff.b0=GET_4_20(shadow[reg], 0);
++      biquad->coeff.b1=GET_4_20(shadow[reg], 3);
++      biquad->coeff.b2=GET_4_20(shadow[reg], 6);
++      biquad->coeff.a1=GET_4_20(shadow[reg], 9);
++      biquad->coeff.a2=GET_4_20(shadow[reg],12);
++      
++      return 0;       
++}
++
++static int
++tas3001c_eq_rw(       struct tas3001c_data_t *self,
++              u_int cmd,
++              u_long arg)
++{
++      int rc;
++      struct tas_biquad_ctrl_t biquad;
++
++      if (copy_from_user((void *)&biquad, (const void *)arg, sizeof(struct tas_biquad_ctrl_t))) {
++              return -EFAULT;
++      }
++
++      if (cmd & SIOC_IN) {
++              rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++              if (rc != 0) return rc;
++      }
++
++      if (cmd & SIOC_OUT) {
++              rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++              if (rc != 0) return rc;
++
++              if (copy_to_user((void *)arg, (const void *)&biquad, sizeof(struct tas_biquad_ctrl_t))) {
++                      return -EFAULT;
++              }
++
++      }
++      return 0;
++}
++
++static int
++tas3001c_eq_list_rw(  struct tas3001c_data_t *self,
++                      u_int cmd,
++                      u_long arg)
++{
++      int rc;
++      int filter_count;
++      int flags;
++      int i,j;
++      char sync_required[2][6];
++      struct tas_biquad_ctrl_t biquad;
++
++      memset(sync_required,0,sizeof(sync_required));
++
++      if (copy_from_user((void *)&filter_count,
++                         (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,filter_count),
++                         sizeof(int))) {
++              return -EFAULT;
++      }
++
++      if (copy_from_user((void *)&flags,
++                         (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,flags),
++                         sizeof(int))) {
++              return -EFAULT;
++      }
++
++      if (cmd & SIOC_IN) {
++      }
++
++      for (i=0; i < filter_count; i++) {
++              if (copy_from_user((void *)&biquad,
++                                 (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++                                 sizeof(struct tas_biquad_ctrl_t))) {
++                      return -EFAULT;
++              }
++
++              if (cmd & SIOC_IN) {
++                      sync_required[biquad.channel][biquad.filter]=1;
++                      rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
++                      if (rc != 0) return rc;
++              }
++
++              if (cmd & SIOC_OUT) {
++                      rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++                      if (rc != 0) return rc;
++
++                      if (copy_to_user((void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++                                       (const void *)&biquad,
++                                       sizeof(struct tas_biquad_ctrl_t))) {
++                              return -EFAULT;
++                      }
++              }
++      }
++
++      if (cmd & SIOC_IN) {
++              if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
++              for (i=0; i<2; i++) {
++                      for (j=0; j<6; j++) {
++                              if (sync_required[i][j]) {
++                                      rc=tas3001c_sync_biquad(self, i, j);
++                                      if (rc < 0) return rc;
++                              }
++                      }
++              }
++              if (flags & TAS_BIQUAD_FAST_LOAD) {
++                      tas3001c_fast_load(self,0);
++                      /* now we need to set up the mixers again,
++                         because leaving fast mode resets them. */
++                      (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++                      (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++                      (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++                      (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++                      (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++              }
++      }
++
++      return 0;
++}
++
++static int
++tas3001c_update_drce( struct tas3001c_data_t *self,
++                      int flags,
++                      struct tas_drce_t *drce)
++{
++      tas_shadow_t *shadow;
++      shadow=self->super.shadow;
++
++      shadow[TAS3001C_REG_DRC][1] = 0xc1;
++
++      if (flags & TAS_DRCE_THRESHOLD) {
++              self->drce_state.threshold=quantize_db(drce->threshold);
++              shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
++      }
++
++      if (flags & TAS_DRCE_ENABLE) {
++              self->drce_state.enable = drce->enable;
++      }
++
++      if (!self->drce_state.enable) {
++              shadow[TAS3001C_REG_DRC][0] = 0xf0;
++      }
++
++#ifdef DEBUG_DRCE
++      printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
++             self->drce_state.enable,
++             self->drce_state.threshold);
++
++      printk("DRCE IOCTL: reg [ %02x %02x ]\n",
++             (unsigned char)shadow[TAS3001C_REG_DRC][0],
++             (unsigned char)shadow[TAS3001C_REG_DRC][1]);
++#endif
++
++      return tas3001c_sync_register(self, TAS3001C_REG_DRC);
++}
++
++static int
++tas3001c_drce_rw(     struct tas3001c_data_t *self,
++                      u_int cmd,
++                      u_long arg)
++{
++      int rc;
++      struct tas_drce_ctrl_t drce_ctrl;
++
++      if (copy_from_user((void *)&drce_ctrl,
++                         (const void *)arg,
++                         sizeof(struct tas_drce_ctrl_t))) {
++              return -EFAULT;
++      }
++
++#ifdef DEBUG_DRCE
++      printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
++             drce_ctrl.flags,
++             drce_ctrl.data.enable,
++             drce_ctrl.data.threshold);
++#endif
++
++      if (cmd & SIOC_IN) {
++              rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
++              if (rc < 0)
++                      return rc;
++      }
++
++      if (cmd & SIOC_OUT) {
++              if (drce_ctrl.flags & TAS_DRCE_ENABLE)
++                      drce_ctrl.data.enable = self->drce_state.enable;
++
++              if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
++                      drce_ctrl.data.threshold = self->drce_state.threshold;
++
++              if (copy_to_user((void *)arg,
++                               (const void *)&drce_ctrl,
++                               sizeof(struct tas_drce_ctrl_t))) {
++                      return -EFAULT;
++              }
++      }
++
++      return 0;
++}
++
++static void
++tas3001c_update_device_parameters(struct tas3001c_data_t *self)
++{
++      int i,j;
++
++      if (!self) return;
++
++      if (self->output_id == TAS_OUTPUT_HEADPHONES) {
++              tas3001c_fast_load(self, 1);
++
++              for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
++                      for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
++                              tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
++                      }
++              }
++
++              tas3001c_fast_load(self, 0);
++
++              (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
++              (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
++
++              return;
++      }
++
++      for (i=0; tas3001c_eq_prefs[i]; i++) {
++              struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
++
++              if (eq->device_id == self->device_id &&
++                  (eq->output_id == 0 || eq->output_id == self->output_id) &&
++                  (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
++
++                      tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
++                      tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
++
++                      break;
++              }
++      }
++}
++
++static void
++tas3001c_device_change_handler(void *self)
++{
++      if (self)
++              tas3001c_update_device_parameters(self);
++}
++
++static struct work_struct device_change;
++
++static int
++tas3001c_output_device_change(        struct tas3001c_data_t *self,
++                              int device_id,
++                              int output_id,
++                              int speaker_id)
++{
++      self->device_id=device_id;
++      self->output_id=output_id;
++      self->speaker_id=speaker_id;
++
++      schedule_work(&device_change);
++      return 0;
++}
++
++static int
++tas3001c_device_ioctl(        struct tas3001c_data_t *self,
++                      u_int cmd,
++                      u_long arg)
++{
++      switch (cmd) {
++      case TAS_READ_EQ:
++      case TAS_WRITE_EQ:
++              return tas3001c_eq_rw(self, cmd, arg);
++
++      case TAS_READ_EQ_LIST:
++      case TAS_WRITE_EQ_LIST:
++              return tas3001c_eq_list_rw(self, cmd, arg);
++
++      case TAS_READ_EQ_FILTER_COUNT:
++              put_user(TAS3001C_BIQUAD_FILTER_COUNT, (uint *)(arg));
++              return 0;
++
++      case TAS_READ_EQ_CHANNEL_COUNT:
++              put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, (uint *)(arg));
++              return 0;
++
++      case TAS_READ_DRCE:
++      case TAS_WRITE_DRCE:
++              return tas3001c_drce_rw(self, cmd, arg);
++
++      case TAS_READ_DRCE_CAPS:
++              put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, (uint *)(arg));
++              return 0;
++
++      case TAS_READ_DRCE_MIN:
++      case TAS_READ_DRCE_MAX: {
++              struct tas_drce_ctrl_t drce_ctrl;
++
++              if (copy_from_user((void *)&drce_ctrl,
++                                 (const void *)arg,
++                                 sizeof(struct tas_drce_ctrl_t))) {
++                      return -EFAULT;
++              }
++
++              if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
++                      if (cmd == TAS_READ_DRCE_MIN) {
++                              drce_ctrl.data.threshold=-36<<8;
++                      } else {
++                              drce_ctrl.data.threshold=-6<<8;
++                      }
++              }
++
++              if (copy_to_user((void *)arg,
++                               (const void *)&drce_ctrl,
++                               sizeof(struct tas_drce_ctrl_t))) {
++                      return -EFAULT;
++              }
++      }
++      }
++
++      return -EINVAL;
++}
++
++static int
++tas3001c_init_mixer(struct tas3001c_data_t *self)
++{
++      unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++      /* Make sure something answers on the i2c bus */
++      if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
++          WRITE_NORMAL|FORCE_WRITE) < 0)
++              return -1;
++
++      tas3001c_fast_load(self, 1);
++
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
++
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
++      (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
++
++      tas3001c_fast_load(self, 0);
++
++      tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
++      tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
++      tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++
++      tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
++      tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
++
++      return 0;
++}
++
++static int
++tas3001c_uninit_mixer(struct tas3001c_data_t *self)
++{
++      tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
++      tas3001c_set_mixer_level(self, SOUND_MIXER_PCM,    0);
++      tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++
++      tas3001c_set_mixer_level(self, SOUND_MIXER_BASS,   0);
++      tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
++
++      return 0;
++}
++
++static int
++tas3001c_init(struct i2c_client *client)
++{
++      struct tas3001c_data_t *self;
++      size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
++      int i, j;
++
++      self = kmalloc(sz, GFP_KERNEL);
++      if (!self)
++              return -ENOMEM;
++      memset(self, 0, sz);
++
++      self->super.client = client;
++      self->super.shadow = (tas_shadow_t *)(self+1);
++      self->output_id = TAS_OUTPUT_HEADPHONES;
++
++      dev_set_drvdata(&client->dev, self);
++
++      for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
++              for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
++                      tas3001c_write_biquad_shadow(self, i, j,
++                              &tas3001c_eq_unity);
++
++      INIT_WORK(&device_change, tas3001c_device_change_handler, self);
++      return 0;
++}
++
++static void
++tas3001c_uninit(struct tas3001c_data_t *self)
++{
++      tas3001c_uninit_mixer(self);
++      kfree(self);
++}
++
++struct tas_driver_hooks_t tas3001c_hooks = {
++      .init                   = (tas_hook_init_t)tas3001c_init,
++      .post_init              = (tas_hook_post_init_t)tas3001c_init_mixer,
++      .uninit                 = (tas_hook_uninit_t)tas3001c_uninit,
++      .get_mixer_level        = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
++      .set_mixer_level        = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
++      .enter_sleep            = (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
++      .leave_sleep            = (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
++      .supported_mixers       = (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
++      .mixer_is_stereo        = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
++      .stereo_mixers          = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
++      .output_device_change   = (tas_hook_output_device_change_t)tas3001c_output_device_change,
++      .device_ioctl           = (tas_hook_device_ioctl_t)tas3001c_device_ioctl
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3001c.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3001c.h       2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3001c.h    2003-09-27 11:38:42.458073776 +0800
+@@ -0,0 +1,64 @@
++/*
++ * Header file for the i2c/i2s based TA3001c sound chip used
++ * on some Apple hardware. Also known as "tumbler".
++ *
++ *  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 Christopher C. Chimelis <chris@debian.org>
++ */
++
++#ifndef _TAS3001C_H_
++#define _TAS3001C_H_
++
++#include <linux/types.h>
++
++#include "tas_common.h"
++#include "tas_eq_prefs.h"
++
++/*
++ * Macros that correspond to the registers that we write to
++ * when setting the various values.
++ */
++
++#define TAS3001C_VERSION      "0.3"
++#define TAS3001C_DATE         "20011214"
++
++#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION
++#define I2C_DRIVERID_TAS3001C   (I2C_DRIVERID_TAS_BASE+0)
++
++extern  struct tas_driver_hooks_t tas3001c_hooks;
++extern struct tas_gain_t tas3001c_gain;
++extern struct tas_eq_pref_t *tas3001c_eq_prefs[];
++
++enum tas3001c_reg_t {
++  TAS3001C_REG_MCR                    = 0x01,
++  TAS3001C_REG_DRC                    = 0x02,
++
++  TAS3001C_REG_VOLUME                 = 0x04,
++  TAS3001C_REG_TREBLE                 = 0x05,
++  TAS3001C_REG_BASS                   = 0x06,
++  TAS3001C_REG_MIXER1                 = 0x07,
++  TAS3001C_REG_MIXER2                 = 0x08,
++
++  TAS3001C_REG_LEFT_BIQUAD0           = 0x0a,
++  TAS3001C_REG_LEFT_BIQUAD1           = 0x0b,
++  TAS3001C_REG_LEFT_BIQUAD2           = 0x0c,
++  TAS3001C_REG_LEFT_BIQUAD3           = 0x0d,
++  TAS3001C_REG_LEFT_BIQUAD4           = 0x0e,
++  TAS3001C_REG_LEFT_BIQUAD5           = 0x0f,
++  TAS3001C_REG_LEFT_BIQUAD6           = 0x10,
++  
++  TAS3001C_REG_RIGHT_BIQUAD0          = 0x13,
++  TAS3001C_REG_RIGHT_BIQUAD1          = 0x14,
++  TAS3001C_REG_RIGHT_BIQUAD2          = 0x15,
++  TAS3001C_REG_RIGHT_BIQUAD3          = 0x16,
++  TAS3001C_REG_RIGHT_BIQUAD4          = 0x17,
++  TAS3001C_REG_RIGHT_BIQUAD5          = 0x18,
++  TAS3001C_REG_RIGHT_BIQUAD6          = 0x19,
++
++  TAS3001C_REG_MAX                    = 0x20
++};
++
++#endif /* _TAS3001C_H_ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3001c_tables.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3001c_tables.c        2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3001c_tables.c     2003-09-27 11:38:42.459073624 +0800
+@@ -0,0 +1,375 @@
++#include "tas_common.h"
++#include "tas_eq_prefs.h"
++
++static struct tas_drce_t eqp_0e_2_1_drce = {
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -15.33  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++};
++
++static struct tas_eq_pref_t eqp_0e_2_1 = {
++  sample_rate:  44100,
++  device_id:    0x0e,
++  output_id:    TAS_OUTPUT_EXTERNAL_SPKR,
++  speaker_id:   0x01,
++
++  drce:         &eqp_0e_2_1_drce,
++
++  filter_count: 12,
++  biquads:      eqp_0e_2_1_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_10_1_0_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -12.46  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++};
++
++static struct tas_eq_pref_t eqp_10_1_0 = {
++  sample_rate:  44100,
++  device_id:    0x10,
++  output_id:    TAS_OUTPUT_INTERNAL_SPKR,
++  speaker_id:   0x00,
++
++  drce:         &eqp_10_1_0_drce,
++
++  filter_count: 12,
++  biquads:      eqp_10_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_15_2_1_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -15.33  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++};
++
++static struct tas_eq_pref_t eqp_15_2_1 = {
++  sample_rate:  44100,
++  device_id:    0x15,
++  output_id:    TAS_OUTPUT_EXTERNAL_SPKR,
++  speaker_id:   0x01,
++
++  drce:         &eqp_15_2_1_drce,
++
++  filter_count: 12,
++  biquads:      eqp_15_2_1_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_15_1_0_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: 0.0     * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
++};
++
++static struct tas_eq_pref_t eqp_15_1_0 = {
++  sample_rate:  44100,
++  device_id:    0x15,
++  output_id:    TAS_OUTPUT_INTERNAL_SPKR,
++  speaker_id:   0x00,
++
++  drce:         &eqp_15_1_0_drce,
++
++  filter_count: 12,
++  biquads:      eqp_15_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_0f_2_1_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -15.33  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
++};
++
++static struct tas_eq_pref_t eqp_0f_2_1 = {
++  sample_rate:  44100,
++  device_id:    0x0f,
++  output_id:    TAS_OUTPUT_EXTERNAL_SPKR,
++  speaker_id:   0x01,
++
++  drce:         &eqp_0f_2_1_drce,
++
++  filter_count: 12,
++  biquads:      eqp_0f_2_1_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_0f_1_0_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -15.33  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
++};
++
++static struct tas_eq_pref_t eqp_0f_1_0 = {
++  sample_rate:  44100,
++  device_id:    0x0f,
++  output_id:    TAS_OUTPUT_INTERNAL_SPKR,
++  speaker_id:   0x00,
++
++  drce:         &eqp_0f_1_0_drce,
++
++  filter_count: 12,
++  biquads:      eqp_0f_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static uint tas3001c_master_tab[]={
++             0x0,       0x75,       0x9c,       0xbb,
++            0xdb,       0xfb,      0x11e,      0x143,
++           0x16b,      0x196,      0x1c3,      0x1f5,
++           0x229,      0x263,      0x29f,      0x2e1,
++           0x328,      0x373,      0x3c5,      0x41b,
++           0x478,      0x4dc,      0x547,      0x5b8,
++           0x633,      0x6b5,      0x740,      0x7d5,
++           0x873,      0x91c,      0x9d2,      0xa92,
++           0xb5e,      0xc39,      0xd22,      0xe19,
++           0xf20,     0x1037,     0x1161,     0x129e,
++          0x13ed,     0x1551,     0x16ca,     0x185d,
++          0x1a08,     0x1bcc,     0x1dac,     0x1fa7,
++          0x21c1,     0x23fa,     0x2655,     0x28d6,
++          0x2b7c,     0x2e4a,     0x3141,     0x3464,
++          0x37b4,     0x3b35,     0x3ee9,     0x42d3,
++          0x46f6,     0x4b53,     0x4ff0,     0x54ce,
++          0x59f2,     0x5f5f,     0x6519,     0x6b24,
++          0x7183,     0x783c,     0x7f53,     0x86cc,
++          0x8ead,     0x96fa,     0x9fba,     0xa8f2,
++          0xb2a7,     0xbce1,     0xc7a5,     0xd2fa,
++          0xdee8,     0xeb75,     0xf8aa,    0x1068e,
++         0x1152a,    0x12487,    0x134ad,    0x145a5,
++         0x1577b,    0x16a37,    0x17df5,    0x192bd,
++         0x1a890,    0x1bf7b,    0x1d78d,    0x1f0d1,
++         0x20b55,    0x22727,    0x24456,    0x262f2,
++         0x2830b
++};
++
++static uint tas3001c_mixer_tab[]={
++             0x0,      0x748,      0x9be,      0xbaf,
++           0xda4,      0xfb1,     0x11de,     0x1431,
++          0x16ad,     0x1959,     0x1c37,     0x1f4b,
++          0x2298,     0x2628,     0x29fb,     0x2e12,
++          0x327d,     0x3734,     0x3c47,     0x41b4,
++          0x4787,     0x4dbe,     0x546d,     0x5b86,
++          0x632e,     0x6b52,     0x7400,     0x7d54,
++          0x873b,     0x91c6,     0x9d1a,     0xa920,
++          0xb5e5,     0xc38c,     0xd21b,     0xe18f,
++          0xf1f5,    0x1036a,    0x1160f,    0x129d6,
++         0x13ed0,    0x1550c,    0x16ca0,    0x185c9,
++         0x1a07b,    0x1bcc3,    0x1dab9,    0x1fa75,
++         0x21c0f,    0x23fa3,    0x26552,    0x28d64,
++         0x2b7c9,    0x2e4a2,    0x31411,    0x3463b,
++         0x37b44,    0x3b353,    0x3ee94,    0x42d30,
++         0x46f55,    0x4b533,    0x4fefc,    0x54ce5,
++         0x59f25,    0x5f5f6,    0x65193,    0x6b23c,
++         0x71835,    0x783c3,    0x7f52c,    0x86cc0,
++         0x8eacc,    0x96fa5,    0x9fba0,    0xa8f1a,
++         0xb2a71,    0xbce0a,    0xc7a4a,    0xd2fa0,
++         0xdee7b,    0xeb752,    0xf8a9f,   0x1068e4,
++        0x1152a3,   0x12486a,   0x134ac8,   0x145a55,
++        0x1577ac,   0x16a370,   0x17df51,   0x192bc2,
++        0x1a88f8,   0x1bf7b7,   0x1d78c9,   0x1f0d04,
++        0x20b542,   0x227268,   0x244564,   0x262f26,
++        0x2830af
++};
++
++static uint tas3001c_treble_tab[]={
++            0x96,       0x95,       0x95,       0x94,
++            0x93,       0x92,       0x92,       0x91,
++            0x90,       0x90,       0x8f,       0x8e,
++            0x8d,       0x8d,       0x8c,       0x8b,
++            0x8a,       0x8a,       0x89,       0x88,
++            0x88,       0x87,       0x86,       0x85,
++            0x85,       0x84,       0x83,       0x83,
++            0x82,       0x81,       0x80,       0x80,
++            0x7f,       0x7e,       0x7e,       0x7d,
++            0x7c,       0x7b,       0x7b,       0x7a,
++            0x79,       0x78,       0x78,       0x77,
++            0x76,       0x76,       0x75,       0x74,
++            0x73,       0x73,       0x72,       0x71,
++            0x71,       0x70,       0x6e,       0x6d,
++            0x6d,       0x6c,       0x6b,       0x6a,
++            0x69,       0x68,       0x67,       0x66,
++            0x65,       0x63,       0x62,       0x62,
++            0x60,       0x5f,       0x5d,       0x5c,
++            0x5a,       0x58,       0x56,       0x55,
++            0x53,       0x51,       0x4f,       0x4c,
++            0x4a,       0x48,       0x45,       0x43,
++            0x40,       0x3d,       0x3a,       0x37,
++            0x35,       0x32,       0x2e,       0x2a,
++            0x27,       0x22,       0x1e,       0x1a,
++            0x15,       0x11,        0xc,        0x7,
++             0x1
++};
++
++static uint tas3001c_bass_tab[]={
++            0x86,       0x83,       0x81,       0x7f,
++            0x7d,       0x7b,       0x79,       0x78,
++            0x76,       0x75,       0x74,       0x72,
++            0x71,       0x6f,       0x6e,       0x6d,
++            0x6c,       0x6b,       0x69,       0x67,
++            0x65,       0x64,       0x61,       0x60,
++            0x5e,       0x5d,       0x5c,       0x5b,
++            0x5a,       0x59,       0x58,       0x57,
++            0x56,       0x55,       0x55,       0x54,
++            0x53,       0x52,       0x50,       0x4f,
++            0x4d,       0x4c,       0x4b,       0x49,
++            0x47,       0x45,       0x44,       0x42,
++            0x41,       0x3f,       0x3e,       0x3d,
++            0x3c,       0x3b,       0x39,       0x38,
++            0x37,       0x36,       0x35,       0x34,
++            0x33,       0x31,       0x30,       0x2f,
++            0x2e,       0x2c,       0x2b,       0x2b,
++            0x29,       0x28,       0x27,       0x26,
++            0x25,       0x24,       0x22,       0x21,
++            0x20,       0x1e,       0x1c,       0x19,
++            0x18,       0x18,       0x17,       0x16,
++            0x15,       0x14,       0x13,       0x12,
++            0x11,       0x10,        0xf,        0xe,
++             0xd,        0xb,        0xa,        0x9,
++             0x8,        0x6,        0x4,        0x2,
++             0x1
++};
++
++struct tas_gain_t tas3001c_gain = {
++  master: tas3001c_master_tab,
++  treble: tas3001c_treble_tab,
++  bass:   tas3001c_bass_tab,
++  mixer:  tas3001c_mixer_tab
++};
++
++struct tas_eq_pref_t *tas3001c_eq_prefs[]={
++  &eqp_0e_2_1,
++  &eqp_10_1_0,
++  &eqp_15_2_1,
++  &eqp_15_1_0,
++  &eqp_0f_2_1,
++  &eqp_0f_1_0,
++  NULL
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3004.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3004.c        2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3004.c     2003-09-27 11:38:42.462073168 +0800
+@@ -0,0 +1,1124 @@
++/*
++ * Driver for the i2c/i2s based TA3004 sound chip used
++ * on some Apple hardware. Also known as "snapper".
++ *
++ * Tobias Sargeant <tobias.sargeant@bigpond.com>
++ * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
++ *
++ *   TODO:
++ *   -----
++ *   * Enable control over input line 2 (is this connected?)
++ *   * Implement sleep support (at least mute everything and
++ *   * set gains to minimum during sleep)
++ *
++ */
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/soundcard.h>
++#include <linux/interrupt.h>
++#include <linux/workqueue.h>
++
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++
++#include "dmasound.h"
++#include "tas_common.h"
++#include "tas3004.h"
++
++#include "tas_ioctl.h"
++
++/* #define DEBUG_DRCE */
++
++#define TAS3004_BIQUAD_FILTER_COUNT  7
++#define TAS3004_BIQUAD_CHANNEL_COUNT 2
++
++#define VOL_DEFAULT   (100 * 4 / 5)
++#define INPUT_DEFAULT (100 * 4 / 5)
++#define BASS_DEFAULT  (100 / 2)
++#define TREBLE_DEFAULT        (100 / 2)
++
++struct tas3004_data_t {
++      struct tas_data_t super;
++      int device_id;
++      int output_id;
++      int speaker_id;
++      struct tas_drce_t drce_state;
++};
++
++#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
++
++#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
++
++
++static const union tas_biquad_t tas3004_eq_unity = {
++      .buf             = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
++};
++
++
++static const struct tas_drce_t tas3004_drce_min = {
++      .enable         = 1,
++      .above          = { .val = MAKE_RATIO(16,0), .expand = 0 },
++      .below          = { .val = MAKE_RATIO(2,0), .expand = 0 },
++      .threshold      = -0x59a0,
++      .energy         = MAKE_TIME(0,  1700),
++      .attack         = MAKE_TIME(0,  1700),
++      .decay          = MAKE_TIME(0,  1700),
++};
++
++
++static const struct tas_drce_t tas3004_drce_max = {
++      .enable         = 1,
++      .above          = { .val = MAKE_RATIO(1,500), .expand = 1 },
++      .below          = { .val = MAKE_RATIO(2,0), .expand = 1 },
++      .threshold      = -0x0,
++      .energy         = MAKE_TIME(2,400000),
++      .attack         = MAKE_TIME(2,400000),
++      .decay          = MAKE_TIME(2,400000),
++};
++
++
++static const unsigned short time_constants[]={
++      MAKE_TIME(0,  1700),
++      MAKE_TIME(0,  3500),
++      MAKE_TIME(0,  6700),
++      MAKE_TIME(0, 13000),
++      MAKE_TIME(0, 26000),
++      MAKE_TIME(0, 53000),
++      MAKE_TIME(0,106000),
++      MAKE_TIME(0,212000),
++      MAKE_TIME(0,425000),
++      MAKE_TIME(0,850000),
++      MAKE_TIME(1,700000),
++      MAKE_TIME(2,400000),
++};
++
++static const unsigned short above_threshold_compression_ratio[]={
++      MAKE_RATIO( 1, 70),
++      MAKE_RATIO( 1,140),
++      MAKE_RATIO( 1,230),
++      MAKE_RATIO( 1,330),
++      MAKE_RATIO( 1,450),
++      MAKE_RATIO( 1,600),
++      MAKE_RATIO( 1,780),
++      MAKE_RATIO( 2,  0),
++      MAKE_RATIO( 2,290),
++      MAKE_RATIO( 2,670),
++      MAKE_RATIO( 3,200),
++      MAKE_RATIO( 4,  0),
++      MAKE_RATIO( 5,330),
++      MAKE_RATIO( 8,  0),
++      MAKE_RATIO(16,  0),
++};
++
++static const unsigned short above_threshold_expansion_ratio[]={
++      MAKE_RATIO(1, 60),
++      MAKE_RATIO(1,130),
++      MAKE_RATIO(1,190),
++      MAKE_RATIO(1,250),
++      MAKE_RATIO(1,310),
++      MAKE_RATIO(1,380),
++      MAKE_RATIO(1,440),
++      MAKE_RATIO(1,500)
++};
++
++static const unsigned short below_threshold_compression_ratio[]={
++      MAKE_RATIO(1, 70),
++      MAKE_RATIO(1,140),
++      MAKE_RATIO(1,230),
++      MAKE_RATIO(1,330),
++      MAKE_RATIO(1,450),
++      MAKE_RATIO(1,600),
++      MAKE_RATIO(1,780),
++      MAKE_RATIO(2,  0)
++};
++
++static const unsigned short below_threshold_expansion_ratio[]={
++      MAKE_RATIO(1, 60),
++      MAKE_RATIO(1,130),
++      MAKE_RATIO(1,190),
++      MAKE_RATIO(1,250),
++      MAKE_RATIO(1,310),
++      MAKE_RATIO(1,380),
++      MAKE_RATIO(1,440),
++      MAKE_RATIO(1,500),
++      MAKE_RATIO(1,560),
++      MAKE_RATIO(1,630),
++      MAKE_RATIO(1,690),
++      MAKE_RATIO(1,750),
++      MAKE_RATIO(1,810),
++      MAKE_RATIO(1,880),
++      MAKE_RATIO(1,940),
++      MAKE_RATIO(2,  0)
++};
++
++static inline int
++search(       unsigned short val,
++      const unsigned short *arr,
++      const int arrsize) {
++      /*
++       * This could be a binary search, but for small tables,
++       * a linear search is likely to be faster
++       */
++
++      int i;
++
++      for (i=0; i < arrsize; i++)
++              if (arr[i] >= val)
++                      goto _1;
++      return arrsize-1;
++ _1:
++      if (i == 0)
++              return 0;
++      return (arr[i]-val < val-arr[i-1]) ? i : i-1;
++}
++
++#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
++
++static inline int
++time_index(unsigned short time)
++{
++      return SEARCH(time, time_constants);
++}
++
++
++static inline int
++above_threshold_compression_index(unsigned short ratio)
++{
++      return SEARCH(ratio, above_threshold_compression_ratio);
++}
++
++
++static inline int
++above_threshold_expansion_index(unsigned short ratio)
++{
++      return SEARCH(ratio, above_threshold_expansion_ratio);
++}
++
++
++static inline int
++below_threshold_compression_index(unsigned short ratio)
++{
++      return SEARCH(ratio, below_threshold_compression_ratio);
++}
++
++
++static inline int
++below_threshold_expansion_index(unsigned short ratio)
++{
++      return SEARCH(ratio, below_threshold_expansion_ratio);
++}
++
++static inline unsigned char db_to_regval(short db) {
++      int r=0;
++
++      r=(db+0x59a0) / 0x60;
++
++      if (r < 0x91) return 0x91;
++      if (r > 0xef) return 0xef;
++      return r;
++}
++
++static inline short quantize_db(short db)
++{
++      return db_to_regval(db) * 0x60 - 0x59a0;
++}
++
++static inline int
++register_width(enum tas3004_reg_t r)
++{
++      switch(r) {
++      case TAS3004_REG_MCR:
++      case TAS3004_REG_TREBLE:
++      case TAS3004_REG_BASS:
++      case TAS3004_REG_ANALOG_CTRL:
++      case TAS3004_REG_TEST1:
++      case TAS3004_REG_TEST2:
++      case TAS3004_REG_MCR2:
++              return 1;
++
++      case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
++      case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
++              return 3;
++
++      case TAS3004_REG_DRC:
++      case TAS3004_REG_VOLUME:
++              return 6;
++
++      case TAS3004_REG_LEFT_MIXER:
++      case TAS3004_REG_RIGHT_MIXER:
++              return 9;
++
++      case TAS3004_REG_TEST:
++              return 10;
++
++      case TAS3004_REG_LEFT_BIQUAD0:
++      case TAS3004_REG_LEFT_BIQUAD1:
++      case TAS3004_REG_LEFT_BIQUAD2:
++      case TAS3004_REG_LEFT_BIQUAD3:
++      case TAS3004_REG_LEFT_BIQUAD4:
++      case TAS3004_REG_LEFT_BIQUAD5:
++      case TAS3004_REG_LEFT_BIQUAD6:
++
++      case TAS3004_REG_RIGHT_BIQUAD0:
++      case TAS3004_REG_RIGHT_BIQUAD1:
++      case TAS3004_REG_RIGHT_BIQUAD2:
++      case TAS3004_REG_RIGHT_BIQUAD3:
++      case TAS3004_REG_RIGHT_BIQUAD4:
++      case TAS3004_REG_RIGHT_BIQUAD5:
++      case TAS3004_REG_RIGHT_BIQUAD6:
++
++      case TAS3004_REG_LEFT_LOUD_BIQUAD:
++      case TAS3004_REG_RIGHT_LOUD_BIQUAD:
++              return 15;
++
++      default:
++              return 0;
++      }
++}
++
++static int
++tas3004_write_register(       struct tas3004_data_t *self,
++                      enum tas3004_reg_t reg_num,
++                      char *data,
++                      uint write_mode)
++{
++      if (reg_num==TAS3004_REG_MCR ||
++          reg_num==TAS3004_REG_BASS ||
++          reg_num==TAS3004_REG_TREBLE) {
++              return tas_write_byte_register(&self->super,
++                                             (uint)reg_num,
++                                             *data,
++                                             write_mode);
++      } else {
++              return tas_write_register(&self->super,
++                                        (uint)reg_num,
++                                        register_width(reg_num),
++                                        data,
++                                        write_mode);
++      }
++}
++
++static int
++tas3004_sync_register(        struct tas3004_data_t *self,
++                      enum tas3004_reg_t reg_num)
++{
++      if (reg_num==TAS3004_REG_MCR ||
++          reg_num==TAS3004_REG_BASS ||
++          reg_num==TAS3004_REG_TREBLE) {
++              return tas_sync_byte_register(&self->super,
++                                            (uint)reg_num,
++                                            register_width(reg_num));
++      } else {
++              return tas_sync_register(&self->super,
++                                       (uint)reg_num,
++                                       register_width(reg_num));
++      }
++}
++
++static int
++tas3004_read_register(        struct tas3004_data_t *self,
++                      enum tas3004_reg_t reg_num,
++                      char *data,
++                      uint write_mode)
++{
++      return tas_read_register(&self->super,
++                               (uint)reg_num,
++                               register_width(reg_num),
++                               data);
++}
++
++static inline int
++tas3004_fast_load(struct tas3004_data_t *self, int fast)
++{
++      if (fast)
++              self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
++      else
++              self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
++      return tas3004_sync_register(self,TAS3004_REG_MCR);
++}
++
++static uint
++tas3004_supported_mixers(struct tas3004_data_t *self)
++{
++      return SOUND_MASK_VOLUME |
++              SOUND_MASK_PCM |
++              SOUND_MASK_ALTPCM |
++              SOUND_MASK_IMIX |
++              SOUND_MASK_TREBLE |
++              SOUND_MASK_BASS;
++}
++
++static int
++tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
++{
++      switch(mixer) {
++      case SOUND_MIXER_VOLUME:
++      case SOUND_MIXER_PCM:
++      case SOUND_MIXER_ALTPCM:
++      case SOUND_MIXER_IMIX:
++              return 1;
++      default:
++              return 0;
++      }
++}
++
++static uint
++tas3004_stereo_mixers(struct tas3004_data_t *self)
++{
++      uint r = tas3004_supported_mixers(self);
++      uint i;
++      
++      for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
++              if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
++                      r &= ~(1<<i);
++      return r;
++}
++
++static int
++tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
++{
++      if (!self)
++              return -1;
++
++      *level = self->super.mixer[mixer];
++
++      return 0;
++}
++
++static int
++tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
++{
++      int rc;
++      tas_shadow_t *shadow;
++      uint temp;
++      uint offset=0;
++
++      if (!self)
++              return -1;
++
++      shadow = self->super.shadow;
++
++      if (!tas3004_mixer_is_stereo(self,mixer))
++              level = tas_mono_to_stereo(level);
++      switch(mixer) {
++      case SOUND_MIXER_VOLUME:
++              temp = tas3004_gain.master[level&0xff];
++              SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
++              temp = tas3004_gain.master[(level>>8)&0xff];
++              SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
++              rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
++              break;
++      case SOUND_MIXER_IMIX:
++              offset += 3;
++      case SOUND_MIXER_ALTPCM:
++              offset += 3;
++      case SOUND_MIXER_PCM:
++              /*
++               * Don't load these in fast mode. The documentation
++               * says it can be done in either mode, but testing it
++               * shows that fast mode produces ugly clicking.
++              */
++              /* tas3004_fast_load(self,1); */
++              temp = tas3004_gain.mixer[level&0xff];
++              SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
++              temp = tas3004_gain.mixer[(level>>8)&0xff];
++              SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
++              rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
++              if (rc == 0)
++                      rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
++              /* tas3004_fast_load(self,0); */
++              break;
++      case SOUND_MIXER_TREBLE:
++              temp = tas3004_gain.treble[level&0xff];
++              shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
++              rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
++              break;
++      case SOUND_MIXER_BASS:
++              temp = tas3004_gain.bass[level&0xff];
++              shadow[TAS3004_REG_BASS][0]=temp&0xff;
++              rc = tas3004_sync_register(self,TAS3004_REG_BASS);
++              break;
++      default:
++              rc = -1;
++              break;
++      }
++      if (rc < 0)
++              return rc;
++      self->super.mixer[mixer] = level;
++      
++      return 0;
++}
++
++static int
++tas3004_leave_sleep(struct tas3004_data_t *self)
++{
++      unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++      if (!self)
++              return -1;
++
++      /* Make sure something answers on the i2c bus */
++      if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
++          WRITE_NORMAL | FORCE_WRITE) < 0)
++              return -1;
++
++      tas3004_fast_load(self, 1);
++
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
++
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
++
++      tas3004_fast_load(self, 0);
++
++      (void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
++      (void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
++      (void)tas3004_sync_register(self,TAS3004_REG_BASS);
++
++      return 0;
++}
++
++static int
++tas3004_enter_sleep(struct tas3004_data_t *self)
++{
++      if (!self)
++              return -1; 
++      return 0;
++}
++
++static int
++tas3004_sync_biquad(  struct tas3004_data_t *self,
++                      u_int channel,
++                      u_int filter)
++{
++      enum tas3004_reg_t reg;
++
++      if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
++          filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++      reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
++
++      return tas3004_sync_register(self,reg);
++}
++
++static int
++tas3004_write_biquad_shadow(  struct tas3004_data_t *self,
++                              u_int channel,
++                              u_int filter,
++                              const union tas_biquad_t *biquad)
++{
++      tas_shadow_t *shadow=self->super.shadow;
++      enum tas3004_reg_t reg;
++
++      if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
++          filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++      reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
++
++      SET_4_20(shadow[reg], 0,biquad->coeff.b0);
++      SET_4_20(shadow[reg], 3,biquad->coeff.b1);
++      SET_4_20(shadow[reg], 6,biquad->coeff.b2);
++      SET_4_20(shadow[reg], 9,biquad->coeff.a1);
++      SET_4_20(shadow[reg],12,biquad->coeff.a2);
++
++      return 0;
++}
++
++static int
++tas3004_write_biquad( struct tas3004_data_t *self,
++                      u_int channel,
++                      u_int filter,
++                      const union tas_biquad_t *biquad)
++{
++      int rc;
++
++      rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
++      if (rc < 0) return rc;
++
++      return tas3004_sync_biquad(self, channel, filter);
++}
++
++static int
++tas3004_write_biquad_list(    struct tas3004_data_t *self,
++                              u_int filter_count,
++                              u_int flags,
++                              struct tas_biquad_ctrl_t *biquads)
++{
++      int i;
++      int rc;
++
++      if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
++
++      for (i=0; i<filter_count; i++) {
++              rc=tas3004_write_biquad(self,
++                                      biquads[i].channel,
++                                      biquads[i].filter,
++                                      &biquads[i].data);
++              if (rc < 0) break;
++      }
++
++      if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
++
++      return rc;
++}
++
++static int
++tas3004_read_biquad(  struct tas3004_data_t *self,
++                      u_int channel,
++                      u_int filter,
++                      union tas_biquad_t *biquad)
++{
++      tas_shadow_t *shadow=self->super.shadow;
++      enum tas3004_reg_t reg;
++
++      if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
++          filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
++
++      reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
++
++      biquad->coeff.b0=GET_4_20(shadow[reg], 0);
++      biquad->coeff.b1=GET_4_20(shadow[reg], 3);
++      biquad->coeff.b2=GET_4_20(shadow[reg], 6);
++      biquad->coeff.a1=GET_4_20(shadow[reg], 9);
++      biquad->coeff.a2=GET_4_20(shadow[reg],12);
++      
++      return 0;       
++}
++
++static int
++tas3004_eq_rw(        struct tas3004_data_t *self,
++              u_int cmd,
++              u_long arg)
++{
++      int rc;
++      struct tas_biquad_ctrl_t biquad;
++
++      if (copy_from_user((void *)&biquad, (const void *)arg, sizeof(struct tas_biquad_ctrl_t))) {
++              return -EFAULT;
++      }
++
++      if (cmd & SIOC_IN) {
++              rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++              if (rc != 0) return rc;
++      }
++
++      if (cmd & SIOC_OUT) {
++              rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++              if (rc != 0) return rc;
++
++              if (copy_to_user((void *)arg, (const void *)&biquad, sizeof(struct tas_biquad_ctrl_t))) {
++                      return -EFAULT;
++              }
++
++      }
++      return 0;
++}
++
++static int
++tas3004_eq_list_rw(   struct tas3004_data_t *self,
++                      u_int cmd,
++                      u_long arg)
++{
++      int rc = 0;
++      int filter_count;
++      int flags;
++      int i,j;
++      char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
++      struct tas_biquad_ctrl_t biquad;
++
++      memset(sync_required,0,sizeof(sync_required));
++
++      if (copy_from_user((void *)&filter_count,
++                         (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,filter_count),
++                         sizeof(int))) {
++              return -EFAULT;
++      }
++
++      if (copy_from_user((void *)&flags,
++                         (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t,flags),
++                         sizeof(int))) {
++              return -EFAULT;
++      }
++
++      if (cmd & SIOC_IN) {
++      }
++
++      for (i=0; i < filter_count; i++) {
++              if (copy_from_user((void *)&biquad,
++                                 (const void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++                                 sizeof(struct tas_biquad_ctrl_t))) {
++                      return -EFAULT;
++              }
++
++              if (cmd & SIOC_IN) {
++                      sync_required[biquad.channel][biquad.filter]=1;
++                      rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
++                      if (rc != 0) return rc;
++              }
++
++              if (cmd & SIOC_OUT) {
++                      rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
++                      if (rc != 0) return rc;
++
++                      if (copy_to_user((void *)arg + offsetof(struct tas_biquad_ctrl_list_t, biquads[i]),
++                                       (const void *)&biquad,
++                                       sizeof(struct tas_biquad_ctrl_t))) {
++                              return -EFAULT;
++                      }
++              }
++      }
++
++      if (cmd & SIOC_IN) {
++              /*
++               * This is OK for the tas3004. For the
++               * tas3001c, going into fast load mode causes
++               * the treble and bass to be reset to 0dB, and
++               * volume controls to be muted.
++               */
++              if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
++              for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
++                      for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
++                              if (sync_required[i][j]) {
++                                      rc=tas3004_sync_biquad(self, i, j);
++                                      if (rc < 0) goto out;
++                              }
++                      }
++              }
++      out:
++              if (flags & TAS_BIQUAD_FAST_LOAD)
++                      tas3004_fast_load(self,0);
++      }
++
++      return rc;
++}
++
++static int
++tas3004_update_drce(  struct tas3004_data_t *self,
++                      int flags,
++                      struct tas_drce_t *drce)
++{
++      tas_shadow_t *shadow;
++      int i;
++      shadow=self->super.shadow;
++
++      if (flags & TAS_DRCE_ABOVE_RATIO) {
++              self->drce_state.above.expand = drce->above.expand;
++              if (drce->above.val == (1<<8)) {
++                      self->drce_state.above.val = 1<<8;
++                      shadow[TAS3004_REG_DRC][0] = 0x02;
++                                      
++              } else if (drce->above.expand) {
++                      i=above_threshold_expansion_index(drce->above.val);
++                      self->drce_state.above.val=above_threshold_expansion_ratio[i];
++                      shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
++              } else {
++                      i=above_threshold_compression_index(drce->above.val);
++                      self->drce_state.above.val=above_threshold_compression_ratio[i];
++                      shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
++              }
++      }
++
++      if (flags & TAS_DRCE_BELOW_RATIO) {
++              self->drce_state.below.expand = drce->below.expand;
++              if (drce->below.val == (1<<8)) {
++                      self->drce_state.below.val = 1<<8;
++                      shadow[TAS3004_REG_DRC][1] = 0x02;
++                                      
++              } else if (drce->below.expand) {
++                      i=below_threshold_expansion_index(drce->below.val);
++                      self->drce_state.below.val=below_threshold_expansion_ratio[i];
++                      shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
++              } else {
++                      i=below_threshold_compression_index(drce->below.val);
++                      self->drce_state.below.val=below_threshold_compression_ratio[i];
++                      shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
++              }
++      }
++
++      if (flags & TAS_DRCE_THRESHOLD) {
++              self->drce_state.threshold=quantize_db(drce->threshold);
++              shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
++      }
++
++      if (flags & TAS_DRCE_ENERGY) {
++              i=time_index(drce->energy);
++              self->drce_state.energy=time_constants[i];
++              shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
++      }
++
++      if (flags & TAS_DRCE_ATTACK) {
++              i=time_index(drce->attack);
++              self->drce_state.attack=time_constants[i];
++              shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
++      }
++
++      if (flags & TAS_DRCE_DECAY) {
++              i=time_index(drce->decay);
++              self->drce_state.decay=time_constants[i];
++              shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
++      }
++
++      if (flags & TAS_DRCE_ENABLE) {
++              self->drce_state.enable = drce->enable;
++      }
++
++      if (!self->drce_state.enable) {
++              shadow[TAS3004_REG_DRC][0] |= 0x01;
++      }
++
++#ifdef DEBUG_DRCE
++      printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
++             self->drce_state.enable,
++             self->drce_state.above.expand,self->drce_state.above.val,
++             self->drce_state.below.expand,self->drce_state.below.val,
++             self->drce_state.threshold,
++             self->drce_state.energy,
++             self->drce_state.attack,
++             self->drce_state.decay);
++
++      printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
++             (unsigned char)shadow[TAS3004_REG_DRC][0],
++             (unsigned char)shadow[TAS3004_REG_DRC][1],
++             (unsigned char)shadow[TAS3004_REG_DRC][2],
++             (unsigned char)shadow[TAS3004_REG_DRC][3],
++             (unsigned char)shadow[TAS3004_REG_DRC][4],
++             (unsigned char)shadow[TAS3004_REG_DRC][5]);
++#endif
++
++      return tas3004_sync_register(self, TAS3004_REG_DRC);
++}
++
++static int
++tas3004_drce_rw(      struct tas3004_data_t *self,
++                      u_int cmd,
++                      u_long arg)
++{
++      int rc;
++      struct tas_drce_ctrl_t drce_ctrl;
++
++      if (copy_from_user((void *)&drce_ctrl,
++                         (const void *)arg,
++                         sizeof(struct tas_drce_ctrl_t))) {
++              return -EFAULT;
++      }
++
++#ifdef DEBUG_DRCE
++      printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
++             drce_ctrl.flags,
++             drce_ctrl.data.enable,
++             drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
++             drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
++             drce_ctrl.data.threshold,
++             drce_ctrl.data.energy,
++             drce_ctrl.data.attack,
++             drce_ctrl.data.decay);
++#endif
++
++      if (cmd & SIOC_IN) {
++              rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
++              if (rc < 0) return rc;
++      }
++
++      if (cmd & SIOC_OUT) {
++              if (drce_ctrl.flags & TAS_DRCE_ENABLE)
++                      drce_ctrl.data.enable = self->drce_state.enable;
++              if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
++                      drce_ctrl.data.above = self->drce_state.above;
++              if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
++                      drce_ctrl.data.below = self->drce_state.below;
++              if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
++                      drce_ctrl.data.threshold = self->drce_state.threshold;
++              if (drce_ctrl.flags & TAS_DRCE_ENERGY)
++                      drce_ctrl.data.energy = self->drce_state.energy;
++              if (drce_ctrl.flags & TAS_DRCE_ATTACK)
++                      drce_ctrl.data.attack = self->drce_state.attack;
++              if (drce_ctrl.flags & TAS_DRCE_DECAY)
++                      drce_ctrl.data.decay = self->drce_state.decay;
++
++              if (copy_to_user((void *)arg,
++                               (const void *)&drce_ctrl,
++                               sizeof(struct tas_drce_ctrl_t))) {
++                      return -EFAULT;
++              }
++      }
++
++      return 0;
++}
++
++static void
++tas3004_update_device_parameters(struct tas3004_data_t *self)
++{
++      char data;
++      int i;
++
++      if (!self) return;
++
++      if (self->output_id == TAS_OUTPUT_HEADPHONES) {
++              /* turn on allPass when headphones are plugged in */
++              data = 0x02;
++      } else {
++              data = 0x00;
++      }
++
++      tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
++
++      for (i=0; tas3004_eq_prefs[i]; i++) {
++              struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
++
++              if (eq->device_id == self->device_id &&
++                  (eq->output_id == 0 || eq->output_id == self->output_id) &&
++                  (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
++
++                      tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
++                      tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
++
++                      break;
++              }
++      }
++}
++
++static void
++tas3004_device_change_handler(void *self)
++{
++      if (!self) return;
++
++      tas3004_update_device_parameters((struct tas3004_data_t *)self);
++}
++
++static struct work_struct device_change;
++
++static int
++tas3004_output_device_change( struct tas3004_data_t *self,
++                              int device_id,
++                              int output_id,
++                              int speaker_id)
++{
++      self->device_id=device_id;
++      self->output_id=output_id;
++      self->speaker_id=speaker_id;
++
++      schedule_work(&device_change);
++
++      return 0;
++}
++
++static int
++tas3004_device_ioctl( struct tas3004_data_t *self,
++                      u_int cmd,
++                      u_long arg)
++{
++      switch (cmd) {
++      case TAS_READ_EQ:
++      case TAS_WRITE_EQ:
++              return tas3004_eq_rw(self, cmd, arg);
++
++      case TAS_READ_EQ_LIST:
++      case TAS_WRITE_EQ_LIST:
++              return tas3004_eq_list_rw(self, cmd, arg);
++
++      case TAS_READ_EQ_FILTER_COUNT:
++              put_user(TAS3004_BIQUAD_FILTER_COUNT, (uint *)(arg));
++              return 0;
++
++      case TAS_READ_EQ_CHANNEL_COUNT:
++              put_user(TAS3004_BIQUAD_CHANNEL_COUNT, (uint *)(arg));
++              return 0;
++
++      case TAS_READ_DRCE:
++      case TAS_WRITE_DRCE:
++              return tas3004_drce_rw(self, cmd, arg);
++
++      case TAS_READ_DRCE_CAPS:
++              put_user(TAS_DRCE_ENABLE         |
++                       TAS_DRCE_ABOVE_RATIO    |
++                       TAS_DRCE_BELOW_RATIO    |
++                       TAS_DRCE_THRESHOLD      |
++                       TAS_DRCE_ENERGY         |
++                       TAS_DRCE_ATTACK         |
++                       TAS_DRCE_DECAY,
++                       (uint *)(arg));
++              return 0;
++
++      case TAS_READ_DRCE_MIN:
++      case TAS_READ_DRCE_MAX: {
++              struct tas_drce_ctrl_t drce_ctrl;
++              const struct tas_drce_t *drce_copy;
++
++              if (copy_from_user((void *)&drce_ctrl,
++                                 (const void *)arg,
++                                 sizeof(struct tas_drce_ctrl_t))) {
++                      return -EFAULT;
++              }
++
++              if (cmd == TAS_READ_DRCE_MIN) {
++                      drce_copy=&tas3004_drce_min;
++              } else {
++                      drce_copy=&tas3004_drce_max;
++              }
++
++              if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
++                      drce_ctrl.data.above=drce_copy->above;
++              }
++              if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
++                      drce_ctrl.data.below=drce_copy->below;
++              }
++              if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
++                      drce_ctrl.data.threshold=drce_copy->threshold;
++              }
++              if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
++                      drce_ctrl.data.energy=drce_copy->energy;
++              }
++              if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
++                      drce_ctrl.data.attack=drce_copy->attack;
++              }
++              if (drce_ctrl.flags & TAS_DRCE_DECAY) {
++                      drce_ctrl.data.decay=drce_copy->decay;
++              }
++
++              if (copy_to_user((void *)arg,
++                               (const void *)&drce_ctrl,
++                               sizeof(struct tas_drce_ctrl_t))) {
++                      return -EFAULT;
++              }
++      }
++      }
++
++      return -EINVAL;
++}
++
++static int
++tas3004_init_mixer(struct tas3004_data_t *self)
++{
++      unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
++
++      /* Make sure something answers on the i2c bus */
++      if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
++          WRITE_NORMAL | FORCE_WRITE) < 0)
++              return -1;
++
++      tas3004_fast_load(self, 1);
++
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
++      (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
++
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
++      (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
++
++      tas3004_sync_register(self, TAS3004_REG_DRC);
++
++      tas3004_sync_register(self, TAS3004_REG_MCR2);
++
++      tas3004_fast_load(self, 0);
++
++      tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
++      tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
++      tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++      tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
++
++      tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
++      tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
++
++      return 0;
++}
++
++static int
++tas3004_uninit_mixer(struct tas3004_data_t *self)
++{
++      tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
++      tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
++      tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
++      tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
++
++      tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
++      tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
++
++      return 0;
++}
++
++static int
++tas3004_init(struct i2c_client *client)
++{
++      struct tas3004_data_t *self;
++      size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
++      char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
++      char mcr2 = 0;
++      int i, j;
++
++      self = kmalloc(sz, GFP_KERNEL);
++      if (!self)
++              return -ENOMEM;
++      memset(self, 0, sz);
++
++      self->super.client = client;
++      self->super.shadow = (tas_shadow_t *)(self+1);
++      self->output_id = TAS_OUTPUT_HEADPHONES;
++
++      dev_set_drvdata(&client->dev, self);
++
++      for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
++              for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
++                      tas3004_write_biquad_shadow(self, i, j,
++                                      &tas3004_eq_unity);
++
++      tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
++      tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
++
++      INIT_WORK(&device_change, tas3004_device_change_handler, self);
++      return 0;
++}
++
++static void 
++tas3004_uninit(struct tas3004_data_t *self)
++{
++      tas3004_uninit_mixer(self);
++      kfree(self);
++}
++
++
++struct tas_driver_hooks_t tas3004_hooks = {
++      .init                   = (tas_hook_init_t)tas3004_init,
++      .post_init              = (tas_hook_post_init_t)tas3004_init_mixer,
++      .uninit                 = (tas_hook_uninit_t)tas3004_uninit,
++      .get_mixer_level        = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
++      .set_mixer_level        = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
++      .enter_sleep            = (tas_hook_enter_sleep_t)tas3004_enter_sleep,
++      .leave_sleep            = (tas_hook_leave_sleep_t)tas3004_leave_sleep,
++      .supported_mixers       = (tas_hook_supported_mixers_t)tas3004_supported_mixers,
++      .mixer_is_stereo        = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
++      .stereo_mixers          = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
++      .output_device_change   = (tas_hook_output_device_change_t)tas3004_output_device_change,
++      .device_ioctl           = (tas_hook_device_ioctl_t)tas3004_device_ioctl
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3004.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3004.h        2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3004.h     2003-09-27 11:38:42.462073168 +0800
+@@ -0,0 +1,77 @@
++/*
++ * Header file for the i2c/i2s based TA3004 sound chip used
++ * on some Apple hardware. Also known as "tumbler".
++ *
++ *  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 Christopher C. Chimelis <chris@debian.org>
++ */
++
++#ifndef _TAS3004_H_
++#define _TAS3004_H_
++
++#include <linux/types.h>
++
++#include "tas_common.h"
++#include "tas_eq_prefs.h"
++
++/*
++ * Macros that correspond to the registers that we write to
++ * when setting the various values.
++ */
++
++#define TAS3004_VERSION               "0.3"
++#define TAS3004_DATE          "20011214"
++
++#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION
++#define I2C_DRIVERID_TAS3004    (I2C_DRIVERID_TAS_BASE+1)
++
++extern  struct tas_driver_hooks_t tas3004_hooks;
++extern struct tas_gain_t tas3004_gain;
++extern struct tas_eq_pref_t *tas3004_eq_prefs[];
++
++enum tas3004_reg_t {
++  TAS3004_REG_MCR                    = 0x01,
++  TAS3004_REG_DRC                    = 0x02,
++
++  TAS3004_REG_VOLUME                 = 0x04,
++  TAS3004_REG_TREBLE                 = 0x05,
++  TAS3004_REG_BASS                   = 0x06,
++  TAS3004_REG_LEFT_MIXER             = 0x07,
++  TAS3004_REG_RIGHT_MIXER            = 0x08,
++
++  TAS3004_REG_LEFT_BIQUAD0           = 0x0a,
++  TAS3004_REG_LEFT_BIQUAD1           = 0x0b,
++  TAS3004_REG_LEFT_BIQUAD2           = 0x0c,
++  TAS3004_REG_LEFT_BIQUAD3           = 0x0d,
++  TAS3004_REG_LEFT_BIQUAD4           = 0x0e,
++  TAS3004_REG_LEFT_BIQUAD5           = 0x0f,
++  TAS3004_REG_LEFT_BIQUAD6           = 0x10,
++  
++  TAS3004_REG_RIGHT_BIQUAD0          = 0x13,
++  TAS3004_REG_RIGHT_BIQUAD1          = 0x14,
++  TAS3004_REG_RIGHT_BIQUAD2          = 0x15,
++  TAS3004_REG_RIGHT_BIQUAD3          = 0x16,
++  TAS3004_REG_RIGHT_BIQUAD4          = 0x17,
++  TAS3004_REG_RIGHT_BIQUAD5          = 0x18,
++  TAS3004_REG_RIGHT_BIQUAD6          = 0x19,
++
++  TAS3004_REG_LEFT_LOUD_BIQUAD       = 0x21,
++  TAS3004_REG_RIGHT_LOUD_BIQUAD      = 0x22,
++
++  TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN  = 0x23,
++  TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24,
++
++  TAS3004_REG_TEST                   = 0x29,
++
++  TAS3004_REG_ANALOG_CTRL            = 0x40,
++  TAS3004_REG_TEST1                  = 0x41,
++  TAS3004_REG_TEST2                  = 0x42,
++  TAS3004_REG_MCR2                   = 0x43,
++
++  TAS3004_REG_MAX                    = 0x44
++};
++
++#endif /* _TAS3004_H_ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas3004_tables.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas3004_tables.c 2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas3004_tables.c      2003-09-27 11:38:42.464072864 +0800
+@@ -0,0 +1,301 @@
++#include "tas3004.h"
++#include "tas_eq_prefs.h"
++
++static struct tas_drce_t eqp_17_1_0_drce={
++    enable:    1,
++    above:     { val: 3.0 * (1<<8), expand: 0 },
++    below:     { val: 1.0 * (1<<8), expand: 0 },
++    threshold: -19.12  * (1<<8),
++    energy:    2.4     * (1<<12),
++    attack:    0.013   * (1<<12),
++    decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
++  { channel: 0, filter: 6, data: { coeff: { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
++  { channel: 1, filter: 6, data: { coeff: { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }
++};
++
++static struct tas_eq_pref_t eqp_17_1_0 = {
++  sample_rate:  44100,
++  device_id:    0x17,
++  output_id:    TAS_OUTPUT_INTERNAL_SPKR,
++  speaker_id:   0x00,
++
++  drce:         &eqp_17_1_0_drce,
++
++  filter_count: 14,
++  biquads:      eqp_17_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_18_1_0_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -13.14  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
++  { channel: 0, filter: 6, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
++  { channel: 1, filter: 6, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }
++};
++
++static struct tas_eq_pref_t eqp_18_1_0 = {
++  sample_rate:  44100,
++  device_id:    0x18,
++  output_id:    TAS_OUTPUT_INTERNAL_SPKR,
++  speaker_id:   0x00,
++
++  drce:         &eqp_18_1_0_drce,
++
++  filter_count: 14,
++  biquads:      eqp_18_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_1a_1_0_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -10.75  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
++  { channel: 0, filter: 6, data: { coeff: { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
++  { channel: 1, filter: 6, data: { coeff: { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }
++};
++
++static struct tas_eq_pref_t eqp_1a_1_0 = {
++  sample_rate:  44100,
++  device_id:    0x1a,
++  output_id:    TAS_OUTPUT_INTERNAL_SPKR,
++  speaker_id:   0x00,
++
++  drce:         &eqp_1a_1_0_drce,
++
++  filter_count: 14,
++  biquads:      eqp_1a_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static struct tas_drce_t eqp_1c_1_0_drce={
++  enable:    1,
++  above:     { val: 3.0 * (1<<8), expand: 0 },
++  below:     { val: 1.0 * (1<<8), expand: 0 },
++  threshold: -14.34  * (1<<8),
++  energy:    2.4     * (1<<12),
++  attack:    0.013   * (1<<12),
++  decay:     0.212   * (1<<12),
++};
++
++static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={
++  { channel: 0, filter: 0, data: { coeff: { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
++  { channel: 0, filter: 1, data: { coeff: { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
++  { channel: 0, filter: 2, data: { coeff: { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
++  { channel: 0, filter: 3, data: { coeff: { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
++  { channel: 0, filter: 4, data: { coeff: { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
++  { channel: 0, filter: 5, data: { coeff: { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
++  { channel: 0, filter: 6, data: { coeff: { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } },
++
++  { channel: 1, filter: 0, data: { coeff: { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
++  { channel: 1, filter: 1, data: { coeff: { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
++  { channel: 1, filter: 2, data: { coeff: { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
++  { channel: 1, filter: 3, data: { coeff: { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
++  { channel: 1, filter: 4, data: { coeff: { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
++  { channel: 1, filter: 5, data: { coeff: { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
++  { channel: 1, filter: 6, data: { coeff: { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }
++};
++
++static struct tas_eq_pref_t eqp_1c_1_0 = {
++  sample_rate:  44100,
++  device_id:    0x1c,
++  output_id:    TAS_OUTPUT_INTERNAL_SPKR,
++  speaker_id:   0x00,
++
++  drce:         &eqp_1c_1_0_drce,
++
++  filter_count: 14,
++  biquads:      eqp_1c_1_0_biquads
++};
++
++/* ======================================================================== */
++
++static uint tas3004_master_tab[]={
++             0x0,       0x75,       0x9c,       0xbb,
++            0xdb,       0xfb,      0x11e,      0x143,
++           0x16b,      0x196,      0x1c3,      0x1f5,
++           0x229,      0x263,      0x29f,      0x2e1,
++           0x328,      0x373,      0x3c5,      0x41b,
++           0x478,      0x4dc,      0x547,      0x5b8,
++           0x633,      0x6b5,      0x740,      0x7d5,
++           0x873,      0x91c,      0x9d2,      0xa92,
++           0xb5e,      0xc39,      0xd22,      0xe19,
++           0xf20,     0x1037,     0x1161,     0x129e,
++          0x13ed,     0x1551,     0x16ca,     0x185d,
++          0x1a08,     0x1bcc,     0x1dac,     0x1fa7,
++          0x21c1,     0x23fa,     0x2655,     0x28d6,
++          0x2b7c,     0x2e4a,     0x3141,     0x3464,
++          0x37b4,     0x3b35,     0x3ee9,     0x42d3,
++          0x46f6,     0x4b53,     0x4ff0,     0x54ce,
++          0x59f2,     0x5f5f,     0x6519,     0x6b24,
++          0x7183,     0x783c,     0x7f53,     0x86cc,
++          0x8ead,     0x96fa,     0x9fba,     0xa8f2,
++          0xb2a7,     0xbce1,     0xc7a5,     0xd2fa,
++          0xdee8,     0xeb75,     0xf8aa,    0x1068e,
++         0x1152a,    0x12487,    0x134ad,    0x145a5,
++         0x1577b,    0x16a37,    0x17df5,    0x192bd,
++         0x1a890,    0x1bf7b,    0x1d78d,    0x1f0d1,
++         0x20b55,    0x22727,    0x24456,    0x262f2,
++         0x2830b
++};
++
++static uint tas3004_mixer_tab[]={
++             0x0,      0x748,      0x9be,      0xbaf,
++           0xda4,      0xfb1,     0x11de,     0x1431,
++          0x16ad,     0x1959,     0x1c37,     0x1f4b,
++          0x2298,     0x2628,     0x29fb,     0x2e12,
++          0x327d,     0x3734,     0x3c47,     0x41b4,
++          0x4787,     0x4dbe,     0x546d,     0x5b86,
++          0x632e,     0x6b52,     0x7400,     0x7d54,
++          0x873b,     0x91c6,     0x9d1a,     0xa920,
++          0xb5e5,     0xc38c,     0xd21b,     0xe18f,
++          0xf1f5,    0x1036a,    0x1160f,    0x129d6,
++         0x13ed0,    0x1550c,    0x16ca0,    0x185c9,
++         0x1a07b,    0x1bcc3,    0x1dab9,    0x1fa75,
++         0x21c0f,    0x23fa3,    0x26552,    0x28d64,
++         0x2b7c9,    0x2e4a2,    0x31411,    0x3463b,
++         0x37b44,    0x3b353,    0x3ee94,    0x42d30,
++         0x46f55,    0x4b533,    0x4fefc,    0x54ce5,
++         0x59f25,    0x5f5f6,    0x65193,    0x6b23c,
++         0x71835,    0x783c3,    0x7f52c,    0x86cc0,
++         0x8eacc,    0x96fa5,    0x9fba0,    0xa8f1a,
++         0xb2a71,    0xbce0a,    0xc7a4a,    0xd2fa0,
++         0xdee7b,    0xeb752,    0xf8a9f,   0x1068e4,
++        0x1152a3,   0x12486a,   0x134ac8,   0x145a55,
++        0x1577ac,   0x16a370,   0x17df51,   0x192bc2,
++        0x1a88f8,   0x1bf7b7,   0x1d78c9,   0x1f0d04,
++        0x20b542,   0x227268,   0x244564,   0x262f26,
++        0x2830af
++};
++
++static uint tas3004_treble_tab[]={
++            0x96,       0x95,       0x95,       0x94,
++            0x93,       0x92,       0x92,       0x91,
++            0x90,       0x90,       0x8f,       0x8e,
++            0x8d,       0x8d,       0x8c,       0x8b,
++            0x8a,       0x8a,       0x89,       0x88,
++            0x88,       0x87,       0x86,       0x85,
++            0x85,       0x84,       0x83,       0x83,
++            0x82,       0x81,       0x80,       0x80,
++            0x7f,       0x7e,       0x7e,       0x7d,
++            0x7c,       0x7b,       0x7b,       0x7a,
++            0x79,       0x78,       0x78,       0x77,
++            0x76,       0x76,       0x75,       0x74,
++            0x73,       0x73,       0x72,       0x71,
++            0x71,       0x68,       0x45,       0x5b,
++            0x6d,       0x6c,       0x6b,       0x6a,
++            0x69,       0x68,       0x67,       0x66,
++            0x65,       0x63,       0x62,       0x62,
++            0x60,       0x5e,       0x5c,       0x5b,
++            0x59,       0x57,       0x55,       0x53,
++            0x52,       0x4f,       0x4d,       0x4a,
++            0x48,       0x46,       0x43,       0x40,
++            0x3d,       0x3a,       0x36,       0x33,
++            0x2f,       0x2c,       0x27,       0x23,
++            0x1f,       0x1a,       0x15,        0xf,
++             0x8,        0x5,        0x2,        0x1,
++             0x1
++};
++
++static uint tas3004_bass_tab[]={
++            0x96,       0x95,       0x95,       0x94,
++            0x93,       0x92,       0x92,       0x91,
++            0x90,       0x90,       0x8f,       0x8e,
++            0x8d,       0x8d,       0x8c,       0x8b,
++            0x8a,       0x8a,       0x89,       0x88,
++            0x88,       0x87,       0x86,       0x85,
++            0x85,       0x84,       0x83,       0x83,
++            0x82,       0x81,       0x80,       0x80,
++            0x7f,       0x7e,       0x7e,       0x7d,
++            0x7c,       0x7b,       0x7b,       0x7a,
++            0x79,       0x78,       0x78,       0x77,
++            0x76,       0x76,       0x75,       0x74,
++            0x73,       0x73,       0x72,       0x71,
++            0x70,       0x6f,       0x6e,       0x6d,
++            0x6c,       0x6b,       0x6a,       0x6a,
++            0x69,       0x67,       0x66,       0x66,
++            0x65,       0x63,       0x62,       0x62,
++            0x61,       0x60,       0x5e,       0x5d,
++            0x5b,       0x59,       0x57,       0x55,
++            0x53,       0x51,       0x4f,       0x4c,
++            0x4a,       0x48,       0x46,       0x44,
++            0x41,       0x3e,       0x3b,       0x38,
++            0x36,       0x33,       0x2f,       0x2b,
++            0x28,       0x24,       0x20,       0x1c,
++            0x17,       0x12,        0xd,        0x7,
++             0x1
++};
++
++struct tas_gain_t tas3004_gain={
++  master: tas3004_master_tab,
++  treble: tas3004_treble_tab,
++  bass:   tas3004_bass_tab,
++  mixer:  tas3004_mixer_tab
++};
++
++struct tas_eq_pref_t *tas3004_eq_prefs[]={
++  &eqp_17_1_0,
++  &eqp_18_1_0,
++  &eqp_1a_1_0,
++  &eqp_1c_1_0,
++  NULL
++};
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_common.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_common.c     2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_common.c  2003-09-27 11:38:42.465072712 +0800
+@@ -0,0 +1,212 @@
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/ioport.h>
++#include <linux/sysctl.h>
++#include <linux/types.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/soundcard.h>
++#include <asm/uaccess.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/prom.h>
++
++#include "tas_common.h"
++
++#define CALL0(proc)                                                           \
++      do {                                                                    \
++              struct tas_data_t *self;                                        \
++              if (!tas_client || driver_hooks == NULL)                        \
++                      return -1;                                              \
++              self = dev_get_drvdata(&tas_client->dev);                       \
++              if (driver_hooks->proc)                                         \
++                      return driver_hooks->proc(self);                        \
++              else                                                            \
++                      return -EINVAL;                                         \
++      } while (0)
++
++#define CALL(proc,arg...)                                                     \
++      do {                                                                    \
++              struct tas_data_t *self;                                        \
++              if (!tas_client || driver_hooks == NULL)                        \
++                      return -1;                                              \
++              self = dev_get_drvdata(&tas_client->dev);                       \
++              if (driver_hooks->proc)                                         \
++                      return driver_hooks->proc(self, ## arg);                \
++              else                                                            \
++                      return -EINVAL;                                         \
++      } while (0)
++
++
++static u8 tas_i2c_address = 0x34;
++static struct i2c_client *tas_client;
++static struct device_node* tas_node;
++
++static int tas_attach_adapter(struct i2c_adapter *);
++static int tas_detach_client(struct i2c_client *);
++
++struct i2c_driver tas_driver = {
++      .owner          = THIS_MODULE,
++      .name           = "tas",
++      .flags          = I2C_DF_NOTIFY,
++      .attach_adapter = tas_attach_adapter,
++      .detach_client  = tas_detach_client,
++};
++
++struct tas_driver_hooks_t *driver_hooks;
++
++int
++tas_register_driver(struct tas_driver_hooks_t *hooks)
++{
++      driver_hooks = hooks;
++      return 0;
++}
++
++int
++tas_get_mixer_level(int mixer, uint *level)
++{
++      CALL(get_mixer_level,mixer,level);
++}
++
++int
++tas_set_mixer_level(int mixer,uint level)
++{
++      CALL(set_mixer_level,mixer,level);
++}
++
++int
++tas_enter_sleep(void)
++{
++      CALL0(enter_sleep);
++}
++
++int
++tas_leave_sleep(void)
++{
++      CALL0(leave_sleep);
++}
++
++int
++tas_supported_mixers(void)
++{
++      CALL0(supported_mixers);
++}
++
++int
++tas_mixer_is_stereo(int mixer)
++{
++      CALL(mixer_is_stereo,mixer);
++}
++
++int
++tas_stereo_mixers(void)
++{
++      CALL0(stereo_mixers);
++}
++
++int
++tas_output_device_change(int device_id,int layout_id,int speaker_id)
++{
++      CALL(output_device_change,device_id,layout_id,speaker_id);
++}
++
++int
++tas_device_ioctl(u_int cmd, u_long arg)
++{
++      CALL(device_ioctl,cmd,arg);
++}
++
++int
++tas_post_init(void)
++{
++      CALL0(post_init);
++}
++
++static int
++tas_detect_client(struct i2c_adapter *adapter, int address)
++{
++      static const char *client_name = "tas Digital Equalizer";
++      struct i2c_client *new_client;
++      int rc = -ENODEV;
++
++      if (!driver_hooks) {
++              printk(KERN_ERR "tas_detect_client called with no hooks !\n");
++              return -ENODEV;
++      }
++      
++      new_client = kmalloc(sizeof(*new_client), GFP_KERNEL);
++      if (!new_client)
++              return -ENOMEM;
++      memset(new_client, 0, sizeof(*new_client));
++
++      new_client->addr = address;
++      new_client->adapter = adapter;
++      new_client->driver = &tas_driver;
++      strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
++
++        if (driver_hooks->init(new_client))
++              goto bail;
++
++      /* Tell the i2c layer a new client has arrived */
++      if (i2c_attach_client(new_client)) {
++              driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
++              goto bail;
++      }
++
++      tas_client = new_client;
++      return 0;
++ bail:
++      tas_client = NULL;
++      kfree(new_client);
++      return rc;
++}
++
++static int
++tas_attach_adapter(struct i2c_adapter *adapter)
++{
++      if (!strncmp(adapter->name, "mac-io", 6))
++              return tas_detect_client(adapter, tas_i2c_address);
++      return 0;
++}
++
++static int
++tas_detach_client(struct i2c_client *client)
++{
++      if (client == tas_client) {
++              driver_hooks->uninit(dev_get_drvdata(&client->dev));
++
++              i2c_detach_client(client);
++              kfree(client);
++      }
++      return 0;
++}
++
++void
++tas_cleanup(void)
++{
++      i2c_del_driver(&tas_driver);
++}
++
++int __init
++tas_init(int driver_id, const char *driver_name)
++{
++      u32* paddr;
++
++      printk(KERN_INFO "tas driver [%s])\n", driver_name);
++
++      tas_node = find_devices("deq");
++      if (tas_node == NULL)
++              return -ENODEV;
++      paddr = (u32 *)get_property(tas_node, "i2c-address", NULL);
++      if (paddr) {
++              tas_i2c_address = (*paddr) >> 1;
++              printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
++                              tas_i2c_address);
++      } else    
++              printk(KERN_INFO "using i2c address: 0x%x (default)\n",
++                              tas_i2c_address);
++
++      return i2c_add_driver(&tas_driver);
++}
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_common.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_common.h     2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_common.h  2003-09-27 11:38:42.465072712 +0800
+@@ -0,0 +1,284 @@
++#ifndef _TAS_COMMON_H_
++#define _TAS_COMMON_H_
++
++#include <linux/i2c.h>
++#include <linux/soundcard.h>
++#include <asm/string.h>
++
++#define I2C_DRIVERID_TAS_BASE   (0xFEBA)
++
++#define SET_4_20(shadow, offset, val)                        \
++      do {                                                 \
++              (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
++              (shadow)[(offset)+1] = ((val) >> 8)  & 0xff; \
++              (shadow)[(offset)+2] = ((val) >> 0)  & 0xff; \
++      } while (0)
++
++#define GET_4_20(shadow, offset)                             \
++      (((u_int)((shadow)[(offset)+0]) << 16) |             \
++       ((u_int)((shadow)[(offset)+1]) <<  8) |             \
++       ((u_int)((shadow)[(offset)+2]) <<  0))
++
++
++#define TAS_BIQUAD_FAST_LOAD 0x01
++
++#define TAS_DRCE_ENABLE           0x01
++#define TAS_DRCE_ABOVE_RATIO      0x02
++#define TAS_DRCE_BELOW_RATIO      0x04
++#define TAS_DRCE_THRESHOLD        0x08
++#define TAS_DRCE_ENERGY           0x10
++#define TAS_DRCE_ATTACK           0x20
++#define TAS_DRCE_DECAY            0x40
++
++#define TAS_DRCE_ALL              0x7f
++
++
++#define TAS_OUTPUT_HEADPHONES     0x00
++#define TAS_OUTPUT_INTERNAL_SPKR  0x01
++#define TAS_OUTPUT_EXTERNAL_SPKR  0x02
++
++
++union tas_biquad_t {
++      struct {
++              int b0,b1,b2,a1,a2;
++      } coeff;
++      int buf[5];
++};
++
++struct tas_biquad_ctrl_t {
++      u_int channel:4;
++      u_int filter:4;
++
++      union tas_biquad_t data;
++};
++
++struct tas_biquad_ctrl_list_t {
++      int flags;
++      int filter_count;
++      struct tas_biquad_ctrl_t biquads[0];
++};
++
++struct tas_ratio_t {
++      unsigned short val;    /* 8.8                        */
++      unsigned short expand; /* 0 = compress, !0 = expand. */
++};
++
++struct tas_drce_t {
++      unsigned short enable;
++      struct tas_ratio_t above;
++      struct tas_ratio_t below;
++      short threshold;       /* dB,       8.8 signed    */
++      unsigned short energy; /* seconds,  4.12 unsigned */
++      unsigned short attack; /* seconds,  4.12 unsigned */
++      unsigned short decay;  /* seconds,  4.12 unsigned */
++};
++
++struct tas_drce_ctrl_t {
++      uint flags;
++
++      struct tas_drce_t data;
++};
++
++struct tas_gain_t
++{
++  unsigned int *master;
++  unsigned int *treble;
++  unsigned int *bass;
++  unsigned int *mixer;
++};
++
++typedef char tas_shadow_t[16];
++
++struct tas_data_t
++{
++      struct i2c_client *client;
++      tas_shadow_t *shadow;
++      uint mixer[SOUND_MIXER_NRDEVICES];
++};
++
++typedef int (*tas_hook_init_t)(struct i2c_client *);
++typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
++typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
++
++typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
++typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
++
++typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
++typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
++
++typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
++typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
++typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
++
++typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
++typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
++
++struct tas_driver_hooks_t {
++      /*
++       * All hardware initialisation must be performed in
++       * post_init(), as tas_dmasound_init() does a hardware reset.
++       *
++       * init() is called before tas_dmasound_init() so that
++       * ouput_device_change() is always called after i2c driver
++       * initialisation. The implication is that
++       * output_device_change() must cope with the fact that it
++       * may be called before post_init().
++       */
++
++      tas_hook_init_t                   init;
++      tas_hook_post_init_t              post_init;
++      tas_hook_uninit_t                 uninit;
++
++      tas_hook_get_mixer_level_t        get_mixer_level;
++      tas_hook_set_mixer_level_t        set_mixer_level;
++
++      tas_hook_enter_sleep_t            enter_sleep;
++      tas_hook_leave_sleep_t            leave_sleep;
++
++      tas_hook_supported_mixers_t       supported_mixers;
++      tas_hook_mixer_is_stereo_t        mixer_is_stereo;
++      tas_hook_stereo_mixers_t          stereo_mixers;
++
++      tas_hook_output_device_change_t   output_device_change;
++      tas_hook_device_ioctl_t           device_ioctl;
++};
++
++enum tas_write_mode_t {
++      WRITE_HW     = 0x01,
++      WRITE_SHADOW = 0x02,
++      WRITE_NORMAL = 0x03,
++      FORCE_WRITE  = 0x04
++};
++
++static inline uint
++tas_mono_to_stereo(uint mono)
++{
++      mono &=0xff;
++      return mono | (mono<<8);
++}
++
++/*
++ * Todo: make these functions a bit more efficient !
++ */
++static inline int
++tas_write_register(   struct tas_data_t *self,
++                      uint reg_num,
++                      uint reg_width,
++                      char *data,
++                      uint write_mode)
++{
++      int rc;
++
++      if (reg_width==0 || data==NULL || self==NULL)
++              return -EINVAL;
++      if (!(write_mode & FORCE_WRITE) &&
++          !memcmp(data,self->shadow[reg_num],reg_width))
++              return 0;
++
++      if (write_mode & WRITE_SHADOW)
++              memcpy(self->shadow[reg_num],data,reg_width);
++      if (write_mode & WRITE_HW) {
++              rc=i2c_smbus_write_block_data(self->client,
++                                            reg_num,
++                                            reg_width,
++                                            data);
++              if (rc < 0) {
++                      printk("tas: I2C block write failed \n");  
++                      return rc; 
++              }
++      }
++      return 0;
++}
++
++static inline int
++tas_sync_register(    struct tas_data_t *self,
++                      uint reg_num,
++                      uint reg_width)
++{
++      int rc;
++
++      if (reg_width==0 || self==NULL)
++              return -EINVAL;
++      rc=i2c_smbus_write_block_data(self->client,
++                                    reg_num,
++                                    reg_width,
++                                    self->shadow[reg_num]);
++      if (rc < 0) {
++              printk("tas: I2C block write failed \n");
++              return rc;
++      }
++      return 0;
++}
++
++static inline int
++tas_write_byte_register(      struct tas_data_t *self,
++                              uint reg_num,
++                              char data,
++                              uint write_mode)
++{
++      if (self==NULL)
++              return -1;
++      if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
++              return 0;
++      if (write_mode & WRITE_SHADOW)
++              self->shadow[reg_num][0]=data;
++      if (write_mode & WRITE_HW) {
++              if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
++                      printk("tas: I2C byte write failed \n");  
++                      return -1; 
++              }
++      }
++      return 0;
++}
++
++static inline int
++tas_sync_byte_register(       struct tas_data_t *self,
++                      uint reg_num,
++                      uint reg_width)
++{
++      if (reg_width==0 || self==NULL)
++              return -1;
++      if (i2c_smbus_write_byte_data(
++          self->client, reg_num, self->shadow[reg_num][0]) < 0) {
++              printk("tas: I2C byte write failed \n");
++              return -1;
++      }
++      return 0;
++}
++
++static inline int
++tas_read_register(    struct tas_data_t *self,
++                      uint reg_num,
++                      uint reg_width,
++                      char *data)
++{
++      if (reg_width==0 || data==NULL || self==NULL)
++              return -1;
++      memcpy(data,self->shadow[reg_num],reg_width);
++      return 0;
++}
++
++extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
++
++extern int tas_get_mixer_level(int mixer,uint *level);
++extern int tas_set_mixer_level(int mixer,uint level);
++extern int tas_enter_sleep(void);
++extern int tas_leave_sleep(void);
++extern int tas_supported_mixers(void);
++extern int tas_mixer_is_stereo(int mixer);
++extern int tas_stereo_mixers(void);
++extern int tas_output_device_change(int,int,int);
++extern int tas_device_ioctl(u_int, u_long);
++
++extern void tas_cleanup(void);
++extern int tas_init(int driver_id,const char *driver_name);
++extern int tas_post_init(void);
++
++#endif /* _TAS_COMMON_H_ */
++/*
++ * Local Variables:
++ * tab-width: 8
++ * indent-tabs-mode: t
++ * c-basic-offset: 8
++ * End:
++ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_eq_prefs.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_eq_prefs.h   2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_eq_prefs.h        2003-09-27 11:38:42.466072560 +0800
+@@ -0,0 +1,24 @@
++#ifndef _TAS_EQ_PREFS_H_
++#define _TAS_EQ_PREFS_H_
++
++struct tas_eq_pref_t {
++      u_int sample_rate;
++      u_int device_id;
++      u_int output_id;
++      u_int speaker_id;
++
++      struct tas_drce_t *drce;
++
++      u_int filter_count;
++      struct tas_biquad_ctrl_t *biquads;
++};
++
++#endif /* _TAS_EQ_PREFS_H_ */
++
++/*
++ * Local Variables:
++ * tab-width: 8
++ * indent-tabs-mode: t
++ * c-basic-offset: 8
++ * End:
++ */
+Index: linux-2.6.0-test5/sound/oss/dmasound/tas_ioctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/tas_ioctl.h      2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/tas_ioctl.h   2003-09-27 11:38:42.466072560 +0800
+@@ -0,0 +1,24 @@
++#ifndef _TAS_IOCTL_H_
++#define _TAS_IOCTL_H_
++
++#include <linux/i2c.h>
++#include <linux/soundcard.h>
++
++
++#define TAS_READ_EQ              _SIOR('t',0,struct tas_biquad_ctrl_t)
++#define TAS_WRITE_EQ             _SIOW('t',0,struct tas_biquad_ctrl_t)
++
++#define TAS_READ_EQ_LIST         _SIOR('t',1,struct tas_biquad_ctrl_t)
++#define TAS_WRITE_EQ_LIST        _SIOW('t',1,struct tas_biquad_ctrl_t)
++
++#define TAS_READ_EQ_FILTER_COUNT  _SIOR('t',2,int)
++#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int)
++
++#define TAS_READ_DRCE            _SIOR('t',4,struct tas_drce_ctrl_t)
++#define TAS_WRITE_DRCE           _SIOW('t',4,struct tas_drce_ctrl_t)
++
++#define TAS_READ_DRCE_CAPS       _SIOR('t',5,int)
++#define TAS_READ_DRCE_MIN        _SIOR('t',6,int)
++#define TAS_READ_DRCE_MAX        _SIOR('t',7,int)
++
++#endif
+Index: linux-2.6.0-test5/sound/oss/dmasound/trans_16.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/dmasound/trans_16.c       2003-09-27 11:38:18.496716456 +0800
++++ linux-2.6.0-test5/sound/oss/dmasound/trans_16.c    2003-09-27 11:38:42.468072256 +0800
+@@ -0,0 +1,679 @@
++/*
++ *  linux/drivers/sound/dmasound/trans_16.c
++ *
++ *  16 bit translation routines.  Only used by Power mac at present.
++ *
++ *  See linux/drivers/sound/dmasound/dmasound_core.c for copyright and
++ *  history prior to 08/02/2001.
++ *
++ *  08/02/2001 Iain Sandoe
++ *            split from dmasound_awacs.c
++ */
++
++#include <linux/soundcard.h>
++#include <asm/uaccess.h>
++#include "dmasound.h"
++
++static short dmasound_alaw2dma16[] ;
++static short dmasound_ulaw2dma16[] ;
++
++static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft);
++static ssize_t pmac_ct_s8(const u_char *userPtr, size_t userCount,
++                        u_char frame[], ssize_t *frameUsed,
++                        ssize_t frameLeft);
++static ssize_t pmac_ct_u8(const u_char *userPtr, size_t userCount,
++                        u_char frame[], ssize_t *frameUsed,
++                        ssize_t frameLeft);
++static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft);
++static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft);
++
++static ssize_t pmac_ctx_law(const u_char *userPtr, size_t userCount,
++                          u_char frame[], ssize_t *frameUsed,
++                          ssize_t frameLeft);
++static ssize_t pmac_ctx_s8(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft);
++static ssize_t pmac_ctx_u8(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft);
++static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
++                          u_char frame[], ssize_t *frameUsed,
++                          ssize_t frameLeft);
++static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
++                          u_char frame[], ssize_t *frameUsed,
++                          ssize_t frameLeft);
++
++static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft);
++static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft);
++
++/*** Translations ************************************************************/
++
++extern int expand_bal;        /* Balance factor for expanding (not volume!) */
++static int expand_data;       /* Data for expanding */
++
++static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft)
++{
++      short *table = dmasound.soft.format == AFMT_MU_LAW
++              ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
++      ssize_t count, used;
++      short *p = (short *) &frame[*frameUsed];
++      int val, stereo = dmasound.soft.stereo;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      while (count > 0) {
++              u_char data;
++              if (get_user(data, userPtr++))
++                      return -EFAULT;
++              val = table[data];
++              *p++ = val;
++              if (stereo) {
++                      if (get_user(data, userPtr++))
++                              return -EFAULT;
++                      val = table[data];
++              }
++              *p++ = val;
++              count--;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_s8(const u_char *userPtr, size_t userCount,
++                        u_char frame[], ssize_t *frameUsed,
++                        ssize_t frameLeft)
++{
++      ssize_t count, used;
++      short *p = (short *) &frame[*frameUsed];
++      int val, stereo = dmasound.soft.stereo;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      while (count > 0) {
++              u_char data;
++              if (get_user(data, userPtr++))
++                      return -EFAULT;
++              val = data << 8;
++              *p++ = val;
++              if (stereo) {
++                      if (get_user(data, userPtr++))
++                              return -EFAULT;
++                      val = data << 8;
++              }
++              *p++ = val;
++              count--;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_u8(const u_char *userPtr, size_t userCount,
++                        u_char frame[], ssize_t *frameUsed,
++                        ssize_t frameLeft)
++{
++      ssize_t count, used;
++      short *p = (short *) &frame[*frameUsed];
++      int val, stereo = dmasound.soft.stereo;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      while (count > 0) {
++              u_char data;
++              if (get_user(data, userPtr++))
++                      return -EFAULT;
++              val = (data ^ 0x80) << 8;
++              *p++ = val;
++              if (stereo) {
++                      if (get_user(data, userPtr++))
++                              return -EFAULT;
++                      val = (data ^ 0x80) << 8;
++              }
++              *p++ = val;
++              count--;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft)
++{
++      ssize_t count, used;
++      int stereo = dmasound.soft.stereo;
++      short *fp = (short *) &frame[*frameUsed];
++
++      frameLeft >>= 2;
++      userCount >>= (stereo? 2: 1);
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      if (!stereo) {
++              short *up = (short *) userPtr;
++              while (count > 0) {
++                      short data;
++                      if (get_user(data, up++))
++                              return -EFAULT;
++                      *fp++ = data;
++                      *fp++ = data;
++                      count--;
++              }
++      } else {
++              if (copy_from_user(fp, userPtr, count * 4))
++                      return -EFAULT;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 4: used * 2;
++}
++
++static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft)
++{
++      ssize_t count, used;
++      int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
++      int stereo = dmasound.soft.stereo;
++      short *fp = (short *) &frame[*frameUsed];
++      short *up = (short *) userPtr;
++
++      frameLeft >>= 2;
++      userCount >>= (stereo? 2: 1);
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      while (count > 0) {
++              short data;
++              if (get_user(data, up++))
++                      return -EFAULT;
++              data ^= mask;
++              *fp++ = data;
++              if (stereo) {
++                      if (get_user(data, up++))
++                              return -EFAULT;
++                      data ^= mask;
++              }
++              *fp++ = data;
++              count--;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 4: used * 2;
++}
++
++
++static ssize_t pmac_ctx_law(const u_char *userPtr, size_t userCount,
++                          u_char frame[], ssize_t *frameUsed,
++                          ssize_t frameLeft)
++{
++      unsigned short *table = (unsigned short *)
++              (dmasound.soft.format == AFMT_MU_LAW
++               ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
++      unsigned int data = expand_data;
++      unsigned int *p = (unsigned int *) &frame[*frameUsed];
++      int bal = expand_bal;
++      int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++      int utotal, ftotal;
++      int stereo = dmasound.soft.stereo;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      ftotal = frameLeft;
++      utotal = userCount;
++      while (frameLeft) {
++              u_char c;
++              if (bal < 0) {
++                      if (userCount == 0)
++                              break;
++                      if (get_user(c, userPtr++))
++                              return -EFAULT;
++                      data = table[c];
++                      if (stereo) {
++                              if (get_user(c, userPtr++))
++                                      return -EFAULT;
++                              data = (data << 16) + table[c];
++                      } else
++                              data = (data << 16) + data;
++                      userCount--;
++                      bal += hSpeed;
++              }
++              *p++ = data;
++              frameLeft--;
++              bal -= sSpeed;
++      }
++      expand_bal = bal;
++      expand_data = data;
++      *frameUsed += (ftotal - frameLeft) * 4;
++      utotal -= userCount;
++      return stereo? utotal * 2: utotal;
++}
++
++static ssize_t pmac_ctx_s8(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft)
++{
++      unsigned int *p = (unsigned int *) &frame[*frameUsed];
++      unsigned int data = expand_data;
++      int bal = expand_bal;
++      int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++      int stereo = dmasound.soft.stereo;
++      int utotal, ftotal;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      ftotal = frameLeft;
++      utotal = userCount;
++      while (frameLeft) {
++              u_char c;
++              if (bal < 0) {
++                      if (userCount == 0)
++                              break;
++                      if (get_user(c, userPtr++))
++                              return -EFAULT;
++                      data = c << 8;
++                      if (stereo) {
++                              if (get_user(c, userPtr++))
++                                      return -EFAULT;
++                              data = (data << 16) + (c << 8);
++                      } else
++                              data = (data << 16) + data;
++                      userCount--;
++                      bal += hSpeed;
++              }
++              *p++ = data;
++              frameLeft--;
++              bal -= sSpeed;
++      }
++      expand_bal = bal;
++      expand_data = data;
++      *frameUsed += (ftotal - frameLeft) * 4;
++      utotal -= userCount;
++      return stereo? utotal * 2: utotal;
++}
++
++
++static ssize_t pmac_ctx_u8(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft)
++{
++      unsigned int *p = (unsigned int *) &frame[*frameUsed];
++      unsigned int data = expand_data;
++      int bal = expand_bal;
++      int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++      int stereo = dmasound.soft.stereo;
++      int utotal, ftotal;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      ftotal = frameLeft;
++      utotal = userCount;
++      while (frameLeft) {
++              u_char c;
++              if (bal < 0) {
++                      if (userCount == 0)
++                              break;
++                      if (get_user(c, userPtr++))
++                              return -EFAULT;
++                      data = (c ^ 0x80) << 8;
++                      if (stereo) {
++                              if (get_user(c, userPtr++))
++                                      return -EFAULT;
++                              data = (data << 16) + ((c ^ 0x80) << 8);
++                      } else
++                              data = (data << 16) + data;
++                      userCount--;
++                      bal += hSpeed;
++              }
++              *p++ = data;
++              frameLeft--;
++              bal -= sSpeed;
++      }
++      expand_bal = bal;
++      expand_data = data;
++      *frameUsed += (ftotal - frameLeft) * 4;
++      utotal -= userCount;
++      return stereo? utotal * 2: utotal;
++}
++
++
++static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
++                          u_char frame[], ssize_t *frameUsed,
++                          ssize_t frameLeft)
++{
++      unsigned int *p = (unsigned int *) &frame[*frameUsed];
++      unsigned int data = expand_data;
++      unsigned short *up = (unsigned short *) userPtr;
++      int bal = expand_bal;
++      int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++      int stereo = dmasound.soft.stereo;
++      int utotal, ftotal;
++
++      frameLeft >>= 2;
++      userCount >>= (stereo? 2: 1);
++      ftotal = frameLeft;
++      utotal = userCount;
++      while (frameLeft) {
++              unsigned short c;
++              if (bal < 0) {
++                      if (userCount == 0)
++                              break;
++                      if (get_user(data, up++))
++                              return -EFAULT;
++                      if (stereo) {
++                              if (get_user(c, up++))
++                                      return -EFAULT;
++                              data = (data << 16) + c;
++                      } else
++                              data = (data << 16) + data;
++                      userCount--;
++                      bal += hSpeed;
++              }
++              *p++ = data;
++              frameLeft--;
++              bal -= sSpeed;
++      }
++      expand_bal = bal;
++      expand_data = data;
++      *frameUsed += (ftotal - frameLeft) * 4;
++      utotal -= userCount;
++      return stereo? utotal * 4: utotal * 2;
++}
++
++
++static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
++                          u_char frame[], ssize_t *frameUsed,
++                          ssize_t frameLeft)
++{
++      int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
++      unsigned int *p = (unsigned int *) &frame[*frameUsed];
++      unsigned int data = expand_data;
++      unsigned short *up = (unsigned short *) userPtr;
++      int bal = expand_bal;
++      int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
++      int stereo = dmasound.soft.stereo;
++      int utotal, ftotal;
++
++      frameLeft >>= 2;
++      userCount >>= (stereo? 2: 1);
++      ftotal = frameLeft;
++      utotal = userCount;
++      while (frameLeft) {
++              unsigned short c;
++              if (bal < 0) {
++                      if (userCount == 0)
++                              break;
++                      if (get_user(data, up++))
++                              return -EFAULT;
++                      data ^= mask;
++                      if (stereo) {
++                              if (get_user(c, up++))
++                                      return -EFAULT;
++                              data = (data << 16) + (c ^ mask);
++                      } else
++                              data = (data << 16) + data;
++                      userCount--;
++                      bal += hSpeed;
++              }
++              *p++ = data;
++              frameLeft--;
++              bal -= sSpeed;
++      }
++      expand_bal = bal;
++      expand_data = data;
++      *frameUsed += (ftotal - frameLeft) * 4;
++      utotal -= userCount;
++      return stereo? utotal * 4: utotal * 2;
++}
++
++/* data in routines... */
++
++static ssize_t pmac_ct_s8_read(const u_char *userPtr, size_t userCount,
++                        u_char frame[], ssize_t *frameUsed,
++                        ssize_t frameLeft)
++{
++      ssize_t count, used;
++      short *p = (short *) &frame[*frameUsed];
++      int val, stereo = dmasound.soft.stereo;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      while (count > 0) {
++              u_char data;
++
++              val = *p++;
++              data = val >> 8;
++              if (put_user(data, (u_char *)userPtr++))
++                      return -EFAULT;
++              if (stereo) {
++                      val = *p;
++                      data = val >> 8;
++                      if (put_user(data, (u_char *)userPtr++))
++                              return -EFAULT;
++              }
++              p++;
++              count--;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 2: used;
++}
++
++
++static ssize_t pmac_ct_u8_read(const u_char *userPtr, size_t userCount,
++                        u_char frame[], ssize_t *frameUsed,
++                        ssize_t frameLeft)
++{
++      ssize_t count, used;
++      short *p = (short *) &frame[*frameUsed];
++      int val, stereo = dmasound.soft.stereo;
++
++      frameLeft >>= 2;
++      if (stereo)
++              userCount >>= 1;
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      while (count > 0) {
++              u_char data;
++
++              val = *p++;
++              data = (val >> 8) ^ 0x80;
++              if (put_user(data, (u_char *)userPtr++))
++                      return -EFAULT;
++              if (stereo) {
++                      val = *p;
++                      data = (val >> 8) ^ 0x80;
++                      if (put_user(data, (u_char *)userPtr++))
++                              return -EFAULT;
++              }
++              p++;
++              count--;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 2: used;
++}
++
++static ssize_t pmac_ct_s16_read(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft)
++{
++      ssize_t count, used;
++      int stereo = dmasound.soft.stereo;
++      short *fp = (short *) &frame[*frameUsed];
++
++      frameLeft >>= 2;
++      userCount >>= (stereo? 2: 1);
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      if (!stereo) {
++              short *up = (short *) userPtr;
++              while (count > 0) {
++                      short data;
++                      data = *fp;
++                      if (put_user(data, up++))
++                              return -EFAULT;
++                      fp+=2;
++                      count--;
++              }
++      } else {
++              if (copy_to_user((u_char *)userPtr, fp, count * 4))
++                      return -EFAULT;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 4: used * 2;
++}
++
++static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
++                         u_char frame[], ssize_t *frameUsed,
++                         ssize_t frameLeft)
++{
++      ssize_t count, used;
++      int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
++      int stereo = dmasound.soft.stereo;
++      short *fp = (short *) &frame[*frameUsed];
++      short *up = (short *) userPtr;
++
++      frameLeft >>= 2;
++      userCount >>= (stereo? 2: 1);
++      used = count = min_t(unsigned long, userCount, frameLeft);
++      while (count > 0) {
++              int data;
++
++              data = *fp++;
++              data ^= mask;
++              if (put_user(data, up++))
++                      return -EFAULT;
++              if (stereo) {
++                      data = *fp;
++                      data ^= mask;
++                      if (put_user(data, up++))
++                              return -EFAULT;
++              }
++              fp++;
++              count--;
++      }
++      *frameUsed += used * 4;
++      return stereo? used * 4: used * 2;
++}
++
++TRANS transAwacsNormal = {
++      ct_ulaw:        pmac_ct_law,
++      ct_alaw:        pmac_ct_law,
++      ct_s8:          pmac_ct_s8,
++      ct_u8:          pmac_ct_u8,
++      ct_s16be:       pmac_ct_s16,
++      ct_u16be:       pmac_ct_u16,
++      ct_s16le:       pmac_ct_s16,
++      ct_u16le:       pmac_ct_u16,
++};
++
++TRANS transAwacsExpand = {
++      ct_ulaw:        pmac_ctx_law,
++      ct_alaw:        pmac_ctx_law,
++      ct_s8:          pmac_ctx_s8,
++      ct_u8:          pmac_ctx_u8,
++      ct_s16be:       pmac_ctx_s16,
++      ct_u16be:       pmac_ctx_u16,
++      ct_s16le:       pmac_ctx_s16,
++      ct_u16le:       pmac_ctx_u16,
++};
++
++TRANS transAwacsNormalRead = {
++      ct_s8:          pmac_ct_s8_read,
++      ct_u8:          pmac_ct_u8_read,
++      ct_s16be:       pmac_ct_s16_read,
++      ct_u16be:       pmac_ct_u16_read,
++      ct_s16le:       pmac_ct_s16_read,
++      ct_u16le:       pmac_ct_u16_read,
++};
++
++/* translation tables */
++/* 16 bit mu-law */
++
++static short dmasound_ulaw2dma16[] = {
++      -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
++      -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
++      -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
++      -11900, -11388, -10876, -10364, -9852,  -9340,  -8828,  -8316,
++      -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
++      -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
++      -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
++      -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
++      -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
++      -1372,  -1308,  -1244,  -1180,  -1116,  -1052,  -988,   -924,
++      -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
++      -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
++      -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
++      -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
++      -120,   -112,   -104,   -96,    -88,    -80,    -72,    -64,
++      -56,    -48,    -40,    -32,    -24,    -16,    -8,     0,
++      32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
++      23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
++      15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
++      11900,  11388,  10876,  10364,  9852,   9340,   8828,   8316,
++      7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
++      5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
++      3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
++      2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
++      1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
++      1372,   1308,   1244,   1180,   1116,   1052,   988,    924,
++      876,    844,    812,    780,    748,    716,    684,    652,
++      620,    588,    556,    524,    492,    460,    428,    396,
++      372,    356,    340,    324,    308,    292,    276,    260,
++      244,    228,    212,    196,    180,    164,    148,    132,
++      120,    112,    104,    96,     88,     80,     72,     64,
++      56,     48,     40,     32,     24,     16,     8,      0,
++};
++
++/* 16 bit A-law */
++
++static short dmasound_alaw2dma16[] = {
++      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
++      -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
++      -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
++      -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
++      -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
++      -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
++      -11008, -10496, -12032, -11520, -8960,  -8448,  -9984,  -9472,
++      -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
++      -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
++      -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
++      -88,    -72,    -120,   -104,   -24,    -8,     -56,    -40,
++      -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
++      -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
++      -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
++      -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
++      -944,   -912,   -1008,  -976,   -816,   -784,   -880,   -848,
++      5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
++      7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
++      2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
++      3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
++      22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
++      30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
++      11008,  10496,  12032,  11520,  8960,   8448,   9984,   9472,
++      15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
++      344,    328,    376,    360,    280,    264,    312,    296,
++      472,    456,    504,    488,    408,    392,    440,    424,
++      88,     72,     120,    104,    24,     8,      56,     40,
++      216,    200,    248,    232,    152,    136,    184,    168,
++      1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
++      1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
++      688,    656,    752,    720,    560,    528,    624,    592,
++      944,    912,    1008,   976,    816,    784,    880,    848,
++};
+Index: linux-2.6.0-test5/sound/oss/forte.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/forte.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/forte.c        2003-09-27 11:38:42.572056448 +0800
+@@ -37,7 +37,6 @@
+ #include <linux/delay.h>
+ #include <linux/poll.h>
+-#include <linux/kernel.h>
+ #include <linux/sound.h>
+ #include <linux/ac97_codec.h>
+Index: linux-2.6.0-test5/sound/oss/i810_audio.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/i810_audio.c      2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/i810_audio.c   2003-09-27 11:38:42.761027720 +0800
+@@ -2728,7 +2728,7 @@
+                     i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
+       /* wait for analog ready */
+-      for (i=10; i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--)
++      for (i=100; i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--)
+       {
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(HZ/20);
+@@ -3091,10 +3091,17 @@
+               return -EIO;
+       if (pci_set_dma_mask(pci_dev, I810_DMA_MASK)) {
+-              printk(KERN_ERR "intel810: architecture does not support"
++              printk(KERN_ERR "i810_audio: architecture does not support"
+                      " 32bit PCI busmaster DMA\n");
+               return -ENODEV;
+       }
++      
++      if( pci_resource_start(pci_dev, 1) == 0)
++      {
++              /* MMIO only ICH5 .. here be dragons .. */
++              printk(KERN_ERR "i810_audio: Pure MMIO interfaces not yet supported.\n");
++              return -ENODEV;
++      }
+       if ((card = kmalloc(sizeof(struct i810_card), GFP_KERNEL)) == NULL) {
+               printk(KERN_ERR "i810_audio: out of memory\n");
+Index: linux-2.6.0-test5/sound/oss/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/Kconfig   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/Kconfig        2003-09-27 11:38:43.119973152 +0800
+@@ -237,13 +237,6 @@
+       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
+-      help
+-        Say Y or M if you have a Hammerfall, Hammerfall light or Hammerfall
+-        DSP card from RME.
+-
+ config SOUND_SONICVIBES
+       tristate "S3 SonicVibes"
+       depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT
+Index: linux-2.6.0-test5/sound/oss/nec_vrc5477.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/nec_vrc5477.c     2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/nec_vrc5477.c  2003-09-27 11:38:43.583902624 +0800
+@@ -96,7 +96,6 @@
+ #endif
+ #if defined(VRC5477_AC97_DEBUG)
+-#include <linux/kernel.h>
+ #define ASSERT(x)  if (!(x)) { \
+       panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+ #else
+Index: linux-2.6.0-test5/sound/oss/rme96xx.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/rme96xx.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/rme96xx.c      2003-09-27 11:38:43.847862496 +0800
+@@ -54,7 +54,6 @@
+ #include <linux/smp_lock.h>
+ #include <linux/delay.h>
+ #include <linux/slab.h>
+-#include <asm/dma.h>
+ #include <asm/hardirq.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+Index: linux-2.6.0-test5/sound/oss/vwsnd.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/oss/vwsnd.c   2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/oss/vwsnd.c        2003-09-27 11:38:43.977842736 +0800
+@@ -158,8 +158,6 @@
+ #ifdef VWSND_DEBUG
+-#include <linux/interrupt.h>          /* for in_interrupt() */
+-
+ static int shut_up = 1;
+ /*
+Index: linux-2.6.0-test5/sound/pci/ens1370.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/pci/ens1370.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/pci/ens1370.c      2003-09-27 11:38:44.106823128 +0800
+@@ -47,6 +47,13 @@
+ #define CHIP1370
+ #endif
++#ifdef CHIP1370
++#define DRIVER_NAME "ENS1370"
++#else
++#define DRIVER_NAME "ENS1371"
++#endif
++
++
+ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Thomas Sailer <sailer@ife.ee.ethz.ch>");
+ MODULE_LICENSE("GPL");
+ MODULE_CLASSES("{sound}");
+@@ -2324,12 +2331,8 @@
+               snd_card_free(card);
+               return err;
+       }
+-#ifdef CHIP1370
+-      strcpy(card->driver, "ENS1370");
+-#endif
+-#ifdef CHIP1371
+-      strcpy(card->driver, "ENS1371");
+-#endif
++      strcpy(card->driver, DRIVER_NAME);
++
+       strcpy(card->shortname, "Ensoniq AudioPCI");
+       sprintf(card->longname, "%s %s at 0x%lx, irq %i",
+               card->shortname,
+@@ -2354,7 +2357,7 @@
+ }
+ static struct pci_driver driver = {
+-      .name = "Ensoniq AudioPCI",
++      .name = DRIVER_NAME,
+       .id_table = snd_audiopci_ids,
+       .probe = snd_audiopci_probe,
+       .remove = __devexit_p(snd_audiopci_remove),
+Index: linux-2.6.0-test5/sound/pci/intel8x0.c
+===================================================================
+--- linux-2.6.0-test5.orig/sound/pci/intel8x0.c        2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/sound/pci/intel8x0.c     2003-09-27 11:38:44.188810664 +0800
+@@ -2231,10 +2231,8 @@
+       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;
+Index: linux-2.6.0-test5/usr/gen_init_cpio.c
+===================================================================
+--- linux-2.6.0-test5.orig/usr/gen_init_cpio.c 2003-09-26 14:32:03.000000000 +0800
++++ linux-2.6.0-test5/usr/gen_init_cpio.c      2003-09-27 11:38:44.576751688 +0800
+@@ -212,7 +212,7 @@
+ int main (int argc, char *argv[])
+ {
+-      cpio_mkdir("/dev", 0700, 0, 0);
++      cpio_mkdir("/dev", 0755, 0, 0);
+       cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1);
+       cpio_mkdir("/root", 0700, 0, 0);
+       cpio_trailer();
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 (file)
index 0000000..453e086
--- /dev/null
@@ -0,0 +1,760 @@
+Index: linux-2.6.0-test5/drivers/dump/dump_netdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_netdev.c  2003-09-27 21:53:32.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_netdev.c       2003-09-30 22:26:22.709337152 +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,26 @@
+ #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;
++      
++      __req = (req_t *)msg;
+-      /* 
+-       * First check if were are dumping or doing startup handshake, if
+-       * not quickly return.
+-       */
+-      if (!netdump_in_progress)
+-              return NET_RX_SUCCESS;
+-
+-      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 +89,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 +125,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 +133,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 +173,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 +247,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 +277,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 +296,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 +308,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 +317,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 +332,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 +340,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 +352,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 +406,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 +434,7 @@
+ err2:
+       in_dev_put(dump_in_dev);
+ err1:
+-      dev_put(dump_ndev);     
++      dev_put(np.dev);        
+       return retval;
+ }
+@@ -707,8 +447,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 +460,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 +479,7 @@
+       reply_t reply;
+       char tmp[200];
+-        if (!dump_ndev)
++        if (!np.dev)
+               return (0);
+       sprintf(tmp, "NETDUMP end.\n");
+@@ -748,11 +487,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 +547,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 +569,7 @@
+       default:
+               return -EINVAL;
+       }
++      #endif
+       return 0;
+ }
+@@ -851,17 +591,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 +621,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/export-netpoll.patch b/lustre/kernel_patches/patches/export-netpoll.patch
new file mode 100644 (file)
index 0000000..6d30941
--- /dev/null
@@ -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/kexec-2.6.0-test5-full.patch b/lustre/kernel_patches/patches/kexec-2.6.0-test5-full.patch
new file mode 100644 (file)
index 0000000..7cbafc1
--- /dev/null
@@ -0,0 +1,1463 @@
+ 0 files changed
+
+Index: linux-2.6.0-test5/MAINTAINERS
+===================================================================
+--- linux-2.6.0-test5.orig/MAINTAINERS 2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/MAINTAINERS      2003-09-26 15:56:27.000000000 +0800
+@@ -1165,6 +1165,17 @@
+ W:    http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
+ S:    Maintained
++KEXEC
++P:    Eric Biederman
++M:    ebiederm@xmission.com
++M:    ebiederman@lnxi.com
++W:    http://www.xmission.com/~ebiederm/files/kexec/
++P:    Andy Pfiffer
++M:    andyp@osdl.org
++W:    http://www.osdl.org/archive/andyp/bloom/Code/Linux/Kexec/
++L:    linux-kernel@vger.kernel.org
++S:    Maintained
++
+ LANMEDIA WAN CARD DRIVER
+ P:    Andrew Stanley-Jones
+ M:    asj@lanmedia.com
+Index: linux-2.6.0-test5/arch/i386/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/Kconfig   2003-09-26 15:56:18.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/Kconfig        2003-09-26 15:56:27.000000000 +0800
+@@ -846,6 +846,23 @@
+       depends on ((X86_SUMMIT || X86_GENERICARCH) && NUMA)
+       default y
++config KEXEC
++      bool "kexec system call (EXPERIMENTAL)"
++      depends on EXPERIMENTAL
++      help
++        kexec is a system call that implements the ability to  shutdown your
++        current kernel, and to start another kernel.  It is like a reboot
++        but it is indepedent of the system firmware.   And like a reboot
++        you can start any kernel with it not just Linux.  
++      
++        The name comes from the similiarity to the exec system call. 
++      
++        It is on an going process to be certain the hardware in a machine
++        is properly shutdown, so do not be surprised if this code does not
++        initially work for you.  It may help to enable device hotplugging
++        support.  As of this writing the exact hardware interface is
++        strongly in flux, so no good recommendation can be made.
++
+ endmenu
+Index: linux-2.6.0-test5/arch/i386/defconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/defconfig 2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/defconfig      2003-09-26 15:56:27.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
+Index: linux-2.6.0-test5/arch/i386/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/Makefile   2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/Makefile        2003-09-26 15:56:27.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_X86_NUMAQ)               += numaq.o
+ obj-$(CONFIG_X86_SUMMIT)      += summit.o
+ obj-$(CONFIG_EDD)                     += edd.o
+Index: linux-2.6.0-test5/arch/i386/kernel/apic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/apic.c     2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/apic.c  2003-09-26 15:56:27.000000000 +0800
+@@ -26,6 +26,7 @@
+ #include <linux/mc146818rtc.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/sysdev.h>
++#include <linux/reboot.h>
+ #include <asm/atomic.h>
+ #include <asm/smp.h>
+@@ -183,6 +184,39 @@
+               outb(0x70, 0x22);
+               outb(0x00, 0x23);
+       }
++#ifdef        CONFIG_KEXEC
++      else {
++              /* Go back to Virtual Wire compatibility mode */
++              unsigned long value;
++
++              /* For the spurious interrupt use vector F, and enable it */
++              value = apic_read(APIC_SPIV);
++              value &= ~APIC_VECTOR_MASK; 
++              value |= APIC_SPIV_APIC_ENABLED;
++              value |= 0xf;
++              apic_write_around(APIC_SPIV, value);
++
++              /* For LVT0 make it edge triggered, active high, external and enabled */
++              value = apic_read(APIC_LVT0);
++              value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | 
++                      APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | 
++                      APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
++              value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
++              value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXINT);
++              apic_write_around(APIC_LVT0, value);
++              
++              /* For LVT1 make it edge triggered, active high, nmi and enabled */
++              value = apic_read(APIC_LVT1);
++              value &= ~(
++                      APIC_MODE_MASK | APIC_SEND_PENDING | 
++                      APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | 
++                      APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
++              value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
++              value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
++              apic_write_around(APIC_LVT1, value);
++      }
++#endif        /* CONFIG_KEXEC */
++
+ }
+ void disable_local_APIC(void)
+@@ -1147,6 +1181,26 @@
+       irq_exit();
+ }
++void stop_apics(void)
++{
++      /* By resetting the APIC's we disable the nmi watchdog */
++#if CONFIG_SMP
++      /*
++       * Stop all CPUs and turn off local APICs and the IO-APIC, so
++       * other OSs see a clean IRQ state.
++       */
++      smp_send_stop();
++#else
++      disable_local_APIC();
++#endif
++#if defined(CONFIG_X86_IO_APIC)
++      if (smp_found_config) {
++              disable_IO_APIC();
++      }
++#endif
++      disconnect_bsp_APIC();
++}
++
+ /*
+  * This initializes the IO-APIC and APIC hardware if this is
+  * a UP kernel.
+Index: linux-2.6.0-test5/arch/i386/kernel/dmi_scan.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/dmi_scan.c 2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/dmi_scan.c      2003-09-26 15:56:27.000000000 +0800
+@@ -222,31 +222,6 @@
+       return 0;
+ }
+-/*
+- * Some machines require the "reboot=s"  commandline option, this quirk makes that automatic.
+- */
+-static __init int set_smp_reboot(struct dmi_blacklist *d)
+-{
+-#ifdef CONFIG_SMP
+-      extern int reboot_smp;
+-      if (reboot_smp == 0)
+-      {
+-              reboot_smp = 1;
+-              printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
+-      }
+-#endif
+-      return 0;
+-}
+-
+-/*
+- * Some machines require the "reboot=b,s"  commandline option, this quirk makes that automatic.
+- */
+-static __init int set_smp_bios_reboot(struct dmi_blacklist *d)
+-{
+-      set_smp_reboot(d);
+-      set_bios_reboot(d);
+-      return 0;
+-}
+ /*
+  * Some bioses have a broken protected mode poweroff and need to use realmode
+@@ -581,7 +556,7 @@
+                       MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
+                       MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH
+                       } },
+-      { set_smp_bios_reboot, "Dell PowerEdge 1300", { /* Handle problems with rebooting on Dell 1300's */
++      { set_bios_reboot, "Dell PowerEdge 1300", {     /* Handle problems with rebooting on Dell 1300's */
+                       MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+                       MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
+                       NO_MATCH, NO_MATCH
+Index: linux-2.6.0-test5/arch/i386/kernel/entry.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/entry.S    2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/entry.S 2003-09-26 15:56:27.000000000 +0800
+@@ -1045,6 +1045,7 @@
+       .long sys_tgkill        /* 270 */
+       .long sys_utimes
+       .long sys_fadvise64_64
++        .long sys_kexec_load
+ nr_syscalls=(.-sys_call_table)/4
+Index: linux-2.6.0-test5/arch/i386/kernel/i8259.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/i8259.c    2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/i8259.c 2003-09-26 15:56:27.000000000 +0800
+@@ -244,9 +244,21 @@
+       return 0;
+ }
++static int i8259A_shutdown(struct sys_device *dev)
++{
++      /* Put the i8259A into a quiescent state that
++       * the kernel initialization code can get it
++       * out of.
++       */
++      outb(0xff, 0x21);       /* mask all of 8259A-1 */
++      outb(0xff, 0xA1);       /* mask all of 8259A-1 */
++      return 0;
++}
++
+ static struct sysdev_class i8259_sysdev_class = {
+       set_kset_name("i8259"),
+       .resume = i8259A_resume,
++      .shutdown = i8259A_shutdown,
+ };
+ static struct sys_device device_i8259A = {
+Index: linux-2.6.0-test5/arch/i386/kernel/io_apic.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/io_apic.c  2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/io_apic.c       2003-09-26 15:56:27.000000000 +0800
+@@ -1602,8 +1602,6 @@
+        * Clear the IO-APIC before rebooting:
+        */
+       clear_IO_APIC();
+-
+-      disconnect_bsp_APIC();
+ }
+ /*
+Index: linux-2.6.0-test5/arch/i386/kernel/machine_kexec.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/machine_kexec.c    2003-09-26 15:56:27.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/machine_kexec.c 2003-09-26 15:56:27.000000000 +0800
+@@ -0,0 +1,116 @@
++#include <linux/config.h>
++#include <linux/mm.h>
++#include <linux/kexec.h>
++#include <linux/delay.h>
++#include <asm/pgtable.h>
++#include <asm/pgalloc.h>
++#include <asm/tlbflush.h>
++#include <asm/mmu_context.h>
++#include <asm/io.h>
++#include <asm/apic.h>
++
++
++/*
++ * machine_kexec
++ * =======================
++ */
++
++
++static void set_idt(void *newidt, __u16 limit)
++{
++      unsigned char curidt[6];
++
++      /* ia32 supports unaliged loads & stores */
++      (*(__u16 *)(curidt)) = limit;
++      (*(__u32 *)(curidt +2)) = (unsigned long)(newidt);
++
++      __asm__ __volatile__ (
++              "lidt %0\n" 
++              : "=m" (curidt)
++              );
++};
++
++
++static void set_gdt(void *newgdt, __u16 limit)
++{
++      unsigned char curgdt[6];
++
++      /* ia32 supports unaliged loads & stores */
++      (*(__u16 *)(curgdt)) = limit;
++      (*(__u32 *)(curgdt +2)) = (unsigned long)(newgdt);
++
++      __asm__ __volatile__ (
++              "lgdt %0\n" 
++              : "=m" (curgdt)
++              );
++};
++
++static void load_segments(void)
++{
++#define __STR(X) #X
++#define STR(X) __STR(X)
++
++      __asm__ __volatile__ (
++              "\tljmp $"STR(__KERNEL_CS)",$1f\n"
++              "\t1:\n"
++              "\tmovl $"STR(__KERNEL_DS)",%eax\n"
++              "\tmovl %eax,%ds\n"
++              "\tmovl %eax,%es\n"
++              "\tmovl %eax,%fs\n"
++              "\tmovl %eax,%gs\n"
++              "\tmovl %eax,%ss\n"
++              );
++#undef STR
++#undef __STR
++}
++
++typedef void (*relocate_new_kernel_t)(
++      unsigned long indirection_page, unsigned long reboot_code_buffer,
++      unsigned long start_address);
++
++const extern unsigned char relocate_new_kernel[];
++extern void relocate_new_kernel_end(void);
++const extern unsigned int relocate_new_kernel_size;
++extern void use_mm(struct mm_struct *mm);
++
++void machine_kexec(struct kimage *image)
++{
++      unsigned long indirection_page;
++      unsigned long reboot_code_buffer;
++      relocate_new_kernel_t rnk;
++
++      /* switch to an mm where the reboot_code_buffer is identity mapped */
++      use_mm(&init_mm);
++      stop_apics();
++
++      /* Interrupts aren't acceptable while we reboot */
++      local_irq_disable();
++      reboot_code_buffer = page_to_pfn(image->reboot_code_pages) << PAGE_SHIFT;
++      indirection_page = image->head & PAGE_MASK;
++
++      /* copy it out */
++      memcpy((void *)reboot_code_buffer, relocate_new_kernel, relocate_new_kernel_size);
++
++      /* The segment registers are funny things, they are
++       * automatically loaded from a table, in memory wherever you
++       * set them to a specific selector, but this table is never
++       * accessed again you set the segment to a different selector.
++       *
++       * The more common model is are caches where the behide
++       * the scenes work is done, but is also dropped at arbitrary
++       * times.
++       *
++       * I take advantage of this here by force loading the
++       * segments, before I zap the gdt with an invalid value.
++       */
++      load_segments();
++      /* The gdt & idt are now invalid.
++       * If you want to load them you must set up your own idt & gdt.
++       */
++      set_gdt(phys_to_virt(0),0);
++      set_idt(phys_to_virt(0),0);
++
++      /* now call it */
++      rnk = (relocate_new_kernel_t) reboot_code_buffer;
++      (*rnk)(indirection_page, reboot_code_buffer, image->start);
++}
+Index: linux-2.6.0-test5/arch/i386/kernel/reboot.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/reboot.c   2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/reboot.c        2003-09-26 15:56:27.000000000 +0800
+@@ -20,8 +20,7 @@
+ int reboot_thru_bios;
+ #ifdef CONFIG_SMP
+-int reboot_smp = 0;
+-static int reboot_cpu = -1;
++int reboot_cpu = -1;    /* specifies the internal linux cpu id, not the apicid */
+ /* shamelessly grabbed from lib/vsprintf.c for readability */
+ #define is_digit(c)   ((c) >= '0' && (c) <= '9')
+ #endif
+@@ -43,7 +42,6 @@
+                       break;
+ #ifdef CONFIG_SMP
+               case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
+-                      reboot_smp = 1;
+                       if (is_digit(*(str+1))) {
+                               reboot_cpu = (int) (*(str+1) - '0');
+                               if (is_digit(*(str+2))) 
+@@ -216,51 +214,7 @@
+ void machine_restart(char * __unused)
+ {
+-#ifdef CONFIG_SMP
+-      int cpuid;
+-      
+-      cpuid = GET_APIC_ID(apic_read(APIC_ID));
+-
+-      if (reboot_smp) {
+-
+-              /* check to see if reboot_cpu is valid 
+-                 if its not, default to the BSP */
+-              if ((reboot_cpu == -1) ||  
+-                    (reboot_cpu > (NR_CPUS -1))  || 
+-                    !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*/
+-              /* re-run this function on the other CPUs
+-                 it will fall though this section since we have 
+-                 cleared reboot_smp, and do the reboot if it is the
+-                 correct CPU, otherwise it halts. */
+-              if (reboot_cpu != cpuid)
+-                      smp_call_function((void *)machine_restart , NULL, 1, 0);
+-      }
+-
+-      /* if reboot_cpu is still -1, then we want a tradional reboot, 
+-         and if we are not running on the reboot_cpu,, halt */
+-      if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
+-              for (;;)
+-              __asm__ __volatile__ ("hlt");
+-      }
+-      /*
+-       * Stop all CPUs and turn off local APICs and the IO-APIC, so
+-       * 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 */
+               *((unsigned short *)__va(0x472)) = reboot_mode;
+@@ -277,10 +231,12 @@
+ void machine_halt(void)
+ {
++      stop_apics();
+ }
+ void machine_power_off(void)
+ {
++      stop_apics();
+       if (pm_power_off)
+               pm_power_off();
+ }
+Index: linux-2.6.0-test5/arch/i386/kernel/relocate_kernel.S
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/relocate_kernel.S  2003-09-26 15:56:27.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/relocate_kernel.S       2003-09-26 15:56:27.000000000 +0800
+@@ -0,0 +1,107 @@
++#include <linux/config.h>
++#include <linux/linkage.h>
++
++      /* Must be relocatable PIC code callable as a C function, that once
++       * it starts can not use the previous processes stack.
++       *
++       */
++      .globl relocate_new_kernel
++relocate_new_kernel:
++      /* read the arguments and say goodbye to the stack */
++      movl  4(%esp), %ebx /* indirection_page */
++      movl  8(%esp), %ebp /* reboot_code_buffer */
++      movl  12(%esp), %edx /* start address */
++
++      /* zero out flags, and disable interrupts */
++      pushl $0
++      popfl
++
++      /* set a new stack at the bottom of our page... */
++      lea   4096(%ebp), %esp
++
++      /* store the parameters back on the stack */
++      pushl   %edx /* store the start address */
++
++      /* Set cr0 to a known state:
++       * 31 0 == Paging disabled
++       * 18 0 == Alignment check disabled
++       * 16 0 == Write protect disabled
++       * 3  0 == No task switch
++       * 2  0 == Don't do FP software emulation.
++       * 0  1 == Proctected mode enabled
++       */
++      movl    %cr0, %eax
++      andl    $~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax
++      orl     $(1<<0), %eax
++      movl    %eax, %cr0
++      
++      /* Set cr4 to a known state:
++       * Setting everything to zero seems safe.
++       */
++      movl    %cr4, %eax
++      andl    $0, %eax
++      movl    %eax, %cr4
++      
++      jmp 1f
++1:    
++
++      /* Flush the TLB (needed?) */
++      xorl    %eax, %eax
++      movl    %eax, %cr3
++
++      /* Do the copies */
++      cld
++0:    /* top, read another word for the indirection page */
++      movl    %ebx, %ecx
++      movl    (%ebx), %ecx
++      addl    $4, %ebx
++      testl   $0x1,   %ecx  /* is it a destination page */
++      jz      1f
++      movl    %ecx,   %edi
++      andl    $0xfffff000, %edi
++      jmp     0b
++1:
++      testl   $0x2,   %ecx  /* is it an indirection page */
++      jz      1f
++      movl    %ecx,   %ebx
++      andl    $0xfffff000, %ebx
++      jmp     0b
++1:
++      testl   $0x4,   %ecx /* is it the done indicator */
++      jz      1f
++      jmp     2f
++1:
++      testl   $0x8,   %ecx /* is it the source indicator */
++      jz      0b           /* Ignore it otherwise */
++      movl    %ecx,   %esi /* For every source page do a copy */
++      andl    $0xfffff000, %esi
++
++      movl    $1024, %ecx
++      rep ; movsl
++      jmp     0b
++
++2:
++
++      /* To be certain of avoiding problems with self modifying code
++       * I need to execute a serializing instruction here.
++       * So I flush the TLB, it's handy, and not processor dependent.
++       */
++      xorl    %eax, %eax
++      movl    %eax, %cr3
++      
++      /* set all of the registers to known values */
++      /* leave %esp alone */
++      
++      xorl    %eax, %eax
++      xorl    %ebx, %ebx
++      xorl    %ecx, %ecx
++      xorl    %edx, %edx
++      xorl    %esi, %esi
++      xorl    %edi, %edi
++      xorl    %ebp, %ebp
++      ret
++relocate_new_kernel_end:
++
++      .globl relocate_new_kernel_size
++relocate_new_kernel_size:     
++      .long relocate_new_kernel_end - relocate_new_kernel
+Index: linux-2.6.0-test5/arch/i386/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/smp.c      2003-09-26 15:56:18.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/smp.c   2003-09-26 15:56:27.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;
++
++      /* See if there has been give a command line override .
++       */
++      if ((reboot_cpu != -1) && !(reboot_cpu >= NR_CPUS) && 
++              test_bit(reboot_cpu, &cpu_online_map)) {
++              reboot_cpu_id = reboot_cpu;
++      }
++       
++      /* Make certain the the cpu I'm rebooting on is online */
++      if (!test_bit(reboot_cpu_id, &cpu_online_map)) {
++              reboot_cpu_id = smp_processor_id();
++      }
++
++      /* Make certain I only run on the appropriate processor */
++      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.
++       */
+       smp_call_function(stop_this_cpu, NULL, 1, 0);
+       local_irq_disable();
+Index: linux-2.6.0-test5/include/asm-i386/apic.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/apic.h     2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/apic.h  2003-09-26 15:56:27.000000000 +0800
+@@ -99,6 +99,9 @@
+ #define NMI_LOCAL_APIC        2
+ #define NMI_INVALID   3
++extern void stop_apics(void);
++#else
++static inline void stop_apics(void) { }
+ #endif /* CONFIG_X86_LOCAL_APIC */
+ #endif /* __ASM_APIC_H */
+Index: linux-2.6.0-test5/include/asm-i386/apicdef.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/apicdef.h  2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/apicdef.h       2003-09-26 15:56:27.000000000 +0800
+@@ -86,6 +86,7 @@
+ #define                       APIC_LVT_REMOTE_IRR             (1<<14)
+ #define                       APIC_INPUT_POLARITY             (1<<13)
+ #define                       APIC_SEND_PENDING               (1<<12)
++#define                       APIC_MODE_MASK                  0x700
+ #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
+Index: linux-2.6.0-test5/include/asm-i386/kexec.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kexec.h    2003-09-26 15:56:27.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/kexec.h 2003-09-26 15:56:27.000000000 +0800
+@@ -0,0 +1,23 @@
++#ifndef _I386_KEXEC_H
++#define _I386_KEXEC_H
++
++#include <asm/fixmap.h>
++
++/*
++ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
++ * I.e. Maximum page that is mapped directly into kernel memory,
++ * and kmap is not required.
++ *
++ * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
++ * calculation for the amount of memory directly mappable into the
++ * kernel memory space.
++ */
++
++/* Maximum physical address we can use pages from */
++#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
++/* Maximum address we can reach in physical address mode */
++#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
++
++#define KEXEC_REBOOT_CODE_SIZE        4096
++
++#endif /* _I386_KEXEC_H */
+Index: linux-2.6.0-test5/include/asm-i386/unistd.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/unistd.h   2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/unistd.h        2003-09-26 15:56:27.000000000 +0800
+@@ -278,8 +278,9 @@
+ #define __NR_tgkill           270
+ #define __NR_utimes           271
+ #define __NR_fadvise64_64     272
+-
+-#define NR_syscalls 273
++#define __NR_sys_kexec_load   273
++   
++#define NR_syscalls 274
+ /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
+Index: linux-2.6.0-test5/include/linux/kexec.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/kexec.h       2003-09-26 15:56:27.000000000 +0800
++++ linux-2.6.0-test5/include/linux/kexec.h    2003-09-26 15:56:27.000000000 +0800
+@@ -0,0 +1,54 @@
++#ifndef LINUX_KEXEC_H
++#define LINUX_KEXEC_H
++
++#if CONFIG_KEXEC
++#include <linux/types.h>
++#include <linux/list.h>
++#include <asm/kexec.h>
++
++/* 
++ * This structure is used to hold the arguments that are used when loading
++ * kernel binaries.
++ */
++
++typedef unsigned long kimage_entry_t;
++#define IND_DESTINATION  0x1
++#define IND_INDIRECTION  0x2
++#define IND_DONE         0x4
++#define IND_SOURCE       0x8
++
++#define KEXEC_SEGMENT_MAX 8
++struct kexec_segment {
++      void *buf;
++      size_t bufsz;
++      void *mem;
++      size_t memsz;
++};
++
++struct kimage {
++      kimage_entry_t head;
++      kimage_entry_t *entry;
++      kimage_entry_t *last_entry;
++
++      unsigned long destination;
++      unsigned long offset;
++
++      unsigned long start;
++      struct page *reboot_code_pages;
++
++      unsigned long nr_segments;
++      struct kexec_segment segment[KEXEC_SEGMENT_MAX+1];
++
++      struct list_head dest_pages;
++      struct list_head unuseable_pages;
++};
++
++
++/* kexec interface functions */
++extern void machine_kexec(struct kimage *image);
++extern asmlinkage long sys_kexec(unsigned long entry, long nr_segments, 
++      struct kexec_segment *segments);
++extern struct kimage *kexec_image;
++#endif
++#endif /* LINUX_KEXEC_H */
++
+Index: linux-2.6.0-test5/include/linux/reboot.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/reboot.h      2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/include/linux/reboot.h   2003-09-26 15:56:27.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.
++ * KEXEC       Restart the system using a different kernel.
+  */
+ #define       LINUX_REBOOT_CMD_RESTART        0x01234567
+@@ -31,6 +32,7 @@
+ #define       LINUX_REBOOT_CMD_POWER_OFF      0x4321FEDC
+ #define       LINUX_REBOOT_CMD_RESTART2       0xA1B2C3D4
+ #define       LINUX_REBOOT_CMD_SW_SUSPEND     0xD000FCE2
++#define LINUX_REBOOT_CMD_KEXEC                0x45584543
+ #ifdef __KERNEL__
+Index: linux-2.6.0-test5/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/Makefile     2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/Makefile  2003-09-26 15:56:27.000000000 +0800
+@@ -17,6 +17,7 @@
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+ obj-$(CONFIG_PM) += power/
+ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
++obj-$(CONFIG_KEXEC) += kexec.o
+ obj-$(CONFIG_COMPAT) += compat.o
+ obj-$(CONFIG_IKCONFIG) += configs.o
+ obj-$(CONFIG_IKCONFIG_PROC) += configs.o
+Index: linux-2.6.0-test5/kernel/kexec.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/kexec.c      2003-09-26 15:56:27.000000000 +0800
++++ linux-2.6.0-test5/kernel/kexec.c   2003-09-26 15:56:27.000000000 +0800
+@@ -0,0 +1,629 @@
++#include <linux/mm.h>
++#include <linux/file.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/version.h>
++#include <linux/compile.h>
++#include <linux/kexec.h>
++#include <linux/spinlock.h>
++#include <linux/list.h>
++#include <linux/highmem.h>
++#include <net/checksum.h>
++#include <asm/page.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <asm/system.h>
++
++/* When kexec transitions to the new kernel there is a one to one
++ * mapping between physical and virtual addresses.  On processors
++ * where you can disable the MMU this is trivial, and easy.  For
++ * others it is still a simple predictable page table to setup.
++ *
++ * In that environment kexec copies the new kernel to it's final
++ * resting place.  This means I can only support memory whose
++ * physical address can fit in an unsigned long.  In particular
++ * addresses where (pfn << PAGE_SHIFT) > ULONG_MAX cannot be handled.
++ * If the assembly stub has more restrictive requirements
++ * KEXEC_SOURCE_MEMORY_LIMIT and KEXEC_DEST_MEMORY_LIMIT can be
++ * defined more restrictively in <asm/kexec.h>.
++ *
++ * The code for the transition from the current kernel to the 
++ * the new kernel is placed in the reboot_code_buffer, whose size
++ * is given by KEXEC_REBOOT_CODE_SIZE.  In the best case only a single
++ * page of memory is necessary, but some architectures require more.
++ * Because this memory must be identity mapped in the transition from
++ * virtual to physical addresses it must live in the range
++ * 0 - TASK_SIZE, as only the user space mappings are arbitrarily
++ * modifyable.
++ *
++ * The assembly stub in the reboot code buffer is passed a linked list
++ * of descriptor pages detailing the source pages of the new kernel,
++ * and the destination addresses of those source pages.  As this data
++ * structure is not used in the context of the current OS, it must
++ * be self contained.
++ *
++ * The code has been made to work with highmem pages and will use a
++ * destination page in it's final resting place (if it happens 
++ * to allocate it).  The end product of this is that most of the
++ * physical address space, and most of ram can be used.
++ *
++ * Future directions include:
++ *  - allocating a page table with the reboot code buffer identity
++ *    mapped, to simplify machine_kexec and make kexec_on_panic, more
++ *    reliable.  
++ *  - allocating the pages for a page table for machines that cannot
++ *    disable their MMUs.  (Hammer, Alpha...)
++ */
++
++/* KIMAGE_NO_DEST is an impossible destination address..., for
++ * allocating pages whose destination address we do not care about.
++ */
++#define KIMAGE_NO_DEST (-1UL)
++
++static int kimage_is_destination_range(
++      struct kimage *image, unsigned long start, unsigned long end);
++static struct page *kimage_alloc_reboot_code_pages(struct kimage *image);
++static struct page *kimage_alloc_page(struct kimage *image, unsigned int gfp_mask, unsigned long dest);
++
++
++static int kimage_alloc(struct kimage **rimage, 
++      unsigned long nr_segments, struct kexec_segment *segments)
++{
++      int result;
++      struct kimage *image;
++      size_t segment_bytes;
++      struct page *reboot_pages;
++      unsigned long i;
++
++      /* Allocate a controlling structure */
++      result = -ENOMEM;
++      image = kmalloc(sizeof(*image), GFP_KERNEL);
++      if (!image) {
++              goto out;
++      }
++      memset(image, 0, sizeof(*image));
++      image->head = 0;
++      image->entry = &image->head;
++      image->last_entry = &image->head;
++
++      /* Initialize the list of destination pages */
++      INIT_LIST_HEAD(&image->dest_pages);
++
++      /* Initialize the list of unuseable pages */
++      INIT_LIST_HEAD(&image->unuseable_pages);
++
++      /* Read in the segments */
++      image->nr_segments = nr_segments;
++      segment_bytes = nr_segments * sizeof*segments;
++      result = copy_from_user(image->segment, segments, segment_bytes);
++      if (result) 
++              goto out;
++
++      /* Verify we have good destination addresses.  The caller is
++       * responsible for making certain we don't attempt to load
++       * the new image into invalid or reserved areas of RAM.  This
++       * just verifies it is an address we can use. 
++       */
++      result = -EADDRNOTAVAIL;
++      for(i = 0; i < nr_segments; i++) {
++              unsigned long mend;
++              mend = ((unsigned long)(image->segment[i].mem)) + 
++                      image->segment[i].memsz;
++              if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT)
++                      goto out;
++      }
++
++      /* Find a location for the reboot code buffer, and add it
++       * the vector of segments so that it's pages will also be
++       * counted as destination pages.  
++       */
++      result = -ENOMEM;
++      reboot_pages = kimage_alloc_reboot_code_pages(image);
++      if (!reboot_pages) {
++              printk(KERN_ERR "Could not allocate reboot_code_buffer\n");
++              goto out;
++      }
++      image->reboot_code_pages = reboot_pages;
++      image->segment[nr_segments].buf = 0;
++      image->segment[nr_segments].bufsz = 0;
++      image->segment[nr_segments].mem = (void *)(page_to_pfn(reboot_pages) << PAGE_SHIFT);
++      image->segment[nr_segments].memsz = KEXEC_REBOOT_CODE_SIZE;
++      image->nr_segments++;
++
++      result = 0;
++ out:
++      if (result == 0) {
++              *rimage = image;
++      } else {
++              kfree(image);
++      }
++      return result;
++}
++
++static int kimage_is_destination_range(
++      struct kimage *image, unsigned long start, unsigned long end)
++{
++      unsigned long i;
++      for(i = 0; i < image->nr_segments; i++) {
++              unsigned long mstart, mend;
++              mstart = (unsigned long)image->segment[i].mem;
++              mend   = mstart + image->segment[i].memsz;
++              if ((end > mstart) && (start < mend)) {
++                      return 1;
++              }
++      }
++      return 0;
++}
++
++#ifdef CONFIG_MMU
++static int identity_map_pages(struct page *pages, int order)
++{
++      struct mm_struct *mm;
++      struct vm_area_struct *vma;
++      int error;
++      mm = &init_mm;
++      vma = 0;
++
++      down_write(&mm->mmap_sem);
++      error = -ENOMEM;
++      vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
++      if (!vma) {
++              goto out;
++      }
++
++      memset(vma, 0, sizeof(vma));
++      vma->vm_mm = mm;
++      vma->vm_start = page_to_pfn(pages) << PAGE_SHIFT;
++      vma->vm_end = vma->vm_start + (1 << (order + PAGE_SHIFT));
++      vma->vm_ops = 0;
++      vma->vm_flags = VM_SHARED \
++              | VM_READ | VM_WRITE | VM_EXEC \
++              | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC \
++              | VM_DONTCOPY | VM_RESERVED;
++      vma->vm_page_prot = protection_map[vma->vm_flags & 0xf];
++      vma->vm_file = NULL;
++      vma->vm_private_data = NULL;
++      INIT_LIST_HEAD(&vma->shared);
++      insert_vm_struct(mm, vma);
++      
++      error = remap_page_range(vma, vma->vm_start, vma->vm_start,
++              vma->vm_end - vma->vm_start, vma->vm_page_prot);
++      if (error) {
++              goto out;
++      }
++
++      error = 0;
++ out:
++      if (error && vma) {
++              kmem_cache_free(vm_area_cachep, vma);
++              vma = 0;
++      }
++      up_write(&mm->mmap_sem);
++
++      return error;
++}
++#else
++#define identity_map_pages(pages, order) 0
++#endif
++
++struct page *kimage_alloc_reboot_code_pages(struct kimage *image)
++{
++      /* The reboot code buffer is special.  It is the only set of
++       * pages that must be allocated in their final resting place,
++       * and the only set of pages whose final resting place we can
++       * pick. 
++       *
++       * At worst this runs in O(N) of the image size.
++       */
++      struct list_head extra_pages, *pos, *next;
++      struct page *pages;
++      unsigned long addr;
++      int order, count;
++      order = get_order(KEXEC_REBOOT_CODE_SIZE);
++      count = 1 << order;
++      INIT_LIST_HEAD(&extra_pages);
++      do {
++              int i;
++              pages = alloc_pages(GFP_HIGHUSER, order);
++              if (!pages)
++                      break;
++              for(i = 0; i < count; i++) {
++                      SetPageReserved(pages +i);
++              }
++              addr = page_to_pfn(pages) << PAGE_SHIFT;
++              if ((page_to_pfn(pages) >= (TASK_SIZE >> PAGE_SHIFT)) ||
++                      kimage_is_destination_range(image, addr, addr + KEXEC_REBOOT_CODE_SIZE)) {
++                      list_add(&pages->list, &extra_pages);
++                      pages = 0;
++              }
++      } while(!pages);
++      if (pages) {
++              int result;
++              result = identity_map_pages(pages, order);
++              if (result < 0) {
++                      list_add(&pages->list, &extra_pages);
++                      pages = 0;
++              }
++      }
++      /* If I could convert a multi page allocation into a buch of
++       * single page allocations I could add these pages to
++       * image->dest_pages.  For now it is simpler to just free the
++       * pages again.
++       */
++      list_for_each_safe(pos, next, &extra_pages) {
++              struct page *page;
++              int i;
++              page = list_entry(pos, struct page, list);
++              for(i = 0; i < count; i++) {
++                      ClearPageReserved(pages +i);
++              }
++              list_del(&extra_pages);
++              __free_pages(page, order);
++      }
++      return pages;
++}
++
++static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
++{
++      if (image->offset != 0) {
++              image->entry++;
++      }
++      if (image->entry == image->last_entry) {
++              kimage_entry_t *ind_page;
++              struct page *page;
++              page = kimage_alloc_page(image, GFP_KERNEL, KIMAGE_NO_DEST);
++              if (!page) {
++                      return -ENOMEM;
++              }
++              ind_page = page_address(page);
++              *image->entry = virt_to_phys(ind_page) | IND_INDIRECTION;
++              image->entry = ind_page;
++              image->last_entry = 
++                      ind_page + ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1);
++      }
++      *image->entry = entry;
++      image->entry++;
++      image->offset = 0;
++      return 0;
++}
++
++static int kimage_set_destination(
++      struct kimage *image, unsigned long destination) 
++{
++      int result;
++      destination &= PAGE_MASK;
++      result = kimage_add_entry(image, destination | IND_DESTINATION);
++      if (result == 0) {
++              image->destination = destination;
++      }
++      return result;
++}
++
++
++static int kimage_add_page(struct kimage *image, unsigned long page)
++{
++      int result;
++      page &= PAGE_MASK;
++      result = kimage_add_entry(image, page | IND_SOURCE);
++      if (result == 0) {
++              image->destination += PAGE_SIZE;
++      }
++      return result;
++}
++
++
++static void kimage_free_extra_pages(struct kimage *image)
++{
++      /* Walk through and free any extra destination pages I may have */
++      struct list_head *pos, *next;
++      list_for_each_safe(pos, next, &image->dest_pages) {
++              struct page *page;
++              page = list_entry(pos, struct page, list);
++              list_del(&page->list);
++              ClearPageReserved(page);
++              __free_page(page);
++      }
++      /* Walk through and free any unuseable pages I have cached */
++      list_for_each_safe(pos, next, &image->unuseable_pages) {
++              struct page *page;
++              page = list_entry(pos, struct page, list);
++              list_del(&page->list);
++              ClearPageReserved(page);
++              __free_page(page);
++      }
++
++}
++static int kimage_terminate(struct kimage *image)
++{
++      int result;
++      result = kimage_add_entry(image, IND_DONE);
++      if (result == 0) {
++              /* Point at the terminating element */
++              image->entry--;
++              kimage_free_extra_pages(image);
++      }
++      return result;
++}
++
++#define for_each_kimage_entry(image, ptr, entry) \
++      for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
++              ptr = (entry & IND_INDIRECTION)? \
++                      phys_to_virt((entry & PAGE_MASK)): ptr +1)
++
++static void kimage_free(struct kimage *image)
++{
++      kimage_entry_t *ptr, entry;
++      kimage_entry_t ind = 0;
++      int i, count, order;
++      if (!image)
++              return;
++      kimage_free_extra_pages(image);
++      for_each_kimage_entry(image, ptr, entry) {
++              if (entry & IND_INDIRECTION) {
++                      /* Free the previous indirection page */
++                      if (ind & IND_INDIRECTION) {
++                              free_page((unsigned long)phys_to_virt(ind & PAGE_MASK));
++                      }
++                      /* Save this indirection page until we are
++                       * done with it.
++                       */
++                      ind = entry;
++              }
++              else if (entry & IND_SOURCE) {
++                      free_page((unsigned long)phys_to_virt(entry & PAGE_MASK));
++              }
++      }
++      order = get_order(KEXEC_REBOOT_CODE_SIZE);
++      count = 1 << order;
++      do_munmap(&init_mm, 
++              page_to_pfn(image->reboot_code_pages) << PAGE_SHIFT, 
++              count << PAGE_SHIFT);
++      for(i = 0; i < count; i++) {
++              ClearPageReserved(image->reboot_code_pages + i);
++      }
++      __free_pages(image->reboot_code_pages, order);
++      kfree(image);
++}
++
++static kimage_entry_t *kimage_dst_used(struct kimage *image, unsigned long page)
++{
++      kimage_entry_t *ptr, entry;
++      unsigned long destination = 0;
++      for_each_kimage_entry(image, ptr, entry) {
++              if (entry & IND_DESTINATION) {
++                      destination = entry & PAGE_MASK;
++              }
++              else if (entry & IND_SOURCE) {
++                      if (page == destination) {
++                              return ptr;
++                      }
++                      destination += PAGE_SIZE;
++              }
++      }
++      return 0;
++}
++
++static struct page *kimage_alloc_page(struct kimage *image, unsigned int gfp_mask, unsigned long destination)
++{
++      /* Here we implment safe guards to ensure that a source page
++       * is not copied to it's destination page before the data on
++       * the destination page is no longer useful.
++       *
++       * To do this we maintain the invariant that a source page is
++       * either it's own destination page, or it is not a
++       * destination page at all.  
++       *
++       * That is slightly stronger than required, but the proof
++       * that no problems will not occur is trivial, and the
++       * implemenation is simply to verify.
++       *
++       * When allocating all pages normally this algorithm will run
++       * in O(N) time, but in the worst case it will run in O(N^2)
++       * time.   If the runtime is a problem the data structures can
++       * be fixed.
++       */
++      struct page *page;
++      unsigned long addr;
++
++      /* Walk through the list of destination pages, and see if I
++       * have a match.
++       */
++      list_for_each_entry(page, &image->dest_pages, list) {
++              addr = page_to_pfn(page) << PAGE_SHIFT;
++              if (addr == destination) {
++                      list_del(&page->list);
++                      return page;
++              }
++      }
++      page = 0;
++      while(1) {
++              kimage_entry_t *old;
++              /* Allocate a page, if we run out of memory give up */
++              page = alloc_page(gfp_mask);
++              if (!page) {
++                      return 0;
++              }
++              SetPageReserved(page);
++              /* If the page cannot be used file it away */
++              if (page_to_pfn(page) > (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
++                      list_add(&page->list, &image->unuseable_pages);
++                      continue;
++              }
++              addr = page_to_pfn(page) << PAGE_SHIFT;
++
++              /* If it is the destination page we want use it */
++              if (addr == destination)
++                      break;
++
++              /* If the page is not a destination page use it */
++              if (!kimage_is_destination_range(image, addr, addr + PAGE_SIZE))
++                      break;
++
++              /* I know that the page is someones destination page.
++               * See if there is already a source page for this
++               * destination page.  And if so swap the source pages.
++               */
++              old = kimage_dst_used(image, addr);
++              if (old) {
++                      /* If so move it */
++                      unsigned long old_addr;
++                      struct page *old_page;
++                      
++                      old_addr = *old & PAGE_MASK;
++                      old_page = pfn_to_page(old_addr >> PAGE_SHIFT);
++                      copy_highpage(page, old_page);
++                      *old = addr | (*old & ~PAGE_MASK);
++
++                      /* The old page I have found cannot be a
++                       * destination page, so return it.
++                       */
++                      addr = old_addr;
++                      page = old_page;
++                      break;
++              }
++              else {
++                      /* Place the page on the destination list I
++                       * will use it later.
++                       */
++                      list_add(&page->list, &image->dest_pages);
++              }
++      }
++      return page;
++}
++
++static int kimage_load_segment(struct kimage *image,
++      struct kexec_segment *segment)
++{     
++      unsigned long mstart;
++      int result;
++      unsigned long offset;
++      unsigned long offset_end;
++      unsigned char *buf;
++
++      result = 0;
++      buf = segment->buf;
++      mstart = (unsigned long)segment->mem;
++
++      offset_end = segment->memsz;
++
++      result = kimage_set_destination(image, mstart);
++      if (result < 0) {
++              goto out;
++      }
++      for(offset = 0;  offset < segment->memsz; offset += PAGE_SIZE) {
++              struct page *page;
++              char *ptr;
++              size_t size, leader;
++              page = kimage_alloc_page(image, GFP_HIGHUSER, mstart + offset);
++              if (page == 0) {
++                      result  = -ENOMEM;
++                      goto out;
++              }
++              result = kimage_add_page(image, page_to_pfn(page) << PAGE_SHIFT);
++              if (result < 0) {
++                      goto out;
++              }
++              ptr = kmap(page);
++              if (segment->bufsz < offset) {
++                      /* We are past the end zero the whole page */
++                      memset(ptr, 0, PAGE_SIZE);
++                      kunmap(page);
++                      continue;
++              }
++              size = PAGE_SIZE;
++              leader = 0;
++              if ((offset == 0)) {
++                      leader = mstart & ~PAGE_MASK;
++              }
++              if (leader) {
++                      /* We are on the first page zero the unused portion */
++                      memset(ptr, 0, leader);
++                      size -= leader;
++                      ptr += leader;
++              }
++              if (size > (segment->bufsz - offset)) {
++                      size = segment->bufsz - offset;
++              }
++              if (size < (PAGE_SIZE - leader)) {
++                      /* zero the trailing part of the page */
++                      memset(ptr + size, 0, (PAGE_SIZE - leader) - size);
++              }
++              result = copy_from_user(ptr, buf + offset, size);
++              kunmap(page);
++              if (result) {
++                      result = (result < 0)?result : -EIO;
++                      goto out;
++              }
++      }
++ out:
++      return result;
++}
++
++/*
++ * Exec Kernel system call: for obvious reasons only root may call it.
++ * 
++ * This call breaks up into three pieces.  
++ * - A generic part which loads the new kernel from the current
++ *   address space, and very carefully places the data in the
++ *   allocated pages.
++ *
++ * - A generic part that interacts with the kernel and tells all of
++ *   the devices to shut down.  Preventing on-going dmas, and placing
++ *   the devices in a consistent state so a later kernel can
++ *   reinitialize them.
++ *
++ * - A machine specific part that includes the syscall number
++ *   and the copies the image to it's final destination.  And
++ *   jumps into the image at entry.
++ *
++ * kexec does not sync, or unmount filesystems so if you need
++ * that to happen you need to do that yourself.
++ */
++struct kimage *kexec_image = 0;
++
++asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, 
++      struct kexec_segment *segments, unsigned long flags)
++{
++      struct kimage *image;
++      int result;
++              
++      /* We only trust the superuser with rebooting the system. */
++      if (!capable(CAP_SYS_ADMIN))
++              return -EPERM;
++
++      /* In case we need just a little bit of special behavior for
++       * reboot on panic 
++       */
++      if (flags != 0)
++              return -EINVAL;
++
++      if (nr_segments > KEXEC_SEGMENT_MAX)
++              return -EINVAL;
++      image = 0;
++
++      result = 0;
++      if (nr_segments > 0) {
++              unsigned long i;
++              result = kimage_alloc(&image, nr_segments, segments);
++              if (result) {
++                      goto out;
++              }
++              image->start = entry;
++              for(i = 0; i < nr_segments; i++) {
++                      result = kimage_load_segment(image, &segments[i]);
++                      if (result) {
++                              goto out;
++                      }
++              }
++              result = kimage_terminate(image);
++              if (result) {
++                      goto out;
++              }
++      }
++
++      image = xchg(&kexec_image, image);
++
++ out:
++      kimage_free(image);
++      return result;
++}
+Index: linux-2.6.0-test5/kernel/sys.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sys.c        2003-09-26 15:56:03.000000000 +0800
++++ linux-2.6.0-test5/kernel/sys.c     2003-09-26 15:56:27.000000000 +0800
+@@ -17,6 +17,7 @@
+ #include <linux/init.h>
+ #include <linux/highuid.h>
+ #include <linux/fs.h>
++#include <linux/kexec.h>
+ #include <linux/workqueue.h>
+ #include <linux/device.h>
+ #include <linux/times.h>
+@@ -208,6 +209,7 @@
+ cond_syscall(sys_lookup_dcookie)
+ cond_syscall(sys_swapon)
+ cond_syscall(sys_swapoff)
++cond_syscall(sys_kexec_load)
+ cond_syscall(sys_init_module)
+ cond_syscall(sys_delete_module)
+ cond_syscall(sys_socketpair)
+@@ -454,6 +456,27 @@
+               machine_restart(buffer);
+               break;
++#ifdef CONFIG_KEXEC
++      case LINUX_REBOOT_CMD_KEXEC:
++      {
++              struct kimage *image;
++              if (arg) {
++                      unlock_kernel();
++                      return -EINVAL;
++              }
++              image = xchg(&kexec_image, 0);
++              if (!image) {
++                      unlock_kernel();
++                      return -EINVAL;
++              }
++              notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
++              system_running = 0;
++              device_shutdown();
++              printk(KERN_EMERG "Starting new kernel\n");
++              machine_kexec(image);
++              break;
++      }
++#endif
+ #ifdef CONFIG_SOFTWARE_SUSPEND
+       case LINUX_REBOOT_CMD_SW_SUSPEND:
+               if (!software_suspend_enabled) {
+Index: linux-2.6.0-test5/fs/aio.c
+===================================================================
+--- linux-2.6.0-test5.orig/fs/aio.c    2003-09-26 14:33:41.000000000 +0800
++++ linux-2.6.0-test5/fs/aio.c 2003-09-26 15:57:02.000000000 +0800
+@@ -561,7 +561,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-over-netpoll.patch b/lustre/kernel_patches/patches/kgdb-over-netpoll.patch
new file mode 100644 (file)
index 0000000..e8184ad
--- /dev/null
@@ -0,0 +1,865 @@
+ 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-test5/drivers/net/kgdb_eth.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/kgdb_eth.c      2003-09-26 14:33:41.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/kgdb_eth.c   2003-09-26 14:34:04.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,33 @@
+       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 +109,55 @@
+               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)
++              netpoll_poll(&np);
+-      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)
++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 +166,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-test5/arch/i386/kernel/kgdb_stub.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/kgdb_stub.c        2003-09-26 14:33:40.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/kgdb_stub.c     2003-09-26 14:34:04.000000000 +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,7 +491,7 @@
+       /*  $<packet info>#<checksum>. */
+-      if (kgdb_eth == -1) {
++      if (!kgdboe) {
+               do {
+                       if (remote_debug)
+                               printk("T:%s\n", buffer);
+@@ -1142,9 +1139,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 +1150,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 +1280,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 +1336,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 +1526,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 +1684,6 @@
+                       newPC = regs.eip;
+-                      if (kgdb_eth != -1) {
+-                              kgdb_eth_set_trapmode(0);
+-                      }
+-
+                       /* clear the trace bit */
+                       regs.eflags &= 0xfffffeff;
+@@ -1724,6 +1715,10 @@
+                                       }
+                               }
+                       }
++
++                      if (kgdboe)
++                              netpoll_set_trap(0);
++
+                       correct_hw_break();
+                       asm volatile ("movl %0, %%db6\n"::"r" (0));
+                       goto exit_kgdb;
+@@ -2430,63 +2425,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-test5/arch/i386/lib/kgdb_serial.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/lib/kgdb_serial.c 2003-09-26 14:33:40.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/lib/kgdb_serial.c      2003-09-26 14:34:04.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-test5/drivers/net/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Makefile        2003-09-26 14:33:41.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Makefile     2003-09-26 15:07:15.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
+@@ -196,3 +194,6 @@
+ include $(TOPDIR)/drivers/usb/net/Makefile.mii
++
++# Must come after all NICs it might use
++obj-$(CONFIG_KGDB) += kgdb_eth.o
+Index: linux-2.6.0-test5/include/asm-i386/kgdb.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kgdb.h     2003-09-26 14:33:41.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/kgdb.h  2003-09-26 15:07:02.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'
diff --git a/lustre/kernel_patches/patches/lkcd-cvs-2.6.0-test5.patch b/lustre/kernel_patches/patches/lkcd-cvs-2.6.0-test5.patch
new file mode 100644 (file)
index 0000000..d9f7145
--- /dev/null
@@ -0,0 +1,6496 @@
+ 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.
++#
++
++dump-y                                        := dump_setup.o dump_fmt.o dump_filters.o dump_scheme.o dump_execute.o
++dump-$(CONFIG_X86)                    += dump_i386.o
++dump-$(CONFIG_CRASH_DUMP_MEMDEV)      += dump_memdev.o dump_overlay.o
++dump-objs                             += $(dump-y)
++
++obj-$(CONFIG_CRASH_DUMP)              += dump.o
++obj-$(CONFIG_CRASH_DUMP_BLOCKDEV)     += dump_blockdev.o
++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
+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 
++ * a block device through the kernel's generic low level block i/o
++ * routines.
++ *
++ * Started: June 2002 - Mohamed Abbas <mohamed.abbas@intel.com>
++ *    Moved original lkcd kiobuf dump i/o code from dump_base.c
++ *    to use generic dump device interfaces
++ *
++ * Sept 2002 - Bharata B. Rao <bharata@in.ibm.com>
++ *    Convert dump i/o to directly use bio instead of kiobuf for 2.5
++ *
++ * Oct 2002  - Suparna Bhattacharya <suparna@in.ibm.com>
++ *    Rework to new dumpdev.h structures, implement open/close/
++ *    silence, misc fixes (blocknr removal, bio_add_page usage)  
++ *
++ * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
++ * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++#include <linux/types.h>
++#include <linux/proc_fs.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/blkdev.h>
++#include <linux/bio.h>
++#include <asm/hardirq.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++
++extern void *dump_page_buf;
++
++/* The end_io callback for dump i/o completion */
++static int
++dump_bio_end_io(struct bio *bio, unsigned int bytes_done, int error)
++{
++      struct dump_blockdev *dump_bdev;
++
++      if (bio->bi_size) {
++              /* some bytes still left to transfer */
++              return 1; /* not complete */
++      }
++
++      dump_bdev = (struct dump_blockdev *)bio->bi_private;
++      if (error) {
++              printk("IO error while writing the dump, aborting\n");
++      }
++
++      dump_bdev->err = error;
++
++      /* no wakeup needed, since caller polls for completion */
++      return 0;
++}
++
++/* Check if the dump bio is already mapped to the specified buffer */
++static int
++dump_block_map_valid(struct dump_blockdev *dev, struct page *page, 
++      int len) 
++{
++      struct bio *bio = dev->bio;
++      unsigned long bsize = 0;
++
++      if (!bio->bi_vcnt)
++              return 0; /* first time, not mapped */
++
++
++      if ((bio_page(bio) != page) || (len > bio->bi_vcnt << PAGE_SHIFT))
++              return 0; /* buffer not mapped */
++
++      bsize = bdev_hardsect_size(bio->bi_bdev);
++      if ((len & (PAGE_SIZE - 1)) || (len & bsize))
++              return 0; /* alignment checks needed */
++
++      /* quick check to decide if we need to redo bio_add_page */
++      if (bdev_get_queue(bio->bi_bdev)->merge_bvec_fn)
++              return 0; /* device may have other restrictions */
++
++      return 1; /* already mapped */
++}
++
++/* 
++ * Set up the dump bio for i/o from the specified buffer 
++ * Return value indicates whether the full buffer could be mapped or not
++ */
++static int
++dump_block_map(struct dump_blockdev *dev, void *buf, int len)
++{
++      struct page *page = virt_to_page(buf);
++      struct bio *bio = dev->bio;
++      unsigned long bsize = 0;
++
++      bio->bi_bdev = dev->bdev;
++      bio->bi_sector = (dev->start_offset + dev->ddev.curr_offset) >> 9;
++      bio->bi_idx = 0; /* reset index to the beginning */
++
++      if (dump_block_map_valid(dev, page, len)) {
++              /* already mapped and usable rightaway */
++              bio->bi_size = len; /* reset size to the whole bio */
++      } else {
++              /* need to map the bio */
++              bio->bi_size = 0;
++              bio->bi_vcnt = 0;
++              bsize = bdev_hardsect_size(bio->bi_bdev);
++
++              /* first a few sanity checks */
++              if (len < bsize) {
++                      printk("map: len less than hardsect size \n");
++                      return -EINVAL;
++              }
++
++              if ((unsigned long)buf & bsize) {
++                      printk("map: not aligned \n");
++                      return -EINVAL;
++              }
++
++              /* assume contig. page aligned low mem buffer( no vmalloc) */
++              if ((page_address(page) != buf) || (len & (PAGE_SIZE - 1))) {
++                      printk("map: invalid buffer alignment!\n");
++                      return -EINVAL; 
++              }
++              /* finally we can go ahead and map it */
++              while (bio->bi_size < len)
++                      if (bio_add_page(bio, page++, PAGE_SIZE, 0) == 0) {
++                              break;
++                      }
++
++              bio->bi_end_io = dump_bio_end_io;
++              bio->bi_private = dev;
++      }
++
++      if (bio->bi_size != len) {
++              printk("map: bio size = %d not enough for len = %d!\n",
++                      bio->bi_size, len);
++              return -E2BIG;
++      }
++      return 0;
++}
++
++static void
++dump_free_bio(struct bio *bio)
++{
++      if (bio)
++              kfree(bio->bi_io_vec);
++      kfree(bio);
++}
++
++/*
++ * Prepares the dump device so we can take a dump later. 
++ * The caller is expected to have filled up the kdev_id field in the 
++ * block dump dev structure.
++ *
++ * At dump time when dump_block_write() is invoked it will be too 
++ * late to recover, so as far as possible make sure obvious errors 
++ * get caught right here and reported back to the caller.
++ */
++static int
++dump_block_open(struct dump_dev *dev, unsigned long arg)
++{
++      struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
++      struct block_device *bdev;
++      int retval = 0;
++      struct bio_vec *bvec;
++
++      /* make sure this is a valid block device */
++      if (!arg) {
++              retval = -EINVAL;
++              goto err;
++      }
++
++      /* get a corresponding block_dev struct for this */
++      bdev = bdget((dev_t)arg);
++      if (!bdev) {
++              retval = -ENODEV;
++              goto err;
++      }
++
++      /* get the block device opened */
++      if ((retval = blkdev_get(bdev, O_RDWR | O_LARGEFILE, 0, BDEV_RAW))) {
++              goto err1;
++      }
++
++      if ((dump_bdev->bio = kmalloc(sizeof(struct bio), GFP_KERNEL)) 
++              == NULL) {
++              printk("Cannot allocate bio\n");
++              retval = -ENOMEM;
++              goto err2;
++      }
++
++      bio_init(dump_bdev->bio);
++
++      if ((bvec = kmalloc(sizeof(struct bio_vec) * 
++              (DUMP_BUFFER_SIZE >> PAGE_SHIFT), GFP_KERNEL)) == NULL) {
++              retval = -ENOMEM;
++              goto err3;
++      }
++
++      /* assign the new dump dev structure */
++      dump_bdev->kdev_id = new_decode_dev((dev_t)arg);
++      dump_bdev->bdev = bdev;
++
++      /* make a note of the limit */
++      dump_bdev->limit = bdev->bd_inode->i_size;
++      
++      /* now make sure we can map the dump buffer */
++      dump_bdev->bio->bi_io_vec = bvec;
++      dump_bdev->bio->bi_max_vecs = DUMP_BUFFER_SIZE >> PAGE_SHIFT;
++
++      retval = dump_block_map(dump_bdev, dump_config.dumper->dump_buf, 
++              DUMP_BUFFER_SIZE);
++              
++      if (retval) {
++              printk("open: dump_block_map failed, ret %d\n", retval);
++              goto err3;
++      }
++
++      printk("Block device (%d,%d) successfully configured for dumping\n",
++             MAJOR(dump_bdev->kdev_id),
++             MINOR(dump_bdev->kdev_id));
++
++
++      /* after opening the block device, return */
++      return retval;
++
++err3: dump_free_bio(dump_bdev->bio);
++      dump_bdev->bio = NULL;
++err2: if (bdev) blkdev_put(bdev, BDEV_RAW);
++              goto err;
++err1: if (bdev) bdput(bdev);
++      dump_bdev->bdev = NULL;
++err:  return retval;
++}
++
++/*
++ * Close the dump device and release associated resources
++ * Invoked when unconfiguring the dump device.
++ */
++static int
++dump_block_release(struct dump_dev *dev)
++{
++      struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
++
++      /* release earlier bdev if present */
++      if (dump_bdev->bdev) {
++              blkdev_put(dump_bdev->bdev, BDEV_RAW);
++              dump_bdev->bdev = NULL;
++      }
++
++      dump_free_bio(dump_bdev->bio);
++      dump_bdev->bio = NULL;
++
++      return 0;
++}
++
++
++/*
++ * Prepare the dump device for use (silence any ongoing activity
++ * and quiesce state) when the system crashes.
++ */
++static int
++dump_block_silence(struct dump_dev *dev)
++{
++      struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
++      struct request_queue *q = bdev_get_queue(dump_bdev->bdev);
++      int ret;
++
++      /* If we can't get request queue lock, refuse to take the dump */
++      if (!spin_trylock(q->queue_lock))
++              return -EBUSY;
++
++      ret = elv_queue_empty(q);
++      spin_unlock(q->queue_lock);
++
++      /* For now we assume we have the device to ourselves */
++      /* Just a quick sanity check */
++      if (!ret) {
++              /* i/o in flight - safer to quit */
++              return -EBUSY;
++      }
++
++      /* 
++       * Move to a softer level of silencing where no spin_lock_irqs 
++       * are held on other cpus
++       */
++      dump_silence_level = DUMP_SOFT_SPIN_CPUS;       
++
++      __dump_irq_enable();
++
++      printk("Dumping to block device (%d,%d) on CPU %d ...\n",
++             MAJOR(dump_bdev->kdev_id), MINOR(dump_bdev->kdev_id),
++             smp_processor_id());
++      
++      return 0;
++}
++
++/*
++ * Invoked when dumping is done. This is the time to put things back 
++ * (i.e. undo the effects of dump_block_silence) so the device is 
++ * available for normal use.
++ */
++static int
++dump_block_resume(struct dump_dev *dev)
++{
++      __dump_irq_restore();
++      return 0;
++}
++
++
++/*
++ * Seek to the specified offset in the dump device.
++ * Makes sure this is a valid offset, otherwise returns an error.
++ */
++static int
++dump_block_seek(struct dump_dev *dev, loff_t off)
++{
++      struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
++      loff_t offset = off + dump_bdev->start_offset;
++      
++      if (offset & ( PAGE_SIZE - 1)) {
++              printk("seek: non-page aligned\n");
++              return -EINVAL;
++      }
++
++      if (offset & (bdev_hardsect_size(dump_bdev->bdev) - 1)) {
++              printk("seek: not sector aligned \n");
++              return -EINVAL;
++      }
++
++      if (offset > dump_bdev->limit) {
++              printk("seek: not enough space left on device!\n");
++              return -ENOSPC; 
++      }
++      dev->curr_offset = off;
++      return 0;
++}
++
++/*
++ * Write out a buffer after checking the device limitations, 
++ * sector sizes, etc. Assumes the buffer is in directly mapped 
++ * kernel address space (not vmalloc'ed).
++ *
++ * Returns: number of bytes written or -ERRNO. 
++ */
++static int
++dump_block_write(struct dump_dev *dev, void *buf, 
++      unsigned long len)
++{
++      struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
++      loff_t offset = dev->curr_offset + dump_bdev->start_offset;
++      int retval = -ENOSPC;
++
++      if (offset >= dump_bdev->limit) {
++              printk("write: not enough space left on device!\n");
++              goto out;
++      }
++
++      /* don't write more blocks than our max limit */
++      if (offset + len > dump_bdev->limit) 
++              len = dump_bdev->limit - offset;
++
++
++      retval = dump_block_map(dump_bdev, buf, len);
++      if (retval){
++              printk("write: dump_block_map failed! err %d\n", retval);
++              goto out;
++      }
++
++      /*
++       * Write out the data to disk.
++       * Assumes the entire buffer mapped to a single bio, which we can
++       * submit and wait for io completion. In the future, may consider
++       * increasing the dump buffer size and submitting multiple bio s 
++       * for better throughput.
++       */
++      dump_bdev->err = -EAGAIN;
++      submit_bio(WRITE, dump_bdev->bio);
++
++      dump_bdev->ddev.curr_offset += len;
++      retval = len;
++ out:
++      return retval;
++}
++
++/*
++ * Name: dump_block_ready()
++ * Func: check if the last dump i/o is over and ready for next request
++ */
++static int
++dump_block_ready(struct dump_dev *dev, void *buf)
++{
++      struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
++      request_queue_t *q = bdev_get_queue(dump_bdev->bio->bi_bdev);
++
++      /* check for io completion */
++      if (dump_bdev->err == -EAGAIN) {
++              q->unplug_fn(q);
++              return -EAGAIN;
++      }
++
++      if (dump_bdev->err) {
++              printk("dump i/o err\n");
++              return dump_bdev->err;
++      }
++
++      return 0;
++}
++
++
++struct dump_dev_ops dump_blockdev_ops = {
++      .open           = dump_block_open,
++      .release        = dump_block_release,
++      .silence        = dump_block_silence,
++      .resume         = dump_block_resume,
++      .seek           = dump_block_seek,
++      .write          = dump_block_write,
++      /* .read not implemented */
++      .ready          = dump_block_ready
++};
++
++static struct dump_blockdev default_dump_blockdev = {
++      .ddev = {.type_name = "blockdev", .ops = &dump_blockdev_ops, 
++                      .curr_offset = 0},
++      /* 
++       * leave enough room for the longest swap header possibly written 
++       * written by mkswap (likely the largest page size supported by
++       * the arch
++       */
++      .start_offset   = DUMP_HEADER_OFFSET,
++      .err            = 0
++      /* assume the rest of the fields are zeroed by default */
++};    
++      
++struct dump_blockdev *dump_blockdev = &default_dump_blockdev;
++
++static int __init
++dump_blockdev_init(void)
++{
++      if (dump_register_device(&dump_blockdev->ddev) < 0) {
++              printk("block device driver registration failed\n");
++              return -1;
++      }
++              
++      printk("block device driver for LKCD registered\n");
++      return 0;
++}
++
++static void __exit
++dump_blockdev_cleanup(void)
++{
++      dump_unregister_device(&dump_blockdev->ddev);
++      printk("block device driver for LKCD unregistered\n");
++}
++
++MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
++MODULE_DESCRIPTION("Block Dump Driver for Linux Kernel Crash Dump (LKCD)");
++MODULE_LICENSE("GPL");
++
++module_init(dump_blockdev_init);
++module_exit(dump_blockdev_cleanup);
+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 
++ *
++ * Started: Oct 2002 -  Suparna Bhattacharya <suparna@in.ibm.com>
++ *    Split and rewrote high level dump execute code to make use 
++ *    of dump method interfaces.
++ *
++ * Derived from original code in dump_base.c created by 
++ *    Matt Robinson <yakker@sourceforge.net>)
++ *    
++ * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
++ * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * Assumes dumper and dump config settings are in place
++ * (invokes corresponding dumper specific routines as applicable)
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++#include <linux/kernel.h>
++#include <linux/notifier.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++
++struct notifier_block *dump_notifier_list; /* dump started/ended callback */
++
++/* Dump progress indicator */
++void 
++dump_speedo(int i)
++{
++      static const char twiddle[4] =  { '|', '\\', '-', '/' };
++      printk("%c\b", twiddle[i&3]);
++}
++
++/* Make the device ready and write out the header */
++int dump_begin(void)
++{
++      int err = 0;
++
++      /* dump_dev = dump_config.dumper->dev; */
++      dumper_reset();
++      if ((err = dump_dev_silence())) {
++              /* quiesce failed, can't risk continuing */
++              /* Todo/Future: switch to alternate dump scheme if possible */
++              printk("dump silence dev failed ! error %d\n", err);
++              return err;
++      }
++
++      pr_debug("Writing dump header\n");
++      if ((err = dump_update_header())) {
++              printk("dump update header failed ! error %d\n", err);
++              dump_dev_resume();
++              return err;
++      }
++
++      dump_config.dumper->curr_offset = DUMP_BUFFER_SIZE;
++
++      return 0;
++}
++
++/* 
++ * Write the dump terminator, a final header update and let go of 
++ * exclusive use of the device for dump.
++ */
++int dump_complete(void)
++{
++      int ret = 0;
++
++      if (dump_config.level != DUMP_LEVEL_HEADER) {
++              if ((ret = dump_update_end_marker())) {
++                      printk("dump update end marker error %d\n", ret);
++              }
++              if ((ret = dump_update_header())) {
++                      printk("dump update header error %d\n", ret);
++              }
++      }
++      ret = dump_dev_resume();
++
++      return ret;
++}
++
++/* Saves all dump data */
++int dump_execute_savedump(void)
++{
++      int ret = 0, err = 0;
++
++      if ((ret = dump_begin()))  {
++              return ret;
++      }
++
++      if (dump_config.level != DUMP_LEVEL_HEADER) { 
++              ret = dump_sequencer();
++      }
++      if ((err = dump_complete())) {
++              printk("Dump complete failed. Error %d\n", err);
++      }
++
++      return ret;
++}
++
++/* Does all the real work:  Capture and save state */
++int dump_generic_execute(const char *panic_str, const struct pt_regs *regs)
++{
++      int ret = 0;
++
++      if ((ret = dump_configure_header(panic_str, regs))) {
++              printk("dump config header failed ! error %d\n", ret);
++              return ret;     
++      }
++
++      /* tell interested parties that a dump is about to start */
++      notifier_call_chain(&dump_notifier_list, DUMP_BEGIN, 
++              &dump_config.dump_device);
++
++      if (dump_config.level != DUMP_LEVEL_NONE)
++              ret = dump_execute_savedump();
++
++      pr_debug("dumped %ld blocks of %d bytes each\n", 
++              dump_config.dumper->count, DUMP_BUFFER_SIZE);
++      
++      /* tell interested parties that a dump has completed */
++      notifier_call_chain(&dump_notifier_list, DUMP_END, 
++              &dump_config.dump_device);
++
++      return ret;
++}
+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.
++ *
++ * Started: Oct 2002 -  Suparna Bhattacharya <suparna@in.ibm.com>
++ *    Split and rewrote default dump selection logic to generic dump 
++ *    method interfaces 
++ * Derived from a portion of dump_base.c created by 
++ *    Matt Robinson <yakker@sourceforge.net>)
++ *
++ * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
++ * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * Used during single-stage dumping and during stage 1 of the 2-stage scheme
++ * (Stage 2 of the 2-stage scheme uses the fully transparent filters
++ * i.e. passthru filters in dump_overlay.c)
++ *
++ * Future: Custom selective dump may involve a different set of filters.
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++#include <linux/kernel.h>
++#include <linux/bootmem.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++
++
++/* Copied from mm/bootmem.c - FIXME */
++/* return the number of _pages_ that will be allocated for the boot bitmap */
++unsigned long dump_calc_bootmap_pages (void)
++{
++      unsigned long mapsize;
++      unsigned long pages = num_physpages;
++
++      mapsize = (pages+7)/8;
++      mapsize = (mapsize + ~PAGE_MASK) & PAGE_MASK;
++      mapsize >>= PAGE_SHIFT;
++
++      return mapsize;
++}
++
++
++#define DUMP_PFN_SAFETY_MARGIN        1024  /* 4 MB */
++/* temporary */
++extern unsigned long min_low_pfn;
++
++
++int dump_low_page(struct page *p)
++{
++      return page_to_pfn(p) < min_low_pfn + dump_calc_bootmap_pages() 
++                      + 1 + DUMP_PFN_SAFETY_MARGIN;
++}
++
++static inline int kernel_page(struct page *p)
++{
++      /* FIXME: Need to exclude hugetlb pages. Clue: reserved but inuse */
++      return PageReserved(p) || (!PageLRU(p) && PageInuse(p));
++}
++
++static inline int user_page(struct page *p)
++{
++      return PageInuse(p) && (!PageReserved(p) && PageLRU(p));
++}
++
++static inline int unreferenced_page(struct page *p)
++{
++      return !PageInuse(p) && !PageReserved(p);
++}
++
++
++/* loc marks the beginning of a range of pages */
++int dump_filter_kernpages(int pass, unsigned long loc, unsigned long sz)
++{
++      struct page *page = (struct page *)loc;
++      /* if any of the pages is a kernel page, select this set */     
++      while (sz) {
++              if (dump_low_page(page) || kernel_page(page))
++                      return 1;
++              sz -= PAGE_SIZE;
++              page++;
++      }       
++      return 0;
++}
++
++
++/* loc marks the beginning of a range of pages */
++int dump_filter_userpages(int pass, unsigned long loc, unsigned long sz)
++{
++      struct page *page = (struct page *)loc;
++      int ret = 0;
++      /* select if the set has any user page, and no kernel pages  */ 
++      while (sz) {
++              if (user_page(page) && !dump_low_page(page)) {
++                      ret = 1;
++              } else if (kernel_page(page) || dump_low_page(page)) {
++                      return 0;
++              }
++              page++;
++              sz -= PAGE_SIZE;
++      }       
++      return ret;
++}
++
++
++
++/* loc marks the beginning of a range of pages */
++int dump_filter_unusedpages(int pass, unsigned long loc, unsigned long sz)
++{
++      struct page *page = (struct page *)loc;
++
++      /* select if the set does not have any used pages  */   
++      while (sz) {
++              if (!unreferenced_page(page) || dump_low_page(page)) {
++                      return 0;
++              }
++              page++;
++              sz -= PAGE_SIZE;
++      }       
++      return 1;
++}
++
++/* dummy: last (non-existent) pass */
++int dump_filter_none(int pass, unsigned long loc, unsigned long sz)
++{
++      return 0;
++}
++
++/* TBD: resolve level bitmask ? */
++struct dump_data_filter dump_filter_table[] = {
++      { .name = "kern", .selector = dump_filter_kernpages, 
++              .level_mask = DUMP_MASK_KERN},
++      { .name = "user", .selector = dump_filter_userpages, 
++              .level_mask = DUMP_MASK_USED},
++      { .name = "unused", .selector = dump_filter_unusedpages, 
++              .level_mask = DUMP_MASK_UNUSED},
++      { .name = "none", .selector = dump_filter_none, 
++              .level_mask = DUMP_MASK_REST},
++      { .name = "", .selector = NULL, .level_mask = 0}
++};
++
+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.
++ *
++ * Used in single stage dumping and stage 1 of soft-boot based dumping 
++ * Saves data in LKCD (lcrash) format 
++ *
++ * Previously a part of dump_base.c
++ *
++ * Started: Oct 2002 -  Suparna Bhattacharya <suparna@in.ibm.com>
++ *    Split off and reshuffled LKCD dump format code around generic
++ *    dump method interfaces.
++ *
++ * Derived from original code created by 
++ *    Matt Robinson <yakker@sourceforge.net>)
++ *
++ * Contributions from SGI, IBM, HP, MCL, and others.
++ *
++ * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
++ * Copyright (C) 2000 - 2002 TurboLinux, Inc.  All rights reserved.
++ * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/time.h>
++#include <linux/sched.h>
++#include <linux/ptrace.h>
++#include <linux/utsname.h>
++#include <asm/dump.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++
++/*
++ * SYSTEM DUMP LAYOUT
++ * 
++ * System dumps are currently the combination of a dump header and a set
++ * of data pages which contain the system memory.  The layout of the dump
++ * (for full dumps) is as follows:
++ *
++ *             +-----------------------------+
++ *             |     generic dump header     |
++ *             +-----------------------------+
++ *             |   architecture dump header  |
++ *             +-----------------------------+
++ *             |         page header         |
++ *             +-----------------------------+
++ *             |          page data          |
++ *             +-----------------------------+
++ *             |         page header         |
++ *             +-----------------------------+
++ *             |          page data          |
++ *             +-----------------------------+
++ *             |              |              |
++ *             |              |              |
++ *             |              |              |
++ *             |              |              |
++ *             |              V              |
++ *             +-----------------------------+
++ *             |        PAGE_END header      |
++ *             +-----------------------------+
++ *
++ * There are two dump headers, the first which is architecture
++ * independent, and the other which is architecture dependent.  This
++ * allows different architectures to dump different data structures
++ * which are specific to their chipset, CPU, etc.
++ *
++ * After the dump headers come a succession of dump page headers along
++ * with dump pages.  The page header contains information about the page
++ * size, any flags associated with the page (whether it's compressed or
++ * not), and the address of the page.  After the page header is the page
++ * data, which is either compressed (or not).  Each page of data is
++ * dumped in succession, until the final dump header (PAGE_END) is
++ * placed at the end of the dump, assuming the dump device isn't out
++ * of space.
++ *
++ * This mechanism allows for multiple compression types, different
++ * types of data structures, different page ordering, etc., etc., etc.
++ * It's a very straightforward mechanism for dumping system memory.
++ */
++
++struct __dump_header dump_header;  /* the primary dump header              */
++struct __dump_header_asm dump_header_asm; /* the arch-specific dump header */
++
++/*
++ *  Set up common header fields (mainly the arch indep section) 
++ *  Per-cpu state is handled by lcrash_save_context
++ *  Returns the size of the header in bytes.
++ */
++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) {
++                      printk("lcrash_init_header(): combined "
++                              "headers larger than DUMP_BUFFER_SIZE!\n");
++                      return -E2BIG;
++      }
++
++      /* initialize the dump headers to zero */
++      memset(&dump_header, 0, sizeof(dump_header));
++      memset(&dump_header_asm, 0, sizeof(dump_header_asm));
++
++      /* configure dump header values */
++      dump_header.dh_magic_number = DUMP_MAGIC_NUMBER;
++      dump_header.dh_version = DUMP_VERSION_NUMBER;
++      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;
++      dump_header.dh_dump_compress = dump_config.dumper->compress->
++              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
++      dump_header.dh_num_dump_pages = 0;
++      do_gettimeofday(&dh_time);
++      dump_header.dh_time.tv_sec = dh_time.tv_sec;
++      dump_header.dh_time.tv_usec = dh_time.tv_usec;
++
++      memcpy((void *)&(dump_header.dh_utsname_sysname), 
++              (const void *)&(system_utsname.sysname), __NEW_UTS_LEN + 1);
++      memcpy((void *)&(dump_header.dh_utsname_nodename), 
++              (const void *)&(system_utsname.nodename), __NEW_UTS_LEN + 1);
++      memcpy((void *)&(dump_header.dh_utsname_release), 
++              (const void *)&(system_utsname.release), __NEW_UTS_LEN + 1);
++      memcpy((void *)&(dump_header.dh_utsname_version), 
++              (const void *)&(system_utsname.version), __NEW_UTS_LEN + 1);
++      memcpy((void *)&(dump_header.dh_utsname_machine), 
++              (const void *)&(system_utsname.machine), __NEW_UTS_LEN + 1);
++      memcpy((void *)&(dump_header.dh_utsname_domainname), 
++              (const void *)&(system_utsname.domainname), __NEW_UTS_LEN + 1);
++
++      if (panic_str) {
++              memcpy((void *)&(dump_header.dh_panic_string),
++                      (const void *)panic_str, DUMP_PANIC_LEN);
++      }
++
++        dump_header_asm.dha_magic_number = DUMP_ASM_MAGIC_NUMBER;
++        dump_header_asm.dha_version = DUMP_ASM_VERSION_NUMBER;
++        dump_header_asm.dha_header_size = sizeof(dump_header_asm);
++
++      dump_header_asm.dha_smp_num_cpus = num_online_cpus();
++      pr_debug("smp_num_cpus in header %d\n", 
++              dump_header_asm.dha_smp_num_cpus);
++
++      dump_header_asm.dha_dumping_cpu = smp_processor_id();
++      
++      return sizeof(dump_header) + sizeof(dump_header_asm);
++}
++
++
++int dump_lcrash_configure_header(const char *panic_str, 
++      const struct pt_regs *regs)
++{
++      int retval = 0;
++
++      dump_config.dumper->header_len = lcrash_init_dump_header(panic_str);
++
++      /* capture register states for all processors */
++      dump_save_this_cpu(regs);
++      __dump_save_other_cpus(); /* side effect:silence cpus */
++
++      /* configure architecture-specific dump header values */
++      if ((retval = __dump_configure_header(regs))) 
++              return retval;
++
++      dump_config.dumper->header_dirty++;
++      return 0;
++}
++
++/* save register and task context */
++void dump_lcrash_save_context(int cpu, const struct pt_regs *regs, 
++      struct task_struct *tsk)
++{
++      dump_header_asm.dha_smp_current_task[cpu] = (uint32_t) tsk;
++
++      __dump_save_regs(&dump_header_asm.dha_smp_regs[cpu], regs);
++
++      /* take a snapshot of the stack */
++      /* doing this enables us to tolerate slight drifts on this cpu */
++      if (dump_header_asm.dha_stack[cpu]) {
++              memcpy((void *)dump_header_asm.dha_stack[cpu],
++                              tsk->thread_info, THREAD_SIZE);
++      }
++      dump_header_asm.dha_stack_ptr[cpu] = (uint32_t)(tsk->thread_info);
++}
++
++/* write out the header */
++int dump_write_header(void)
++{
++      int retval = 0, size;
++      void *buf = dump_config.dumper->dump_buf;
++
++      /* accounts for DUMP_HEADER_OFFSET if applicable */
++      if ((retval = dump_dev_seek(0))) {
++              printk("Unable to seek to dump header offset: %d\n", 
++                      retval);
++              return retval;
++      }
++
++      memcpy(buf, (void *)&dump_header, sizeof(dump_header));
++      size = sizeof(dump_header);
++      memcpy(buf + size, (void *)&dump_header_asm, sizeof(dump_header_asm));
++      size += sizeof(dump_header_asm);
++      size = PAGE_ALIGN(size);
++      retval = dump_ll_write(buf , size);
++
++      if (retval < size) 
++              return (retval >= 0) ? ENOSPC : retval;
++
++      return 0;
++}
++
++int dump_generic_update_header(void)
++{
++      int err = 0;
++
++      if (dump_config.dumper->header_dirty) {
++              if ((err = dump_write_header())) {
++                      printk("dump write header failed !err %d\n", err);
++              } else {
++                      dump_config.dumper->header_dirty = 0;
++              }
++      }
++
++      return err;
++}
++
++static inline int is_curr_stack_page(struct page *page, unsigned long size)
++{
++      unsigned long thread_addr = (unsigned long)current_thread_info();
++      unsigned long addr = (unsigned long)page_address(page);
++
++      return !PageHighMem(page) && (addr < thread_addr + THREAD_SIZE)
++              && (addr + size > thread_addr);
++}
++
++static inline int is_dump_page(struct page *page, unsigned long size)
++{
++      unsigned long addr = (unsigned long)page_address(page);
++      unsigned long dump_buf = (unsigned long)dump_config.dumper->dump_buf;
++
++      return !PageHighMem(page) && (addr < dump_buf + DUMP_BUFFER_SIZE)
++              && (addr + size > dump_buf);
++}
++
++int dump_allow_compress(struct page *page, unsigned long size)
++{
++      /*
++       * Don't compress the page if any part of it overlaps
++       * with the current stack or dump buffer (since the contents
++       * in these could be changing while compression is going on)
++       */
++      return !is_curr_stack_page(page, size) && !is_dump_page(page, size);
++}
++
++void lcrash_init_pageheader(struct __dump_page *dp, struct page *page, 
++      unsigned long sz)
++{
++      memset(dp, sizeof(struct __dump_page), 0);
++      dp->dp_flags = 0; 
++      dp->dp_size = 0;
++      if (sz > 0)
++              dp->dp_address = page_to_pfn(page) << PAGE_SHIFT;
++
++#if DUMP_DEBUG > 6
++      dp->dp_page_index = dump_header.dh_num_dump_pages;
++      dp->dp_byte_offset = dump_header.dh_num_bytes + DUMP_BUFFER_SIZE
++              + DUMP_HEADER_OFFSET; /* ?? */
++#endif /* DUMP_DEBUG */
++}
++
++int dump_lcrash_add_data(unsigned long loc, unsigned long len)
++{
++      struct page *page = (struct page *)loc;
++      void *addr, *buf = dump_config.dumper->curr_buf;
++      struct __dump_page *dp = (struct __dump_page *)buf; 
++      int bytes, size;
++
++      if (buf > dump_config.dumper->dump_buf + DUMP_BUFFER_SIZE)
++              return -ENOMEM;
++
++      lcrash_init_pageheader(dp, page, len);
++      buf += sizeof(struct __dump_page);
++
++      while (len) {
++              addr = kmap_atomic(page, KM_DUMP);
++              size = bytes = (len > PAGE_SIZE) ? PAGE_SIZE : len;     
++              /* check for compression */
++              if (dump_allow_compress(page, bytes)) {
++                      size = dump_compress_data((char *)addr, bytes, (char *)buf);
++              }
++              /* set the compressed flag if the page did compress */
++              if (size && (size < bytes)) {
++                      dp->dp_flags |= DUMP_DH_COMPRESSED;
++              } else {
++                      /* compression failed -- default to raw mode */
++                      dp->dp_flags |= DUMP_DH_RAW;
++                      memcpy(buf, addr, bytes);
++                      size = bytes;
++              }
++              /* memset(buf, 'A', size); temporary: testing only !! */
++              kunmap_atomic(addr, KM_DUMP);
++              dp->dp_size += size;
++              buf += size;
++              len -= bytes;
++              page++;
++      }
++
++      /* now update the header */
++#if DUMP_DEBUG > 6
++      dump_header.dh_num_bytes += dp->dp_size + sizeof(*dp);
++#endif
++      dump_header.dh_num_dump_pages++;
++      dump_config.dumper->header_dirty++;
++
++      dump_config.dumper->curr_buf = buf;     
++
++      return len;
++}
++
++int dump_lcrash_update_end_marker(void)
++{
++      struct __dump_page *dp = 
++              (struct __dump_page *)dump_config.dumper->curr_buf;
++      unsigned long left;
++      int ret = 0;
++              
++      lcrash_init_pageheader(dp, NULL, 0);
++      dp->dp_flags |= DUMP_DH_END; /* tbd: truncation test ? */
++      
++      /* now update the header */
++#if DUMP_DEBUG > 6
++      dump_header.dh_num_bytes += sizeof(*dp);
++#endif
++      dump_config.dumper->curr_buf += sizeof(*dp);
++      left = dump_config.dumper->curr_buf - dump_config.dumper->dump_buf;
++
++      printk("\n");
++
++      while (left) {
++              if ((ret = dump_dev_seek(dump_config.dumper->curr_offset))) {
++                      printk("Seek failed at offset 0x%llx\n", 
++                      dump_config.dumper->curr_offset);
++                      return ret;
++              }
++
++              if (DUMP_BUFFER_SIZE > left) 
++                      memset(dump_config.dumper->curr_buf, 'm', 
++                              DUMP_BUFFER_SIZE - left);
++
++              if ((ret = dump_ll_write(dump_config.dumper->dump_buf, 
++                      DUMP_BUFFER_SIZE)) < DUMP_BUFFER_SIZE) {
++                      return (ret < 0) ? ret : -ENOSPC;
++              }
++
++              dump_config.dumper->curr_offset += DUMP_BUFFER_SIZE;
++      
++              if (left > DUMP_BUFFER_SIZE) {
++                      left -= DUMP_BUFFER_SIZE;
++                      memcpy(dump_config.dumper->dump_buf, 
++                      dump_config.dumper->dump_buf + DUMP_BUFFER_SIZE, left);
++                      dump_config.dumper->curr_buf -= DUMP_BUFFER_SIZE;
++              } else {
++                      left = 0;
++              }
++      }
++      return 0;
++}
++
++
++/* Default Formatter (lcrash) */
++struct dump_fmt_ops dump_fmt_lcrash_ops = {
++      .configure_header       = dump_lcrash_configure_header,
++      .update_header          = dump_generic_update_header,
++      .save_context           = dump_lcrash_save_context,
++      .add_data               = dump_lcrash_add_data,
++      .update_end_marker      = dump_lcrash_update_end_marker
++};
++
++struct dump_fmt dump_fmt_lcrash = {
++      .name   = "lcrash",
++      .ops    = &dump_fmt_lcrash_ops
++};
++
+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.
++ *
++ * Created by: Matt Robinson (yakker@sourceforge.net)
++ * Copyright 2001 Matt D. Robinson.  All rights reserved.
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/* header files */
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/dump.h>
++#include <linux/zlib.h>
++#include <linux/vmalloc.h>
++
++static void *deflate_workspace;
++
++/*
++ * Name: dump_compress_gzip()
++ * Func: Compress a DUMP_PAGE_SIZE page using gzip-style algorithms (the.
++ *       deflate functions similar to what's used in PPP).
++ */
++static u16
++dump_compress_gzip(const u8 *old, u16 oldsize, u8 *new, u16 newsize)
++{
++      /* error code and dump stream */
++      int err;
++      z_stream dump_stream;
++      
++      dump_stream.workspace = deflate_workspace;
++      
++      if ((err = zlib_deflateInit(&dump_stream, Z_BEST_COMPRESSION)) != Z_OK) {
++              /* fall back to RLE compression */
++              printk("dump_compress_gzip(): zlib_deflateInit() "
++                      "failed (%d)!\n", err);
++              return 0;
++      }
++
++      /* use old (page of memory) and size (DUMP_PAGE_SIZE) as in-streams */
++      dump_stream.next_in = (u8 *) old;
++      dump_stream.avail_in = oldsize;
++
++      /* out streams are new (dpcpage) and new size (DUMP_DPC_PAGE_SIZE) */
++      dump_stream.next_out = new;
++      dump_stream.avail_out = newsize;
++
++      /* deflate the page -- check for error */
++      err = zlib_deflate(&dump_stream, Z_FINISH);
++      if (err != Z_STREAM_END) {
++              /* zero is return code here */
++              (void)zlib_deflateEnd(&dump_stream);
++              printk("dump_compress_gzip(): zlib_deflate() failed (%d)!\n",
++                      err);
++              return 0;
++      }
++
++      /* let's end the deflated compression stream */
++      if ((err = zlib_deflateEnd(&dump_stream)) != Z_OK) {
++              printk("dump_compress_gzip(): zlib_deflateEnd() "
++                      "failed (%d)!\n", err);
++      }
++
++      /* return the compressed byte total (if it's smaller) */
++      if (dump_stream.total_out >= oldsize) {
++              return oldsize;
++      }
++      return dump_stream.total_out;
++}
++
++/* setup the gzip compression functionality */
++static struct __dump_compress dump_gzip_compression = {
++      .compress_type = DUMP_COMPRESS_GZIP,
++      .compress_func = dump_compress_gzip,
++      .compress_name = "GZIP",
++};
++
++/*
++ * Name: dump_compress_gzip_init()
++ * Func: Initialize gzip as a compression mechanism.
++ */
++static int __init
++dump_compress_gzip_init(void)
++{
++      deflate_workspace = vmalloc(zlib_deflate_workspacesize());
++      if (!deflate_workspace) {
++              printk("dump_compress_gzip_init(): Failed to "
++                      "alloc %d bytes for deflate workspace\n",
++                      zlib_deflate_workspacesize());
++              return -ENOMEM;
++      }
++      dump_register_compression(&dump_gzip_compression);
++      return 0;
++}
++
++/*
++ * Name: dump_compress_gzip_cleanup()
++ * Func: Remove gzip as a compression mechanism.
++ */
++static void __exit
++dump_compress_gzip_cleanup(void)
++{
++      vfree(deflate_workspace);
++      dump_unregister_compression(DUMP_COMPRESS_GZIP);
++}
++
++/* module initialization */
++module_init(dump_compress_gzip_init);
++module_exit(dump_compress_gzip_cleanup);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
++MODULE_DESCRIPTION("Gzip compression module for crash dump driver");
+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.
++ *
++ * Created by: Matt Robinson (yakker@sgi.com)
++ *
++ * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
++ *
++ * 2.3 kernel modifications by: Matt D. Robinson (yakker@turbolinux.com)
++ * Copyright 2000 TurboLinux, Inc.  All rights reserved.
++ * 
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/*
++ * The hooks for dumping the kernel virtual memory to disk are in this
++ * file.  Any time a modification is made to the virtual memory mechanism,
++ * these routines must be changed to use the new mechanisms.
++ */
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/smp.h>
++#include <linux/fs.h>
++#include <linux/vmalloc.h>
++#include <linux/mm.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++#include <linux/irq.h>
++
++#include <asm/processor.h>
++#include <asm/e820.h>
++#include <asm/hardirq.h>
++#include <asm/nmi.h>
++
++static __s32       saved_irq_count;   /* saved preempt_count() flags */
++
++static int
++alloc_dha_stack(void)
++{
++      int i;
++      void *ptr;
++      
++      if (dump_header_asm.dha_stack[0])
++              return 0;
++
++      ptr = vmalloc(THREAD_SIZE * num_online_cpus());
++      if (!ptr) {
++              printk("vmalloc for dha_stacks failed\n");
++              return -ENOMEM;
++      }
++
++      for (i = 0; i < num_online_cpus(); i++) {
++              dump_header_asm.dha_stack[i] = (u32)((unsigned long)ptr +
++                              (i * THREAD_SIZE));
++      }
++      return 0;
++}
++
++static int
++free_dha_stack(void) 
++{
++      if (dump_header_asm.dha_stack[0]) {
++              vfree((void *)dump_header_asm.dha_stack[0]);    
++              dump_header_asm.dha_stack[0] = 0;
++      }
++      return 0;
++}
++
++
++void 
++__dump_save_regs(struct pt_regs *dest_regs, const struct pt_regs *regs)
++{
++      *dest_regs = *regs;
++
++      /* In case of panic dumps, we collects regs on entry to panic.
++       * so, we shouldn't 'fix' ssesp here again. But it is hard to
++       * tell just looking at regs whether ssesp need fixing. We make
++       * this decision by looking at xss in regs. If we have better
++       * means to determine that ssesp are valid (by some flag which
++       * tells that we are here due to panic dump), then we can use
++       * that instead of this kludge.
++       */
++      if (!user_mode(regs)) {
++              if ((0xffff & regs->xss) == __KERNEL_DS) 
++                      /* already fixed up */
++                      return;
++              dest_regs->esp = (unsigned long)&(regs->esp);
++              __asm__ __volatile__ ("movw %%ss, %%ax;"
++                      :"=a"(dest_regs->xss));
++      }
++}
++
++
++#ifdef CONFIG_SMP
++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 cpumask_t saved_affinity[NR_IRQS];
++
++extern void stop_this_cpu(void *); /* exported by i386 kernel */
++
++static int
++dump_nmi_callback(struct pt_regs *regs, int cpu) 
++{
++      if (!dump_expect_ipi[cpu])
++              return 0;
++
++      dump_expect_ipi[cpu] = 0;
++      
++      dump_save_this_cpu(regs);
++      atomic_dec(&waiting_for_dump_ipi);
++
++ level_changed:
++      switch (dump_silence_level) {
++      case DUMP_HARD_SPIN_CPUS:       /* Spin until dump is complete */
++              while (dump_oncpu) {
++                      barrier();      /* paranoia */
++                      if (dump_silence_level != DUMP_HARD_SPIN_CPUS)
++                              goto level_changed;
++
++                      cpu_relax();    /* kill time nicely */
++              }
++              break;
++
++      case DUMP_HALT_CPUS:            /* Execute halt */
++              stop_this_cpu(NULL);
++              break;
++              
++      case DUMP_SOFT_SPIN_CPUS:
++              /* Mark the task so it spins in schedule */
++              set_tsk_thread_flag(current, TIF_NEED_RESCHED);
++              break;
++      }
++
++      return 1;
++}
++
++/* save registers on other processors */
++void 
++__dump_save_other_cpus(void)
++{
++      int i, cpu = smp_processor_id();
++      int other_cpus = num_online_cpus()-1;
++      
++      if (other_cpus > 0) {
++              atomic_set(&waiting_for_dump_ipi, other_cpus);
++
++              for (i = 0; i < NR_CPUS; i++) {
++                      dump_expect_ipi[i] = (i != cpu && cpu_online(i));
++              }
++
++              /* short circuit normal NMI handling temporarily */
++              set_nmi_callback(dump_nmi_callback);
++              wmb();
++
++              dump_send_ipi();
++              /* may be we dont need to wait for NMI to be processed. 
++                 just write out the header at the end of dumping, if
++                 this IPI is not processed until then, there probably
++                 is a problem and we just fail to capture state of 
++                 other cpus. */
++              while(atomic_read(&waiting_for_dump_ipi) > 0) {
++                      cpu_relax();
++              }
++
++              unset_nmi_callback();
++      }
++}
++
++/*
++ * Routine to save the old irq affinities and change affinities of all irqs to
++ * the dumping cpu.
++ */
++static void 
++set_irq_affinity(void)
++{
++      int i;
++      int cpu = smp_processor_id();
++
++      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] = cpumask_of_cpu(cpu);
++              if (irq_desc[i].handler->set_affinity != NULL)
++                      irq_desc[i].handler->set_affinity(i, irq_affinity[i]);
++      }
++}
++
++/*
++ * Restore old irq affinities.
++ */
++static void 
++reset_irq_affinity(void)
++{
++      int i;
++
++      memcpy(irq_affinity, saved_affinity, NR_IRQS * sizeof(unsigned long));
++      for (i = 0; i < NR_IRQS; i++) {
++              if (irq_desc[i].handler == NULL)
++                      continue;
++              if (irq_desc[i].handler->set_affinity != NULL)
++                      irq_desc[i].handler->set_affinity(i, saved_affinity[i]);
++      }
++}
++
++#else /* !CONFIG_SMP */
++#define set_irq_affinity()    do { } while (0)
++#define reset_irq_affinity()  do { } while (0)
++#define save_other_cpu_states() do { } while (0)
++#endif /* !CONFIG_SMP */
++
++/* 
++ * Kludge - dump from interrupt context is unreliable (Fixme)
++ *
++ * We do this so that softirqs initiated for dump i/o 
++ * get processed and we don't hang while waiting for i/o
++ * to complete or in any irq synchronization attempt.
++ *
++ * This is not quite legal of course, as it has the side 
++ * effect of making all interrupts & softirqs triggered 
++ * while dump is in progress complete before currently 
++ * pending softirqs and the currently executing interrupt 
++ * code. 
++ */
++static inline void
++irq_bh_save(void)
++{
++      saved_irq_count = irq_count();
++      preempt_count() &= ~(HARDIRQ_MASK|SOFTIRQ_MASK);
++}
++
++static inline void
++irq_bh_restore(void)
++{
++      preempt_count() |= saved_irq_count;
++}
++
++/*
++ * Name: __dump_irq_enable
++ * Func: Reset system so interrupts are enabled.
++ *     This is used for dump methods that require interrupts
++ *     Eventually, all methods will have interrupts disabled
++ *     and this code can be removed.
++ *
++ *     Change irq affinities
++ *     Re-enable interrupts
++ */
++void 
++__dump_irq_enable(void)
++{
++      set_irq_affinity();
++      irq_bh_save();
++      local_irq_enable();
++}
++
++/*
++ * Name: __dump_irq_restore
++ * Func: Resume the system state in an architecture-specific way.
++
++ */
++void 
++__dump_irq_restore(void)
++{
++      local_irq_disable();
++      reset_irq_affinity();
++      irq_bh_restore();
++}
++
++/*
++ * Name: __dump_configure_header()
++ * Func: Meant to fill in arch specific header fields except per-cpu state
++ * already captured via __dump_save_context for all CPUs.
++ */
++int
++__dump_configure_header(const struct pt_regs *regs)
++{
++      return (0);
++}
++
++/*
++ * Name: __dump_init()
++ * Func: Initialize the dumping routine process.
++ */
++void
++__dump_init(uint64_t local_memory_start)
++{
++      return;
++}
++
++/*
++ * Name: __dump_open()
++ * Func: Open the dump device (architecture specific).
++ */
++void
++__dump_open(void)
++{
++      alloc_dha_stack();
++}
++
++/*
++ * Name: __dump_cleanup()
++ * Func: Free any architecture specific data structures. This is called
++ *       when the dump module is being removed.
++ */
++void
++__dump_cleanup(void)
++{
++      free_dha_stack();
++}
++
++extern int pfn_is_ram(unsigned long);
++
++/*
++ * Name: __dump_page_valid()
++ * Func: Check if page is valid to dump.
++ */ 
++int 
++__dump_page_valid(unsigned long index)
++{
++      if (!pfn_valid(index))
++              return 0;
++
++      return pfn_is_ram(index);
++}
++
+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
++ * memory areas. The saved pages may be written out to persistent storage  
++ * after a soft reboot.
++ *
++ * Started: Oct 2002 -  Suparna Bhattacharya <suparna@in.ibm.com>
++ *
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * This code is released under version 2 of the GNU GPL.
++ *
++ * The approach of tracking pages containing saved dump using map pages 
++ * allocated as needed has been derived from the Mission Critical Linux 
++ * mcore dump implementation. 
++ *
++ * Credits and a big thanks for letting the lkcd project make use of 
++ * the excellent piece of work and also helping with clarifications 
++ * and tips along the way are due to:
++ *    Dave Winchell <winchell@mclx.com> (primary author of mcore)
++ *    Jeff Moyer <moyer@mclx.com>
++ *    Josh Huber <huber@mclx.com>
++ *
++ * For those familiar with the mcore code, the main differences worth
++ * noting here (besides the dump device abstraction) result from enabling 
++ * "high" memory pages (pages not permanently mapped in the kernel 
++ * address space) to be used for saving dump data (because of which a 
++ * simple virtual address based linked list cannot be used anymore for 
++ * managing free pages), an added level of indirection for faster 
++ * lookups during the post-boot stage, and the idea of pages being 
++ * made available as they get freed up while dump to memory progresses 
++ * rather than one time before starting the dump. The last point enables 
++ * a full memory snapshot to be saved starting with an initial set of 
++ * bootstrap pages given a good compression ratio. (See dump_overlay.c)
++ *
++ */
++
++/*
++ * -----------------MEMORY LAYOUT ------------------
++ * The memory space consists of a set of discontiguous pages, and
++ * discontiguous map pages as well, rooted in a chain of indirect
++ * map pages (also discontiguous). Except for the indirect maps 
++ * (which must be preallocated in advance), the rest of the pages 
++ * could be in high memory.
++ *
++ * root
++ *  |    ---------    --------        --------
++ *  -->  | .  . +|--->|  .  +|------->| . .  |       indirect 
++ *       --|--|---    ---|----        --|-|---             maps
++ *         |  |          |                    | |     
++ *    ------  ------   -------     ------ -------
++ *    | .  |  | .  |   | .  . |    | .  | |  . . |   maps 
++ *    --|---  --|---   --|--|--    --|--- ---|-|--
++ *     page    page    page page   page   page page  data
++ *                                                   pages
++ *
++ * Writes to the dump device happen sequentially in append mode.
++ * The main reason for the existence of the indirect map is
++ * to enable a quick way to lookup a specific logical offset in
++ * the saved data post-soft-boot, e.g. to writeout pages
++ * with more critical data first, even though such pages
++ * would have been compressed and copied last, being the lowest
++ * ranked candidates for reuse due to their criticality.
++ * (See dump_overlay.c)
++ */
++#include <linux/mm.h>
++#include <linux/highmem.h>
++#include <linux/bootmem.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++
++#define DUMP_MAP_SZ (PAGE_SIZE / sizeof(unsigned long)) /* direct map size */
++#define DUMP_IND_MAP_SZ       DUMP_MAP_SZ - 1  /* indirect map size */
++#define DUMP_NR_BOOTSTRAP     64  /* no of bootstrap pages */
++
++extern int dump_low_page(struct page *);
++
++/* check if the next entry crosses a page boundary */
++static inline int is_last_map_entry(unsigned long *map)
++{
++      unsigned long addr = (unsigned long)(map + 1);
++
++      return (!(addr & (PAGE_SIZE - 1)));
++}
++
++/* Todo: should have some validation checks */
++/* The last entry in the indirect map points to the next indirect map */
++/* Indirect maps are referred to directly by virtual address */
++static inline unsigned long *next_indirect_map(unsigned long *map)
++{
++      return (unsigned long *)map[DUMP_IND_MAP_SZ];
++}
++
++#ifdef CONFIG_CRASH_DUMP_SOFTBOOT
++/* Called during early bootup - fixme: make this __init */
++void dump_early_reserve_map(struct dump_memdev *dev)
++{
++      unsigned long *map1, *map2;
++      loff_t off = 0, last = dev->last_used_offset >> PAGE_SHIFT;
++      int i, j;
++      
++      printk("Reserve bootmap space holding previous dump of %lld pages\n",
++                      last);
++      map1= (unsigned long *)dev->indirect_map_root;
++
++      while (map1 && (off < last)) {
++              reserve_bootmem(virt_to_phys((void *)map1), PAGE_SIZE);
++              for (i=0;  (i < DUMP_MAP_SZ - 1) && map1[i] && (off < last); 
++                      i++, off += DUMP_MAP_SZ) {
++                      pr_debug("indirect map[%d] = 0x%lx\n", i, map1[i]);
++                      if (map1[i] >= max_low_pfn)
++                              continue;
++                      reserve_bootmem(map1[i] << PAGE_SHIFT, PAGE_SIZE);
++                      map2 = pfn_to_kaddr(map1[i]);
++                      for (j = 0 ; (j < DUMP_MAP_SZ) && map2[j] && 
++                              (off + j < last); j++) {
++                              pr_debug("\t map[%d][%d] = 0x%lx\n", i, j, 
++                                      map2[j]);
++                              if (map2[j] < max_low_pfn) {
++                                      reserve_bootmem(map2[j] << PAGE_SHIFT,
++                                              PAGE_SIZE);
++                              }
++                      }
++              }
++              map1 = next_indirect_map(map1);
++      }
++      dev->nr_free = 0; /* these pages don't belong to this boot */
++}
++#endif
++
++/* mark dump pages so that they aren't used by this kernel */
++void dump_mark_map(struct dump_memdev *dev)
++{
++      unsigned long *map1, *map2;
++      loff_t off = 0, last = dev->last_used_offset >> PAGE_SHIFT;
++      struct page *page;
++      int i, j;
++      
++      printk("Dump: marking pages in use by previous dump\n");
++      map1= (unsigned long *)dev->indirect_map_root;
++
++      while (map1 && (off < last)) {
++              page = virt_to_page(map1);      
++              set_page_count(page, 1);
++              for (i=0;  (i < DUMP_MAP_SZ - 1) && map1[i] && (off < last); 
++                      i++, off += DUMP_MAP_SZ) {
++                      pr_debug("indirect map[%d] = 0x%lx\n", i, map1[i]);
++                      page = pfn_to_page(map1[i]);
++                      set_page_count(page, 1);
++                      map2 = kmap_atomic(page, KM_DUMP);
++                      for (j = 0 ; (j < DUMP_MAP_SZ) && map2[j] && 
++                              (off + j < last); j++) {
++                              pr_debug("\t map[%d][%d] = 0x%lx\n", i, j, 
++                                      map2[j]);
++                              page = pfn_to_page(map2[j]);
++                              set_page_count(page, 1);
++                      }
++              }
++              map1 = next_indirect_map(map1);
++      }
++}
++      
++
++/* 
++ * Given a logical offset into the mem device lookup the 
++ * corresponding page 
++ *    loc is specified in units of pages 
++ * Note: affects curr_map (even in the case where lookup fails)
++ */
++struct page *dump_mem_lookup(struct dump_memdev *dump_mdev, unsigned long loc)
++{
++      unsigned long *map;
++      unsigned long i, index = loc / DUMP_MAP_SZ;
++      struct page *page = NULL;
++      unsigned long curr_pfn, curr_map, *curr_map_ptr = NULL;
++
++      map = (unsigned long *)dump_mdev->indirect_map_root;
++      if (!map)
++              return NULL;
++
++      if (loc > dump_mdev->last_offset >> PAGE_SHIFT)
++              return NULL;
++
++      /* 
++       * first locate the right indirect map 
++       * in the chain of indirect maps 
++       */
++      for (i = 0; i + DUMP_IND_MAP_SZ < index ; i += DUMP_IND_MAP_SZ) {
++              if (!(map = next_indirect_map(map)))
++                      return NULL;
++      }
++      /* then the right direct map */
++      /* map entries are referred to by page index */
++      if ((curr_map = map[index - i])) {
++              page = pfn_to_page(curr_map);
++              /* update the current traversal index */
++              /* dump_mdev->curr_map = &map[index - i];*/
++              curr_map_ptr = &map[index - i];
++      }
++
++      if (page)
++              map = kmap_atomic(page, KM_DUMP);
++      else 
++              return NULL;
++
++      /* and finally the right entry therein */
++      /* data pages are referred to by page index */
++      i = index * DUMP_MAP_SZ;
++      if ((curr_pfn = map[loc - i])) {
++              page = pfn_to_page(curr_pfn);
++              dump_mdev->curr_map = curr_map_ptr;
++              dump_mdev->curr_map_offset = loc - i;
++              dump_mdev->ddev.curr_offset = loc << PAGE_SHIFT;
++      } else {
++              page = NULL;
++      }
++      kunmap_atomic(map, KM_DUMP);
++
++      return page;
++}
++                      
++/* 
++ * Retrieves a pointer to the next page in the dump device 
++ * Used during the lookup pass post-soft-reboot 
++ */
++struct page *dump_mem_next_page(struct dump_memdev *dev)
++{
++      unsigned long i; 
++      unsigned long *map;     
++      struct page *page = NULL;
++
++      if (dev->ddev.curr_offset + PAGE_SIZE >= dev->last_offset) {
++              return NULL;
++      }
++
++      if ((i = (unsigned long)(++dev->curr_map_offset)) >= DUMP_MAP_SZ) {
++              /* move to next map */  
++              if (is_last_map_entry(++dev->curr_map)) {
++                      /* move to the next indirect map page */
++                      printk("dump_mem_next_page: go to next indirect map\n");
++                      dev->curr_map = (unsigned long *)*dev->curr_map;
++                      if (!dev->curr_map)
++                              return NULL;
++              }
++              i = dev->curr_map_offset = 0;
++              pr_debug("dump_mem_next_page: next map 0x%lx, entry 0x%lx\n",
++                              dev->curr_map, *dev->curr_map);
++
++      };
++      
++      if (*dev->curr_map) {
++              map = kmap_atomic(pfn_to_page(*dev->curr_map), KM_DUMP);
++              if (map[i])
++                      page = pfn_to_page(map[i]);
++              kunmap_atomic(map, KM_DUMP);
++              dev->ddev.curr_offset += PAGE_SIZE;
++      };
++
++      return page;
++}
++
++/* Copied from dump_filters.c */
++static inline int kernel_page(struct page *p)
++{
++      /* FIXME: Need to exclude hugetlb pages. Clue: reserved but inuse */
++      return PageReserved(p) || (!PageLRU(p) && PageInuse(p));
++}
++
++static inline int user_page(struct page *p)
++{
++      return PageInuse(p) && (!PageReserved(p) && PageLRU(p));
++}
++
++int dump_reused_by_boot(struct page *page)
++{
++      /* Todo
++       * Checks:
++       * if PageReserved 
++       * if < __end + bootmem_bootmap_pages for this boot + allowance 
++       * if overwritten by initrd (how to check ?)
++       * Also, add more checks in early boot code
++       * e.g. bootmem bootmap alloc verify not overwriting dump, and if
++       * so then realloc or move the dump pages out accordingly.
++       */
++
++      /* Temporary proof of concept hack, avoid overwriting kern pages */
++
++      return (kernel_page(page) || dump_low_page(page) || user_page(page));
++}
++
++
++/* Uses the free page passed in to expand available space */
++int dump_mem_add_space(struct dump_memdev *dev, struct page *page)
++{
++      struct page *map_page;
++      unsigned long *map;     
++      unsigned long i; 
++
++      if (!dev->curr_map)
++              return -ENOMEM; /* must've exhausted indirect map */
++
++      if (!*dev->curr_map || dev->curr_map_offset >= DUMP_MAP_SZ) {
++              /* add map space */
++              *dev->curr_map = page_to_pfn(page);
++              dev->curr_map_offset = 0;
++              return 0;
++      }
++
++      /* add data space */
++      i = dev->curr_map_offset;
++      map_page = pfn_to_page(*dev->curr_map);
++      map = (unsigned long *)kmap_atomic(map_page, KM_DUMP);
++      map[i] = page_to_pfn(page);
++      kunmap_atomic(map, KM_DUMP);
++      dev->curr_map_offset = ++i;
++      dev->last_offset += PAGE_SIZE;
++      if (i >= DUMP_MAP_SZ) {
++              /* move to next map */
++              if (is_last_map_entry(++dev->curr_map)) {
++                      /* move to the next indirect map page */
++                      pr_debug("dump_mem_add_space: using next"
++                      "indirect map\n");
++                      dev->curr_map = (unsigned long *)*dev->curr_map;
++              }
++      }               
++      return 0;
++}
++
++
++/* Caution: making a dest page invalidates existing contents of the page */
++int dump_check_and_free_page(struct dump_memdev *dev, struct page *page)
++{
++      int err = 0;
++
++      /* 
++       * the page can be used as a destination only if we are sure
++       * it won't get overwritten by the soft-boot, and is not
++       * critical for us right now.
++       */
++      if (dump_reused_by_boot(page))
++              return 0;
++
++      if ((err = dump_mem_add_space(dev, page))) {
++              printk("Warning: Unable to extend memdev space. Err %d\n",
++              err);
++              return 0;
++      }
++
++      dev->nr_free++;
++      return 1;
++}
++
++
++/* Set up the initial maps and bootstrap space  */
++/* Must be called only after any previous dump is written out */
++int dump_mem_open(struct dump_dev *dev, unsigned long devid)
++{
++      struct dump_memdev *dump_mdev = DUMP_MDEV(dev);
++      unsigned long nr_maps, *map, *prev_map = &dump_mdev->indirect_map_root;
++      void *addr;
++      struct page *page;
++      unsigned long i = 0;
++      int err = 0;
++
++      /* Todo: sanity check for unwritten previous dump */
++
++      /* allocate pages for indirect map (non highmem area) */
++      nr_maps = num_physpages / DUMP_MAP_SZ; /* maps to cover entire mem */
++      for (i = 0; i < nr_maps; i += DUMP_IND_MAP_SZ) {
++              if (!(map = (unsigned long *)dump_alloc_mem(PAGE_SIZE))) {
++                      printk("Unable to alloc indirect map %ld\n", 
++                              i / DUMP_IND_MAP_SZ);
++                      return -ENOMEM;
++              }
++              clear_page(map);
++              *prev_map = (unsigned long)map;
++              prev_map = &map[DUMP_IND_MAP_SZ];
++      };
++              
++      dump_mdev->curr_map = (unsigned long *)dump_mdev->indirect_map_root;
++      dump_mdev->curr_map_offset = 0; 
++
++      /* 
++       * allocate a few bootstrap pages: at least 1 map and 1 data page
++       * plus enough to save the dump header
++       */
++      i = 0;
++      do {
++              if (!(addr = dump_alloc_mem(PAGE_SIZE))) {
++                      printk("Unable to alloc bootstrap page %ld\n", i);
++                      return -ENOMEM;
++              }
++
++              page = virt_to_page(addr);
++              if (dump_low_page(page)) {
++                      dump_free_mem(addr);
++                      continue;
++              }
++
++              if (dump_mem_add_space(dump_mdev, page)) {
++                      printk("Warning: Unable to extend memdev "
++                                      "space. Err %d\n", err);
++                      dump_free_mem(addr);
++                      continue;
++              }
++              i++;
++      } while (i < DUMP_NR_BOOTSTRAP);
++
++      printk("dump memdev init: %ld maps, %ld bootstrap pgs, %ld free pgs\n",
++              nr_maps, i, dump_mdev->last_offset >> PAGE_SHIFT);
++      
++      dump_mdev->last_bs_offset = dump_mdev->last_offset;
++
++      return 0;
++}
++
++/* Releases all pre-alloc'd pages */
++int dump_mem_release(struct dump_dev *dev)
++{
++      struct dump_memdev *dump_mdev = DUMP_MDEV(dev);
++      struct page *page, *map_page;
++      unsigned long *map, *prev_map;
++      void *addr;
++      int i;
++
++      if (!dump_mdev->nr_free)
++              return 0;
++
++      pr_debug("dump_mem_release\n");
++      page = dump_mem_lookup(dump_mdev, 0);
++      for (i = 0; page && (i < DUMP_NR_BOOTSTRAP - 1); i++) {
++              if (PageHighMem(page))
++                      break;
++              addr = page_address(page);
++              if (!addr) {
++                      printk("page_address(%p) = NULL\n", page);
++                      break;
++              }
++              pr_debug("Freeing page at 0x%lx\n", addr); 
++              dump_free_mem(addr);
++              if (dump_mdev->curr_map_offset >= DUMP_MAP_SZ - 1) {
++                      map_page = pfn_to_page(*dump_mdev->curr_map);
++                      if (PageHighMem(map_page))
++                              break;
++                      page = dump_mem_next_page(dump_mdev);
++                      addr = page_address(map_page);
++                      if (!addr) {
++                              printk("page_address(%p) = NULL\n", 
++                                      map_page);
++                              break;
++                      }
++                      pr_debug("Freeing map page at 0x%lx\n", addr);
++                      dump_free_mem(addr);
++                      i++;
++              } else {
++                      page = dump_mem_next_page(dump_mdev);
++              }
++      }
++
++      /* now for the last used bootstrap page used as a map page */
++      if ((i < DUMP_NR_BOOTSTRAP) && (*dump_mdev->curr_map)) {
++              map_page = pfn_to_page(*dump_mdev->curr_map);
++              if ((map_page) && !PageHighMem(map_page)) {
++                      addr = page_address(map_page);
++                      if (!addr) {
++                              printk("page_address(%p) = NULL\n", map_page);
++                      } else {
++                              pr_debug("Freeing map page at 0x%lx\n", addr);
++                              dump_free_mem(addr);
++                              i++;
++                      }
++              }
++      }
++
++      printk("Freed %d bootstrap pages\n", i);
++
++      /* free the indirect maps */
++      map = (unsigned long *)dump_mdev->indirect_map_root;
++
++      i = 0;
++      while (map) {
++              prev_map = map;
++              map = next_indirect_map(map);
++              dump_free_mem(prev_map);
++              i++;
++      }
++
++      printk("Freed %d indirect map(s)\n", i);
++
++      /* Reset the indirect map */
++      dump_mdev->indirect_map_root = 0;
++      dump_mdev->curr_map = 0;
++
++      /* Reset the free list */
++      dump_mdev->nr_free = 0;
++
++      dump_mdev->last_offset = dump_mdev->ddev.curr_offset = 0;
++      dump_mdev->last_used_offset = 0;
++      dump_mdev->curr_map = NULL;
++      dump_mdev->curr_map_offset = 0;
++      return 0;
++}
++
++/*
++ * Long term:
++ * It is critical for this to be very strict. Cannot afford
++ * to have anything running and accessing memory while we overwrite 
++ * memory (potential risk of data corruption).
++ * If in doubt (e.g if a cpu is hung and not responding) just give
++ * up and refuse to proceed with this scheme.
++ *
++ * Note: I/O will only happen after soft-boot/switchover, so we can 
++ * safely disable interrupts and force stop other CPUs if this is
++ * going to be a disruptive dump, no matter what they
++ * are in the middle of.
++ */
++/* 
++ * ATM Most of this is already taken care of in the nmi handler 
++ * We may halt the cpus rightaway if we know this is going to be disruptive 
++ * For now, since we've limited ourselves to overwriting free pages we
++ * aren't doing much here. Eventually, we'd have to wait to make sure other
++ * cpus aren't using memory we could be overwriting
++ */
++int dump_mem_silence(struct dump_dev *dev)
++{
++      struct dump_memdev *dump_mdev = DUMP_MDEV(dev);
++
++      if (dump_mdev->last_offset > dump_mdev->last_bs_offset) {
++              /* prefer to run lkcd config & start with a clean slate */
++              return -EEXIST;
++      }
++      return 0;
++}
++
++extern int dump_overlay_resume(void);
++
++/* Trigger the next stage of dumping */
++int dump_mem_resume(struct dump_dev *dev)
++{
++      dump_overlay_resume(); 
++      return 0;
++}
++
++/* 
++ * Allocate mem dev pages as required and copy buffer contents into it.
++ * Fails if the no free pages are available
++ * Keeping it simple and limited for starters (can modify this over time)
++ *  Does not handle holes or a sparse layout
++ *  Data must be in multiples of PAGE_SIZE
++ */
++int dump_mem_write(struct dump_dev *dev, void *buf, unsigned long len)
++{
++      struct dump_memdev *dump_mdev = DUMP_MDEV(dev);
++      struct page *page;
++      unsigned long n = 0;
++      void *addr;
++      unsigned long *saved_curr_map, saved_map_offset;
++      int ret = 0;
++
++      pr_debug("dump_mem_write: offset 0x%llx, size %ld\n", 
++              dev->curr_offset, len);
++
++      if (dev->curr_offset + len > dump_mdev->last_offset)  {
++              printk("Out of space to write\n");
++              return -ENOSPC;
++      }
++      
++      if ((len & (PAGE_SIZE - 1)) || (dev->curr_offset & (PAGE_SIZE - 1)))
++              return -EINVAL; /* not aligned in units of page size */
++
++      saved_curr_map = dump_mdev->curr_map;
++      saved_map_offset = dump_mdev->curr_map_offset;
++      page = dump_mem_lookup(dump_mdev, dev->curr_offset >> PAGE_SHIFT);
++
++      for (n = len; (n > 0) && page; n -= PAGE_SIZE, buf += PAGE_SIZE ) {
++              addr = kmap_atomic(page, KM_DUMP);
++              /* memset(addr, 'x', PAGE_SIZE); */
++              memcpy(addr, buf, PAGE_SIZE);
++              kunmap_atomic(addr, KM_DUMP);
++              /* dev->curr_offset += PAGE_SIZE; */
++              page = dump_mem_next_page(dump_mdev);
++      }
++
++      dump_mdev->curr_map = saved_curr_map;
++      dump_mdev->curr_map_offset = saved_map_offset;
++
++      if (dump_mdev->last_used_offset < dev->curr_offset)
++              dump_mdev->last_used_offset = dev->curr_offset;
++
++      return (len - n) ? (len - n) : ret ;
++}
++
++/* dummy - always ready */
++int dump_mem_ready(struct dump_dev *dev, void *buf)
++{
++      return 0;
++}
++
++/* 
++ * Should check for availability of space to write upto the offset 
++ * affects only the curr_offset; last_offset untouched 
++ * Keep it simple: Only allow multiples of PAGE_SIZE for now 
++ */
++int dump_mem_seek(struct dump_dev *dev, loff_t offset)
++{
++      struct dump_memdev *dump_mdev = DUMP_MDEV(dev);
++
++      if (offset & (PAGE_SIZE - 1))
++              return -EINVAL; /* allow page size units only for now */
++      
++      /* Are we exceeding available space ? */
++      if (offset > dump_mdev->last_offset) {
++              printk("dump_mem_seek failed for offset 0x%llx\n",
++                      offset);
++              return -ENOSPC; 
++      }
++
++      dump_mdev->ddev.curr_offset = offset;
++      return 0;
++}
++
++struct dump_dev_ops dump_memdev_ops = {
++      .open           = dump_mem_open,
++      .release        = dump_mem_release,
++      .silence        = dump_mem_silence,
++      .resume         = dump_mem_resume,
++      .seek           = dump_mem_seek,
++      .write          = dump_mem_write,
++      .read           = NULL, /* not implemented at the moment */
++      .ready          = dump_mem_ready
++};
++
++static struct dump_memdev default_dump_memdev = {
++      .ddev = {.type_name = "memdev", .ops = &dump_memdev_ops,
++               .device_id = 0x14}
++      /* assume the rest of the fields are zeroed by default */
++};    
++      
++/* may be overwritten if a previous dump exists */
++struct dump_memdev *dump_memdev = &default_dump_memdev;
++
+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. 
++ *
++ * Some of this code has been taken/adapted from Ingo Molnar's netconsole
++ * code. LKCD team expresses its thanks to Ingo.
++ *
++ * Started: June 2002 - Mohamed Abbas <mohamed.abbas@intel.com>
++ *    Adapted netconsole code to implement LKCD dump over the network.
++ *
++ * Nov 2002 - Bharata B. Rao <bharata@in.ibm.com>
++ *    Innumerable code cleanups, simplification and some fixes.
++ *    Netdump configuration done by ioctl instead of using module parameters.
++ *
++ * Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ *  This code is released under version 2 of the GNU GPL.
++ */
++
++#include <net/tcp.h>
++#include <net/udp.h>
++#include <linux/delay.h>
++#include <linux/random.h>
++#include <linux/reboot.h>
++#include <linux/module.h>
++#include <linux/dump.h>
++#include <linux/dump_netdev.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];
++
++/*
++ * 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
++#define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN)
++
++/*
++ * We maintain a small pool of fully-sized skbs,
++ * to make sure the message gets out even in
++ * extreme OOM situations.
++ */
++#define DUMP_MAX_SKBS 32
++
++#define MAX_SKB_SIZE \
++              (MAX_UDP_CHUNK + sizeof(struct udphdr) + \
++                              sizeof(struct iphdr) + sizeof(struct ethhdr))
++
++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);
++
++      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 int
++dump_rx_hook(struct sk_buff *skb)
++{
++      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;
++
++      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) &&
++          (ntohl(__req->command) != COMM_START_NETDUMP_ACK) &&
++          (memcmp(&__req->magic, &dump_magic, sizeof(dump_magic)) != 0))
++              goto out;
++
++      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);
++      new_req = 1;
++out:
++      return NET_RX_DROP;
++}
++
++static void
++dump_send_mem(struct net_device *dev, req_t *req, const char* buff, size_t len)
++{
++      int i;
++
++      int nr_chunks = len/1024;
++      reply_t reply;
++      
++      reply.nr = req->nr;
++      reply.info = 0;
++
++        if ( nr_chunks <= 0)
++               nr_chunks = 1;
++      for (i = 0; i < nr_chunks; i++) {
++              unsigned int offset = i*1024;
++              reply.code = REPLY_MEM;
++              reply.info = offset;
++                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
++ * of the netdump startup reply, with the possibility of packets
++ * getting lost. We resend the startup packet if no ACK is received,
++ * after a 1 second delay.
++ *
++ * (The client can test the success of the handshake via the HELLO
++ * command, and send ACKs until we enter netdump mode.)
++ */
++static int
++dump_handshake(struct dump_dev *net_dev)
++{
++      char tmp[200];
++      reply_t reply;
++      int i, j;
++
++      if (startup_handshake) {
++              sprintf(tmp, "NETDUMP start, waiting for start-ACK.\n");
++              reply.code = REPLY_START_NETDUMP;
++              reply.nr = 0;
++              reply.info = 0;
++      } else {
++              sprintf(tmp, "NETDUMP start, waiting for start-ACK.\n");
++              reply.code = REPLY_START_WRITE_NETDUMP;
++              reply.nr = net_dev->curr_offset;
++              reply.info = net_dev->curr_offset;
++      }
++      
++      /* send 300 handshake packets before declaring failure */
++      for (i = 0; i < 300; i++) {
++              dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++
++              /* wait 1 sec */
++              for (j = 0; j < 10000; j++) {
++                      udelay(100);
++                      dump_ndev->poll_controller(dump_ndev);
++                      zap_completion_queue();
++                      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
++               * packet again
++               */
++              if (startup_handshake) {
++                      if (req.command == COMM_HELLO || req.command ==
++                              COMM_START_NETDUMP_ACK) {
++                              return 0;
++                      } else {
++                              new_req = 0;
++                              continue;
++                      }
++              } else {
++                      if (req.command == COMM_SEND_MEM) {
++                              return 0;
++                      } else {
++                              new_req = 0;
++                              continue;
++                      }
++              }
++      }
++      return -1;
++}
++
++static ssize_t
++do_netdump(struct dump_dev *net_dev, const char* buff, size_t len)
++{
++      reply_t reply;
++      char tmp[200];
++      ssize_t  ret = 0;
++      int repeatCounter, counter, total_loop;
++      
++      netdump_in_progress = 1;
++
++      if (dump_handshake(net_dev) < 0) {
++              printk("network dump failed due to handshake failure\n");
++              goto out;
++      }
++
++      /*
++       * Ideally startup handshake should be done during dump configuration,
++       * i.e., in dump_net_open(). This will be done when I figure out
++       * the dependency between startup handshake, subsequent write and
++       * various commands wrt to net-server.
++       */
++      if (startup_handshake)
++              startup_handshake = 0;
++
++        counter = 0;
++      repeatCounter = 0;
++      total_loop = 0;
++      while (1) {
++                if (!new_req) {
++                      dump_ndev->poll_controller(dump_ndev);
++                      zap_completion_queue();
++              }
++              if (!new_req) {
++                      repeatCounter++;
++
++                      if (repeatCounter > 5) {
++                              counter++;
++                              if (counter > 10000) {
++                                      if (total_loop >= 100000) {
++                                              printk("Time OUT LEAVE NOW\n");
++                                              goto out;
++                                      } else {
++                                              total_loop++;
++                                              printk("Try number %d out of "
++                                                      "10 before Time Out\n",
++                                                      total_loop);
++                                      }
++                              }
++                              mdelay(1);
++                              repeatCounter = 0;
++                      }       
++                      continue;
++              }
++              repeatCounter = 0;
++              counter = 0;
++              total_loop = 0;
++              new_req = 0;
++              switch (req.command) {
++              case COMM_NONE:
++                      break;
++
++              case COMM_SEND_MEM:
++                      dump_send_mem(dump_ndev, &req, buff, len);
++                      break;
++
++              case COMM_EXIT:
++                case COMM_START_WRITE_NETDUMP_ACK:
++                      ret = len;
++                      goto out;
++
++              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);
++                      break;
++
++              case COMM_GET_PAGE_SIZE:
++                      sprintf(tmp, "PAGE_SIZE: %ld\n", PAGE_SIZE);
++                      reply.code = REPLY_PAGE_SIZE;
++                      reply.nr = req.nr;
++                      reply.info = PAGE_SIZE;
++                      dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++                      break;
++
++              case COMM_GET_NR_PAGES:
++                      reply.code = REPLY_NR_PAGES;
++                      reply.nr = req.nr;
++                      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);
++                      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);
++                      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;
++                      reply.info = req.command;
++                      sprintf(tmp, "Got unknown command code %d!\n",
++                                      req.command);
++                      dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++                      break;
++              }
++      }
++out:
++      netdump_in_progress = 0;
++      return ret;
++}
++
++static int
++dump_validate_config(void)
++{
++      source_ip = dump_in_dev->ifa_list->ifa_local;
++      if (!source_ip) {
++              printk("network device %s has no local address, "
++                              "aborting.\n", device_name);
++              return -1;
++      }
++
++#define IP(x) ((unsigned char *)&source_ip)[x]
++      printk("Source %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3));
++#undef IP
++
++      if (!source_port) {
++              printk("source_port parameter not specified, aborting.\n");
++              return -1;
++      }
++      printk(":%i\n", source_port);
++      source_port = htons(source_port);
++
++      if (!target_ip) {
++              printk("target_ip parameter not specified, aborting.\n");
++              return -1;
++      }
++
++#define IP(x) ((unsigned char *)&target_ip)[x]
++      printk("Target %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3));
++#undef IP
++
++      if (!target_port) {
++              printk("target_port parameter not specified, aborting.\n");
++              return -1;
++      }
++      printk(":%i\n", target_port);
++      target_port = htons(target_port);
++
++      printk("Target Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x",
++              daddr[0], daddr[1], daddr[2], daddr[3], daddr[4], daddr[5]);
++
++      if ((daddr[0] & daddr[1] & daddr[2] & daddr[3] & daddr[4] & 
++                              daddr[5]) == 255)
++              printk("(Broadcast)");
++      printk("\n");
++      return 0;
++}
++
++/*
++ * Prepares the dump device so we can take a dump later. 
++ * Validates the netdump configuration parameters.
++ *
++ * TODO: Network connectivity check should be done here.
++ */
++static int
++dump_net_open(struct dump_dev *net_dev, unsigned long arg)
++{
++      int retval = 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))) {
++              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))) {
++              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;
++
++      net_dev->curr_offset = 0;
++      printk("Network device %s successfully configured for dumping\n",
++                      device_name);
++      return retval;
++err2:
++      in_dev_put(dump_in_dev);
++err1:
++      dev_put(dump_ndev);     
++      return retval;
++}
++
++/*
++ * Close the dump device and release associated resources
++ * Invoked when unconfiguring the dump device.
++ */
++static int
++dump_net_release(struct dump_dev *net_dev)
++{
++      if (dump_in_dev)
++              in_dev_put(dump_in_dev);
++      if (dump_ndev)
++              dev_put(dump_ndev);
++      return 0;
++}
++
++/*
++ * Prepare the dump device for use (silence any ongoing activity
++ * and quiesce state) when the system crashes.
++ */
++static int
++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,
++                      smp_processor_id());
++      return 0;
++}
++
++/*
++ * Invoked when dumping is done. This is the time to put things back 
++ * (i.e. undo the effects of dump_block_silence) so the device is 
++ * available for normal use.
++ */
++static int
++dump_net_resume(struct dump_dev *net_dev)
++{
++      int indx;
++      reply_t reply;
++      char tmp[200];
++
++        if (!dump_ndev)
++              return (0);
++
++      sprintf(tmp, "NETDUMP end.\n");
++      for( indx = 0; indx < 6; indx++) {
++              reply.code = REPLY_END_NETDUMP;
++              reply.nr = 0;
++              reply.info = 0;
++              dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++      }
++      printk("NETDUMP END!\n");
++      local_irq_restore(flags_global);
++      dump_ndev->rx_hook = NULL;
++      startup_handshake = 0;
++      return 0;
++}
++
++/*
++ * Seek to the specified offset in the dump device.
++ * Makes sure this is a valid offset, otherwise returns an error.
++ */
++static  int
++dump_net_seek(struct dump_dev *net_dev, loff_t off)
++{
++      /*
++       * For now using DUMP_HEADER_OFFSET as hard coded value,
++       * See dump_block_seekin dump_blockdev.c to know how to
++       * do this properly.
++       */
++      net_dev->curr_offset = off + DUMP_HEADER_OFFSET;
++      return 0;
++}
++
++/*
++ *
++ */
++static int
++dump_net_write(struct dump_dev *net_dev, void *buf, unsigned long len)
++{
++      int cnt, i, off;
++      ssize_t ret;
++
++      cnt = len/ PAGE_SIZE;
++
++      for (i = 0; i < cnt; i++) {
++              off = i* PAGE_SIZE;
++              ret = do_netdump(net_dev, buf+off, PAGE_SIZE);
++              if (ret <= 0)
++                      return -1;
++              net_dev->curr_offset = net_dev->curr_offset + PAGE_SIZE;
++      }
++      return len;
++}
++
++/*
++ * check if the last dump i/o is over and ready for next request
++ */
++static int
++dump_net_ready(struct dump_dev *net_dev, void *buf)
++{
++      return 0;
++}
++
++/*
++ * ioctl function used for configuring network dump
++ */
++static int
++dump_net_ioctl(struct dump_dev *net_dev, unsigned int cmd, unsigned long arg)
++{
++      switch (cmd) {
++      case DIOSTARGETIP:
++              target_ip = arg;
++              break;
++      case DIOSTARGETPORT:
++              target_port = (u16)arg;
++              break;
++      case DIOSSOURCEPORT:
++              source_port = (u16)arg;
++              break;
++      case DIOSETHADDR:
++              return copy_from_user(daddr, (void *)arg, 6);
++              break;
++      case DIOGTARGETIP:
++      case DIOGTARGETPORT:
++      case DIOGSOURCEPORT:
++      case DIOGETHADDR:
++              break;
++      default:
++              return -EINVAL;
++      }
++      return 0;
++}
++
++struct dump_dev_ops dump_netdev_ops = {
++      .open           = dump_net_open,
++      .release        = dump_net_release,
++      .silence        = dump_net_silence,
++      .resume         = dump_net_resume,
++      .seek           = dump_net_seek,
++      .write          = dump_net_write,
++      /* .read not implemented */
++      .ready          = dump_net_ready,
++      .ioctl          = dump_net_ioctl
++};
++
++static struct dump_dev default_dump_netdev = {
++      .type_name = "networkdev", 
++      .ops = &dump_netdev_ops, 
++      .curr_offset = 0
++};
++
++static int __init
++dump_netdev_init(void)
++{
++        default_dump_netdev.curr_offset = 0;
++
++      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;
++}
++
++static void __exit
++dump_netdev_cleanup(void)
++{
++      dump_unregister_device(&default_dump_netdev);
++}
++
++MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
++MODULE_DESCRIPTION("Network Dump Driver for Linux Kernel Crash Dump (LKCD)");
++MODULE_LICENSE("GPL");
++
++module_init(dump_netdev_init);
++module_exit(dump_netdev_cleanup);
+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
++ * with post soft-boot writeout)
++ *
++ * Started: Oct 2002 -  Suparna Bhattacharya <suparna@in.ibm.com>
++ *
++ * This approach of saving the dump in memory and writing it 
++ * out after a softboot without clearing memory is derived from the 
++ * Mission Critical Linux dump implementation. Credits and a big
++ * thanks for letting the lkcd project make use of the excellent 
++ * piece of work and also for helping with clarifications and 
++ * tips along the way are due to:
++ *    Dave Winchell <winchell@mclx.com> (primary author of mcore)
++ *    and also to
++ *    Jeff Moyer <moyer@mclx.com>
++ *    Josh Huber <huber@mclx.com>
++ * 
++ * For those familiar with the mcore implementation, the key 
++ * differences/extensions here are in allowing entire memory to be 
++ * saved (in compressed form) through a careful ordering scheme 
++ * on both the way down as well on the way up after boot, the latter
++ * for supporting the LKCD notion of passes in which most critical 
++ * data is the first to be saved to the dump device. Also the post 
++ * boot writeout happens from within the kernel rather than driven 
++ * from userspace.
++ *
++ * The sequence is orchestrated through the abstraction of "dumpers",
++ * one for the first stage which then sets up the dumper for the next 
++ * stage, providing for a smooth and flexible reuse of the singlestage 
++ * dump scheme methods and a handle to pass dump device configuration 
++ * information across the soft boot. 
++ *
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/*
++ * Disruptive dumping using the second kernel soft-boot option
++ * for issuing dump i/o operates in 2 stages:
++ * 
++ * (1) - Saves the (compressed & formatted) dump in memory using a 
++ *       carefully ordered overlay scheme designed to capture the 
++ *       entire physical memory or selective portions depending on 
++ *       dump config settings, 
++ *     - Registers the stage 2 dumper and 
++ *     - Issues a soft reboot w/o clearing memory. 
++ *
++ *     The overlay scheme starts with a small bootstrap free area
++ *     and follows a reverse ordering of passes wherein it 
++ *     compresses and saves data starting with the least critical 
++ *     areas first, thus freeing up the corresponding pages to 
++ *     serve as destination for subsequent data to be saved, and
++ *     so on. With a good compression ratio, this makes it feasible
++ *     to capture an entire physical memory dump without significantly
++ *     reducing memory available during regular operation.
++ *
++ * (2) Post soft-reboot, runs through the saved memory dump and
++ *     writes it out to disk, this time around, taking care to
++ *     save the more critical data first (i.e. pages which figure 
++ *     in early passes for a regular dump). Finally issues a 
++ *     clean reboot.
++ *     
++ *     Since the data was saved in memory after selection/filtering
++ *     and formatted as per the chosen output dump format, at this 
++ *     stage the filter and format actions are just dummy (or
++ *     passthrough) actions, except for influence on ordering of
++ *     passes.
++ */
++
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/highmem.h>
++#include <linux/bootmem.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++
++extern struct list_head dumper_list_head;
++extern struct dump_memdev *dump_memdev;
++extern struct dumper dumper_stage2;
++struct dump_config_block *dump_saved_config = NULL;
++extern struct dump_blockdev *dump_blockdev;
++static struct dump_memdev *saved_dump_memdev = NULL;
++static struct dumper *saved_dumper = NULL;
++
++/* For testing 
++extern void dump_display_map(struct dump_memdev *);
++*/
++
++struct dumper *dumper_by_name(char *name)
++{
++#ifdef LATER
++      struct dumper *dumper;
++      list_for_each_entry(dumper, &dumper_list_head, dumper_list)
++              if (!strncmp(dumper->name, name, 32))
++                      return dumper;
++
++      /* not found */
++      return NULL; 
++#endif
++      /* Temporary proof of concept */
++      if (!strncmp(dumper_stage2.name, name, 32))
++              return &dumper_stage2;
++      else
++              return NULL;
++}
++
++#ifdef CONFIG_CRASH_DUMP_SOFTBOOT
++extern void dump_early_reserve_map(struct dump_memdev *);
++
++void crashdump_reserve(void)
++{
++      extern unsigned long crashdump_addr;
++
++      if (crashdump_addr == 0xdeadbeef) 
++              return;
++
++      /* reserve dump config and saved dump pages */
++      dump_saved_config = (struct dump_config_block *)crashdump_addr;
++      /* magic verification */
++      if (dump_saved_config->magic != DUMP_MAGIC_LIVE) {
++              printk("Invalid dump magic. Ignoring dump\n");
++              dump_saved_config = NULL;
++              return;
++      }
++                      
++      printk("Dump may be available from previous boot\n");
++
++      reserve_bootmem(virt_to_phys((void *)crashdump_addr), 
++              PAGE_ALIGN(sizeof(struct dump_config_block)));
++      dump_early_reserve_map(&dump_saved_config->memdev);
++
++}
++#endif
++
++/* 
++ * Loads the dump configuration from a memory block saved across soft-boot
++ * The ops vectors need fixing up as the corresp. routines may have 
++ * relocated in the new soft-booted kernel.
++ */
++int dump_load_config(struct dump_config_block *config)
++{
++      struct dumper *dumper;
++      struct dump_data_filter *filter_table, *filter;
++      struct dump_dev *dev;
++      int i;
++
++      if (config->magic != DUMP_MAGIC_LIVE)
++              return -ENOENT; /* not a valid config */
++
++      /* initialize generic config data */
++      memcpy(&dump_config, &config->config, sizeof(dump_config));
++
++      /* initialize dumper state */
++      if (!(dumper = dumper_by_name(config->dumper.name)))  {
++              printk("dumper name mismatch\n");
++              return -ENOENT; /* dumper mismatch */
++      }
++      
++      /* verify and fixup schema */
++      if (strncmp(dumper->scheme->name, config->scheme.name, 32)) {
++              printk("dumper scheme mismatch\n");
++              return -ENOENT; /* mismatch */
++      }
++      config->scheme.ops = dumper->scheme->ops;
++      config->dumper.scheme = &config->scheme;
++      
++      /* verify and fixup filter operations */
++      filter_table = dumper->filter;
++      for (i = 0, filter = config->filter_table; 
++              ((i < MAX_PASSES) && filter_table[i].selector); 
++              i++, filter++) {
++              if (strncmp(filter_table[i].name, filter->name, 32)) {
++                      printk("dump filter mismatch\n");
++                      return -ENOENT; /* filter name mismatch */
++              }
++              filter->selector = filter_table[i].selector;
++      }
++      config->dumper.filter = config->filter_table;
++
++      /* fixup format */
++      if (strncmp(dumper->fmt->name, config->fmt.name, 32)) {
++              printk("dump format mismatch\n");
++              return -ENOENT; /* mismatch */
++      }
++      config->fmt.ops = dumper->fmt->ops;
++      config->dumper.fmt = &config->fmt;
++
++      /* fixup target device */
++      dev = (struct dump_dev *)(&config->dev[0]);
++      if (dumper->dev == NULL) {
++              pr_debug("Vanilla dumper - assume default\n");
++              if (dump_dev == NULL)
++                      return -ENODEV;
++              dumper->dev = dump_dev;
++      }
++
++      if (strncmp(dumper->dev->type_name, dev->type_name, 32)) { 
++              printk("dump dev type mismatch %s instead of %s\n",
++                              dev->type_name, dumper->dev->type_name);
++              return -ENOENT; /* mismatch */
++      }
++      dev->ops = dumper->dev->ops; 
++      config->dumper.dev = dev;
++      
++      /* fixup memory device containing saved dump pages */
++      /* assume statically init'ed dump_memdev */
++      config->memdev.ddev.ops = dump_memdev->ddev.ops; 
++      /* switch to memdev from prev boot */
++      saved_dump_memdev = dump_memdev; /* remember current */
++      dump_memdev = &config->memdev;
++
++      /* Make this the current primary dumper */
++      dump_config.dumper = &config->dumper;
++
++      return 0;
++}
++
++/* Saves the dump configuration in a memory block for use across a soft-boot */
++int dump_save_config(struct dump_config_block *config)
++{
++      printk("saving dump config settings\n");
++
++      /* dump config settings */
++      memcpy(&config->config, &dump_config, sizeof(dump_config));
++
++      /* dumper state */
++      memcpy(&config->dumper, dump_config.dumper, sizeof(struct dumper));
++      memcpy(&config->scheme, dump_config.dumper->scheme, 
++              sizeof(struct dump_scheme));
++      memcpy(&config->fmt, dump_config.dumper->fmt, sizeof(struct dump_fmt));
++      memcpy(&config->dev[0], dump_config.dumper->dev, 
++              sizeof(struct dump_anydev));
++      memcpy(&config->filter_table, dump_config.dumper->filter, 
++              sizeof(struct dump_data_filter)*MAX_PASSES);
++
++      /* handle to saved mem pages */
++      memcpy(&config->memdev, dump_memdev, sizeof(struct dump_memdev));
++
++      config->magic = DUMP_MAGIC_LIVE;
++      
++      return 0;
++}
++
++int dump_init_stage2(struct dump_config_block *saved_config)
++{
++      int err = 0;
++
++      pr_debug("dump_init_stage2\n");
++      /* Check if dump from previous boot exists */
++      if (saved_config) {
++              printk("loading dumper from previous boot \n");
++              /* load and configure dumper from previous boot */
++              if ((err = dump_load_config(saved_config)))
++                      return err;
++
++              if (!dump_oncpu) {
++                      if ((err = dump_configure(dump_config.dump_device))) {
++                              printk("Stage 2 dump configure failed\n");
++                              return err;
++                      }
++              }
++
++              dumper_reset();
++              dump_dev = dump_config.dumper->dev;
++              /* write out the dump */
++              err = dump_generic_execute(NULL, NULL);
++              
++              dump_saved_config = NULL;
++
++              if (!dump_oncpu) {
++                      dump_unconfigure(); 
++              }
++              
++              return err;
++
++      } else {
++              /* no dump to write out */
++              printk("no dumper from previous boot \n");
++              return 0;
++      }
++}
++
++extern void dump_mem_markpages(struct dump_memdev *);
++
++int dump_switchover_stage(void)
++{
++      int ret = 0;
++
++      /* trigger stage 2 rightaway - in real life would be after soft-boot */
++      /* dump_saved_config would be a boot param */
++      saved_dump_memdev = dump_memdev;
++      saved_dumper = dump_config.dumper;
++      ret = dump_init_stage2(dump_saved_config);
++      dump_memdev = saved_dump_memdev;
++      dump_config.dumper = saved_dumper;
++      return ret;
++}
++
++int dump_activate_softboot(void) 
++{
++      int err = 0;
++
++      /* temporary - switchover to writeout previously saved dump */
++      err = dump_switchover_stage(); /* non-disruptive case */
++      if (dump_oncpu) 
++              dump_config.dumper = &dumper_stage1; /* set things back */
++
++      return err;
++
++      dump_silence_level = DUMP_HALT_CPUS;
++      /* wait till we become the only cpu */
++      /* maybe by checking for online cpus ? */
++
++      /* now call into kexec */
++
++      /* TBD/Fixme: 
++       * should we call reboot notifiers ? inappropriate for panic ?  
++       * what about device_shutdown() ? 
++       * is explicit bus master disabling needed or can we do that
++       * through driverfs ? 
++       */
++      return 0;
++}
++
++/* --- DUMP SCHEME ROUTINES  --- */
++
++static inline int dump_buf_pending(struct dumper *dumper)
++{
++      return (dumper->curr_buf - dumper->dump_buf);
++}
++
++/* Invoked during stage 1 of soft-reboot based dumping */
++int dump_overlay_sequencer(void)
++{
++      struct dump_data_filter *filter = dump_config.dumper->filter;
++      struct dump_data_filter *filter2 = dumper_stage2.filter;
++      int pass = 0, err = 0, save = 0;
++      int (*action)(unsigned long, unsigned long);
++
++      /* Make sure gzip compression is being used */
++      if (dump_config.dumper->compress->compress_type != DUMP_COMPRESS_GZIP) {
++              printk(" Please set GZIP compression \n");
++              return -EINVAL;
++      }
++
++      /* start filling in dump data right after the header */
++      dump_config.dumper->curr_offset = 
++              PAGE_ALIGN(dump_config.dumper->header_len);
++
++      /* Locate the last pass */
++      for (;filter->selector; filter++, pass++);
++      
++      /* 
++       * Start from the end backwards: overlay involves a reverse 
++       * ordering of passes, since less critical pages are more
++       * likely to be reusable as scratch space once we are through
++       * with them. 
++       */
++      for (--pass, --filter; pass >= 0; pass--, filter--)
++      {
++              /* Assumes passes are exclusive (even across dumpers) */
++              /* Requires care when coding the selection functions */
++              if ((save = filter->level_mask & dump_config.level))
++                      action = dump_save_data;
++              else
++                      action = dump_skip_data;
++
++              /* Remember the offset where this pass started */
++              /* The second stage dumper would use this */
++              if (dump_buf_pending(dump_config.dumper) & (PAGE_SIZE - 1)) {
++                      pr_debug("Starting pass %d with pending data\n", pass);
++                      pr_debug("filling dummy data to page-align it\n");
++                      dump_config.dumper->curr_buf = (void *)PAGE_ALIGN(
++                              (unsigned long)dump_config.dumper->curr_buf);
++              }
++              
++              filter2[pass].start = dump_config.dumper->curr_offset
++                      + dump_buf_pending(dump_config.dumper);
++
++              err = dump_iterator(pass, action, filter);
++
++              filter2[pass].end = dump_config.dumper->curr_offset
++                      + dump_buf_pending(dump_config.dumper);
++
++              if (err < 0) {
++                      printk("dump_overlay_seq: failure %d in pass %d\n", 
++                              err, pass);
++                      break;
++              }       
++              printk("\n %d overlay pages %s of %d each in pass %d\n", 
++              err, save ? "saved" : "skipped", DUMP_PAGE_SIZE, pass);
++      }
++
++      return err;
++}
++
++/* from dump_memdev.c */
++extern struct page *dump_mem_lookup(struct dump_memdev *dev, unsigned long loc);
++extern struct page *dump_mem_next_page(struct dump_memdev *dev);
++
++static inline struct page *dump_get_saved_page(loff_t loc)
++{
++      return (dump_mem_lookup(dump_memdev, loc >> PAGE_SHIFT));
++}
++
++static inline struct page *dump_next_saved_page(void)
++{
++      return (dump_mem_next_page(dump_memdev));
++}
++
++/* 
++ * Iterates over list of saved dump pages. Invoked during second stage of 
++ * soft boot dumping
++ *
++ * Observation: If additional selection is desired at this stage then
++ * a different iterator could be written which would advance 
++ * to the next page header everytime instead of blindly picking up
++ * the data. In such a case loc would be interpreted differently. 
++ * At this moment however a blind pass seems sufficient, cleaner and
++ * faster.
++ */
++int dump_saved_data_iterator(int pass, int (*action)(unsigned long, 
++      unsigned long), struct dump_data_filter *filter)
++{
++      loff_t loc = filter->start;
++      struct page *page;
++      unsigned long count = 0;
++      int err = 0;
++      unsigned long sz;
++
++      printk("pass %d, start off 0x%llx end offset 0x%llx\n", pass,
++                      filter->start, filter->end);
++
++      /* loc will get treated as logical offset into stage 1 */
++      page = dump_get_saved_page(loc);
++                      
++      for (; loc < filter->end; loc += PAGE_SIZE) {
++              dump_config.dumper->curr_loc = loc;
++              if (!page) {
++                      printk("no more saved data for pass %d\n", pass);
++                      break;
++              }
++              sz = (loc + PAGE_SIZE > filter->end) ? filter->end - loc :
++                      PAGE_SIZE;
++
++              if (page && filter->selector(pass, (unsigned long)page, 
++                      PAGE_SIZE))  {
++                      pr_debug("mem offset 0x%llx\n", loc);
++                      if ((err = action((unsigned long)page, sz))) 
++                              break;
++                      else
++                              count++;
++                      /* clear the contents of page */
++                      /* fixme: consider using KM_DUMP instead */
++                      clear_highpage(page);
++                      
++              }
++              page = dump_next_saved_page();
++      }
++
++      return err ? err : count;
++}
++
++static inline int dump_overlay_pages_done(struct page *page, int nr)
++{
++      int ret=0;
++
++      for (; nr ; page++, nr--) {
++              if (dump_check_and_free_page(dump_memdev, page))
++                      ret++;
++      }
++      return ret;
++}
++
++int dump_overlay_save_data(unsigned long loc, unsigned long len)
++{
++      int err = 0;
++      struct page *page = (struct page *)loc;
++      static unsigned long cnt = 0;
++
++      if ((err = dump_generic_save_data(loc, len)))
++              return err;
++
++      if (dump_overlay_pages_done(page, len >> PAGE_SHIFT)) {
++              cnt++;
++              if (!(cnt & 0x7f))
++                      pr_debug("released page 0x%lx\n", page_to_pfn(page));
++      }
++      
++      return err;
++}
++
++
++int dump_overlay_skip_data(unsigned long loc, unsigned long len)
++{
++      struct page *page = (struct page *)loc;
++
++      dump_overlay_pages_done(page, len >> PAGE_SHIFT);
++      return 0;
++}
++
++int dump_overlay_resume(void)
++{
++      int err = 0;
++
++      /* 
++       * switch to stage 2 dumper, save dump_config_block
++       * and then trigger a soft-boot
++       */
++      dumper_stage2.header_len = dump_config.dumper->header_len;
++      dump_config.dumper = &dumper_stage2;
++      if ((err = dump_save_config(dump_saved_config)))
++              return err;
++
++      dump_dev = dump_config.dumper->dev;
++
++      return err;
++      err = dump_switchover_stage();  /* plugs into soft boot mechanism */
++      dump_config.dumper = &dumper_stage1; /* set things back */
++      return err;
++}
++
++int dump_overlay_configure(unsigned long devid)
++{
++      struct dump_dev *dev;
++      struct dump_config_block *saved_config = dump_saved_config;
++      int err = 0;
++
++      /* If there is a previously saved dump, write it out first */
++      if (saved_config) {
++              printk("Processing old dump pending writeout\n");
++              err = dump_switchover_stage();
++              if (err) {
++                      printk("failed to writeout saved dump\n");
++                      return err;
++              }
++              dump_free_mem(saved_config); /* testing only: not after boot */
++      }
++
++      dev = dumper_stage2.dev = dump_config.dumper->dev;
++      /* From here on the intermediate dump target is memory-only */
++      dump_dev = dump_config.dumper->dev = &dump_memdev->ddev;
++      if ((err = dump_generic_configure(0))) {
++              printk("dump generic configure failed: err %d\n", err);
++              return err;
++      }
++      /* temporary */
++      dumper_stage2.dump_buf = dump_config.dumper->dump_buf;
++
++      /* Sanity check on the actual target dump device */
++      if (!dev || (err = dev->ops->open(dev, devid))) {
++              return err;
++      }
++      /* TBD: should we release the target if this is soft-boot only ? */
++
++      /* alloc a dump config block area to save across reboot */
++      if (!(dump_saved_config = dump_alloc_mem(sizeof(struct 
++              dump_config_block)))) {
++              printk("dump config block alloc failed\n");
++              /* undo configure */
++              dump_generic_unconfigure();
++              return -ENOMEM;
++      }
++      dump_config.dump_addr = (unsigned long)dump_saved_config;
++      printk("Dump config block of size %d set up at 0x%lx\n", 
++              sizeof(*dump_saved_config), (unsigned long)dump_saved_config);
++      return 0;
++}
++
++int dump_overlay_unconfigure(void)
++{
++      struct dump_dev *dev = dumper_stage2.dev;
++      int err = 0;
++
++      pr_debug("dump_overlay_unconfigure\n");
++      /* Close the secondary device */
++      dev->ops->release(dev); 
++      pr_debug("released secondary device\n");
++
++      err = dump_generic_unconfigure();
++      pr_debug("Unconfigured generic portions\n");
++      dump_free_mem(dump_saved_config);
++      dump_saved_config = NULL;
++      pr_debug("Freed saved config block\n");
++      dump_dev = dump_config.dumper->dev = dumper_stage2.dev;
++
++      printk("Unconfigured overlay dumper\n");
++      return err;
++}
++
++int dump_staged_unconfigure(void)
++{
++      int err = 0;
++      struct dump_config_block *saved_config = dump_saved_config;
++      struct dump_dev *dev;
++
++      pr_debug("dump_staged_unconfigure\n");
++      err = dump_generic_unconfigure();
++
++      /* now check if there is a saved dump waiting to be written out */
++      if (saved_config) {
++              printk("Processing saved dump pending writeout\n");
++              if ((err = dump_switchover_stage())) {
++                      printk("Error in commiting saved dump at 0x%lx\n", 
++                              (unsigned long)saved_config);
++                      printk("Old dump may hog memory\n");
++              } else {
++                      dump_free_mem(saved_config);
++                      pr_debug("Freed saved config block\n");
++              }
++              dump_saved_config = NULL;
++      } else {
++              dev = &dump_memdev->ddev;
++              dev->ops->release(dev);
++      }
++      printk("Unconfigured second stage dumper\n");
++
++      return 0;
++}
++
++/* ----- PASSTHRU FILTER ROUTINE --------- */
++
++/* transparent - passes everything through */
++int dump_passthru_filter(int pass, unsigned long loc, unsigned long sz)
++{
++      return 1;
++}
++
++/* ----- PASSTRU FORMAT ROUTINES ---- */
++
++
++int dump_passthru_configure_header(const char *panic_str, const struct pt_regs *regs)
++{
++      dump_config.dumper->header_dirty++;
++      return 0;
++}
++
++/* Copies bytes of data from page(s) to the specified buffer */
++int dump_copy_pages(void *buf, struct page *page, unsigned long sz)
++{
++      unsigned long len = 0, bytes;
++      void *addr;
++
++      while (len < sz) {
++              addr = kmap_atomic(page, KM_DUMP);
++              bytes = (sz > len + PAGE_SIZE) ? PAGE_SIZE : sz - len;  
++              memcpy(buf, addr, bytes); 
++              kunmap_atomic(addr, KM_DUMP);
++              buf += bytes;
++              len += bytes;
++              page++;
++      }
++      /* memset(dump_config.dumper->curr_buf, 0x57, len); temporary */
++
++      return sz - len;
++}
++
++int dump_passthru_update_header(void)
++{
++      long len = dump_config.dumper->header_len;
++      struct page *page;
++      void *buf = dump_config.dumper->dump_buf;
++      int err = 0;
++
++      if (!dump_config.dumper->header_dirty)
++              return 0;
++
++      pr_debug("Copying header of size %ld bytes from memory\n", len);
++      if (len > DUMP_BUFFER_SIZE) 
++              return -E2BIG;
++
++      page = dump_mem_lookup(dump_memdev, 0);
++      for (; (len > 0) && page; buf += PAGE_SIZE, len -= PAGE_SIZE) {
++              if ((err = dump_copy_pages(buf, page, PAGE_SIZE)))
++                      return err;
++              page = dump_mem_next_page(dump_memdev);
++      }
++      if (len > 0) {
++              printk("Incomplete header saved in mem\n");
++              return -ENOENT;
++      }
++
++      if ((err = dump_dev_seek(0))) {
++              printk("Unable to seek to dump header offset\n");
++              return err;
++      }
++      err = dump_ll_write(dump_config.dumper->dump_buf, 
++              buf - dump_config.dumper->dump_buf);
++      if (err < dump_config.dumper->header_len)
++              return (err < 0) ? err : -ENOSPC;
++
++      dump_config.dumper->header_dirty = 0;
++      return 0;
++}
++
++static loff_t next_dph_offset = 0;
++
++static int dph_valid(struct __dump_page *dph)
++{
++      if ((dph->dp_address & (PAGE_SIZE - 1)) || (dph->dp_flags 
++            > DUMP_DH_COMPRESSED) || (!dph->dp_flags) ||
++              (dph->dp_size > PAGE_SIZE)) {
++      printk("dp->address = 0x%llx, dp->size = 0x%x, dp->flag = 0x%x\n",
++              dph->dp_address, dph->dp_size, dph->dp_flags);
++              return 0;
++      }
++      return 1;
++}
++
++int dump_verify_lcrash_data(void *buf, unsigned long sz)
++{
++      struct __dump_page *dph;
++
++      /* sanity check for page headers */
++      while (next_dph_offset + sizeof(*dph) < sz) {
++              dph = (struct __dump_page *)(buf + next_dph_offset);
++              if (!dph_valid(dph)) {
++                      printk("Invalid page hdr at offset 0x%llx\n",
++                              next_dph_offset);
++                      return -EINVAL;
++              }
++              next_dph_offset += dph->dp_size + sizeof(*dph);
++      }
++
++      next_dph_offset -= sz;  
++      return 0;
++}
++
++/* 
++ * TBD/Later: Consider avoiding the copy by using a scatter/gather 
++ * vector representation for the dump buffer
++ */
++int dump_passthru_add_data(unsigned long loc, unsigned long sz)
++{
++      struct page *page = (struct page *)loc;
++      void *buf = dump_config.dumper->curr_buf;
++      int err = 0;
++
++      if ((err = dump_copy_pages(buf, page, sz))) {
++              printk("dump_copy_pages failed");
++              return err;
++      }
++
++      if ((err = dump_verify_lcrash_data(buf, sz))) {
++              printk("dump_verify_lcrash_data failed\n");
++              printk("Invalid data for pfn 0x%lx\n", page_to_pfn(page));
++              printk("Page flags 0x%lx\n", page->flags);
++              printk("Page count 0x%x\n", atomic_read(&page->count));
++              return err;
++      }
++
++      dump_config.dumper->curr_buf = buf + sz;
++
++      return 0;
++}
++
++
++/* Stage 1 dumper: Saves compressed dump in memory and soft-boots system */
++
++/* Scheme to overlay saved data in memory for writeout after a soft-boot */
++struct dump_scheme_ops dump_scheme_overlay_ops = {
++      .configure      = dump_overlay_configure,
++      .unconfigure    = dump_overlay_unconfigure,
++      .sequencer      = dump_overlay_sequencer,
++      .iterator       = dump_page_iterator,
++      .save_data      = dump_overlay_save_data,
++      .skip_data      = dump_overlay_skip_data,
++      .write_buffer   = dump_generic_write_buffer
++};
++
++struct dump_scheme dump_scheme_overlay = {
++      .name           = "overlay",
++      .ops            = &dump_scheme_overlay_ops
++};
++
++
++/* Stage 1 must use a good compression scheme - default to gzip */
++extern struct __dump_compress dump_gzip_compression;
++
++struct dumper dumper_stage1 = {
++      .name           = "stage1",
++      .scheme         = &dump_scheme_overlay,
++      .fmt            = &dump_fmt_lcrash,
++      .compress       = &dump_none_compression, /* needs to be gzip */
++      .filter         = dump_filter_table,
++      .dev            = NULL,
++};            
++
++/* Stage 2 dumper: Activated after softboot to write out saved dump to device */
++
++/* Formatter that transfers data as is (transparent) w/o further conversion */
++struct dump_fmt_ops dump_fmt_passthru_ops = {
++      .configure_header       = dump_passthru_configure_header,
++      .update_header          = dump_passthru_update_header,
++      .save_context           = NULL, /* unused */
++      .add_data               = dump_passthru_add_data,
++      .update_end_marker      = dump_lcrash_update_end_marker
++};
++
++struct dump_fmt dump_fmt_passthru = {
++      .name   = "passthru",
++      .ops    = &dump_fmt_passthru_ops
++};
++
++/* Filter that simply passes along any data within the range (transparent)*/
++/* Note: The start and end ranges in the table are filled in at run-time */
++
++extern int dump_filter_none(int pass, unsigned long loc, unsigned long sz);
++
++struct dump_data_filter dump_passthru_filtertable[MAX_PASSES] = {
++{.name = "passkern", .selector = dump_passthru_filter, 
++      .level_mask = DUMP_MASK_KERN },
++{.name = "passuser", .selector = dump_passthru_filter, 
++      .level_mask = DUMP_MASK_USED },
++{.name = "passunused", .selector = dump_passthru_filter, 
++      .level_mask = DUMP_MASK_UNUSED },
++{.name = "none", .selector = dump_filter_none, 
++      .level_mask = DUMP_MASK_REST }
++};
++
++
++/* Scheme to handle data staged / preserved across a soft-boot */
++struct dump_scheme_ops dump_scheme_staged_ops = {
++      .configure      = dump_generic_configure,
++      .unconfigure    = dump_staged_unconfigure,
++      .sequencer      = dump_generic_sequencer,
++      .iterator       = dump_saved_data_iterator,
++      .save_data      = dump_generic_save_data,
++      .skip_data      = dump_generic_skip_data,
++      .write_buffer   = dump_generic_write_buffer
++};
++
++struct dump_scheme dump_scheme_staged = {
++      .name           = "staged",
++      .ops            = &dump_scheme_staged_ops
++};
++
++/* The stage 2 dumper comprising all these */
++struct dumper dumper_stage2 = {
++      .name           = "stage2",
++      .scheme         = &dump_scheme_staged,
++      .fmt            = &dump_fmt_passthru,
++      .compress       = &dump_none_compression,
++      .filter         = dump_passthru_filtertable,
++      .dev            = NULL,
++};            
++
+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.
++ *
++ * Created by: Matt Robinson (yakker@sourceforge.net)
++ * Copyright 2001 Matt D. Robinson.  All rights reserved.
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/* header files */
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/init.h>
++#include <linux/dump.h>
++
++/*
++ * Name: dump_compress_rle()
++ * Func: Compress a DUMP_PAGE_SIZE (hardware) page down to something more
++ *       reasonable, if possible.  This is the same routine we use in IRIX.
++ */
++static u16
++dump_compress_rle(const u8 *old, u16 oldsize, u8 *new, u16 newsize)
++{
++      u16 ri, wi, count = 0;
++      u_char value = 0, cur_byte;
++
++      /*
++       * If the block should happen to "compress" to larger than the
++       * buffer size, allocate a larger one and change cur_buf_size.
++       */
++
++      wi = ri = 0;
++
++      while (ri < oldsize) {
++              if (!ri) {
++                      cur_byte = value = old[ri];
++                      count = 0;
++              } else {
++                      if (count == 255) {
++                              if (wi + 3 > oldsize) {
++                                      return oldsize;
++                              }
++                              new[wi++] = 0;
++                              new[wi++] = count;
++                              new[wi++] = value;
++                              value = cur_byte = old[ri];
++                              count = 0;
++                      } else { 
++                              if ((cur_byte = old[ri]) == value) {
++                                      count++;
++                              } else {
++                                      if (count > 1) {
++                                              if (wi + 3 > oldsize) {
++                                                      return oldsize;
++                                              }
++                                              new[wi++] = 0;
++                                              new[wi++] = count;
++                                              new[wi++] = value;
++                                      } else if (count == 1) {
++                                              if (value == 0) {
++                                                      if (wi + 3 > oldsize) {
++                                                              return oldsize;
++                                                      }
++                                                      new[wi++] = 0;
++                                                      new[wi++] = 1;
++                                                      new[wi++] = 0;
++                                              } else {
++                                                      if (wi + 2 > oldsize) {
++                                                              return oldsize;
++                                                      }
++                                                      new[wi++] = value;
++                                                      new[wi++] = value;
++                                              }
++                                      } else { /* count == 0 */
++                                              if (value == 0) {
++                                                      if (wi + 2 > oldsize) {
++                                                              return oldsize;
++                                                      }
++                                                      new[wi++] = value;
++                                                      new[wi++] = value;
++                                              } else {
++                                                      if (wi + 1 > oldsize) {
++                                                              return oldsize;
++                                                      }
++                                                      new[wi++] = value;
++                                              }
++                                      } /* if count > 1 */
++
++                                      value = cur_byte;
++                                      count = 0;
++
++                              } /* if byte == value */
++
++                      } /* if count == 255 */
++
++              } /* if ri == 0 */
++              ri++;
++
++      }
++      if (count > 1) {
++              if (wi + 3 > oldsize) {
++                      return oldsize;
++              }
++              new[wi++] = 0;
++              new[wi++] = count;
++              new[wi++] = value;
++      } else if (count == 1) {
++              if (value == 0) {
++                      if (wi + 3 > oldsize)
++                              return oldsize;
++                      new[wi++] = 0;
++                      new[wi++] = 1;
++                      new[wi++] = 0;
++              } else {
++                      if (wi + 2 > oldsize)
++                              return oldsize;
++                      new[wi++] = value;
++                      new[wi++] = value;
++              }
++      } else { /* count == 0 */
++              if (value == 0) {
++                      if (wi + 2 > oldsize)
++                              return oldsize;
++                      new[wi++] = value;
++                      new[wi++] = value;
++              } else {
++                      if (wi + 1 > oldsize)
++                              return oldsize;
++                      new[wi++] = value;
++              }
++      } /* if count > 1 */
++
++      value = cur_byte;
++      count = 0;
++      return wi;
++}
++
++/* setup the rle compression functionality */
++static struct __dump_compress dump_rle_compression = {
++      .compress_type = DUMP_COMPRESS_RLE,
++      .compress_func = dump_compress_rle,
++      .compress_name = "RLE",
++};
++
++/*
++ * Name: dump_compress_rle_init()
++ * Func: Initialize rle compression for dumping.
++ */
++static int __init
++dump_compress_rle_init(void)
++{
++      dump_register_compression(&dump_rle_compression);
++      return 0;
++}
++
++/*
++ * Name: dump_compress_rle_cleanup()
++ * Func: Remove rle compression for dumping.
++ */
++static void __exit
++dump_compress_rle_cleanup(void)
++{
++      dump_unregister_compression(DUMP_COMPRESS_RLE);
++}
++
++/* module initialization */
++module_init(dump_compress_rle_init);
++module_exit(dump_compress_rle_cleanup);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
++MODULE_DESCRIPTION("RLE compression module for crash dump driver");
+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
++ *
++ * Previously a part of dump_base.c
++ *
++ * Started: Oct 2002 -  Suparna Bhattacharya <suparna@in.ibm.com>
++ *    Split and rewrote LKCD dump scheme to generic dump method 
++ *    interfaces 
++ * Derived from original code created by
++ *    Matt Robinson <yakker@sourceforge.net>)
++ *
++ * Contributions from SGI, IBM, HP, MCL, and others.
++ *
++ * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
++ * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/*
++ * Implements the default dump scheme, i.e. single-stage gathering and 
++ * saving of dump data directly to the target device, which operates in
++ * a push mode, where the dumping system decides what data it saves
++ * taking into account pre-specified dump config options.
++ *
++ * Aside: The 2-stage dump scheme, where there is a soft-reset between
++ * the gathering and saving phases, also reuses some of these
++ * default routines (see dump_overlay.c) 
++ */ 
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/reboot.h>
++#include <linux/nmi.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++
++extern int panic_timeout;  /* time before reboot */
++
++extern void dump_speedo(int);
++
++/* Default sequencer used during single stage dumping */
++/* Also invoked during stage 2 of soft-boot based dumping */
++int dump_generic_sequencer(void)
++{
++      struct dump_data_filter *filter = dump_config.dumper->filter;
++      int pass = 0, err = 0, save = 0;
++      int (*action)(unsigned long, unsigned long);
++
++      /* 
++       * We want to save the more critical data areas first in 
++       * case we run out of space, encounter i/o failures, or get
++       * interrupted otherwise and have to give up midway
++       * So, run through the passes in increasing order 
++       */
++      for (;filter->selector; filter++, pass++)
++      {
++              /* Assumes passes are exclusive (even across dumpers) */
++              /* Requires care when coding the selection functions */
++              if ((save = filter->level_mask & dump_config.level))
++                      action = dump_save_data;
++              else
++                      action = dump_skip_data;
++
++              if ((err = dump_iterator(pass, action, filter)) < 0)
++                      break;
++
++              printk("\n %d dump pages %s of %d each in pass %d\n", 
++              err, save ? "saved" : "skipped", DUMP_PAGE_SIZE, pass);
++
++      }
++
++      return (err < 0) ? err : 0;
++}
++
++static inline struct page *dump_get_page(loff_t loc)
++{
++      unsigned long page_index = loc >> PAGE_SHIFT;
++
++      /* todo: complete this  to account for ia64/discontig mem */
++      /* todo: and to check for validity, ram page, no i/o mem etc */
++      /* need to use pfn/physaddr equiv of kern_addr_valid */
++      if (__dump_page_valid(page_index))
++              return pfn_to_page(page_index);
++      else
++              return NULL;
++
++}
++
++/* Default iterator: for singlestage and stage 1 of soft-boot dumping */
++/* Iterates over range of physical memory pages in DUMP_PAGE_SIZE increments */
++int dump_page_iterator(int pass, int (*action)(unsigned long, unsigned long), 
++      struct dump_data_filter *filter)
++{
++      /* Todo : fix unit, type */
++      loff_t loc;
++      int count = 0, err = 0;
++      struct page *page;
++
++      /* Todo: Add membanks code */
++      /* TBD: Check if we need to address DUMP_PAGE_SIZE < PAGE_SIZE */       
++      
++      for (loc = filter->start; loc < filter->end; loc += DUMP_PAGE_SIZE) {
++              dump_config.dumper->curr_loc = loc;
++              page = dump_get_page(loc);
++              if (page && filter->selector(pass, (unsigned long) page, 
++              DUMP_PAGE_SIZE)) {
++                      if ((err = action((unsigned long)page, DUMP_PAGE_SIZE)))
++                      {
++                              printk("dump_page_iterator: err %d for loc "
++                              "0x%llx, in pass %d\n", err, loc, pass);
++                              break;
++                      } else
++                              count++;
++              }
++      }
++
++      return err ? err : count;
++}
++
++/* 
++ * Base function that saves the selected block of data in the dump 
++ * Action taken when iterator decides that data needs to be saved 
++ */
++int dump_generic_save_data(unsigned long loc, unsigned long sz)
++{
++      void *buf;
++      void *dump_buf = dump_config.dumper->dump_buf;
++      int left, bytes, ret;
++
++      if ((ret = dump_add_data(loc, sz))) {
++              return ret;
++      }
++      buf = dump_config.dumper->curr_buf;
++
++      /* If we've filled up the buffer write it out */
++      if ((left = buf - dump_buf) >= DUMP_BUFFER_SIZE) {
++              bytes = dump_write_buffer(dump_buf, DUMP_BUFFER_SIZE);
++              if (bytes < DUMP_BUFFER_SIZE) {
++                      printk("dump_write_buffer failed %d\n", bytes);
++                      return bytes ? -ENOSPC : bytes;
++              }
++
++              left -= bytes;
++              
++              /* -- A few chores to do from time to time -- */
++              dump_config.dumper->count++;
++
++              if (!(dump_config.dumper->count & 0x3f)) {
++                      /* Update the header every one in a while */
++                      memset((void *)dump_buf, 'b', DUMP_BUFFER_SIZE);
++                      if ((ret = dump_update_header()) < 0) {
++                              /* issue warning */
++                              return ret;
++                      }
++                      printk(".");
++
++                      touch_nmi_watchdog();
++              } else if (!(dump_config.dumper->count & 0x7)) {
++                      /* Show progress so the user knows we aren't hung */
++                      dump_speedo(dump_config.dumper->count >> 3); 
++              }
++              /* Todo: Touch/Refresh watchdog */
++
++              /* --- Done with periodic chores -- */
++
++              /* 
++               * extra bit of copying to simplify verification  
++               * in the second kernel boot based scheme
++               */
++              memcpy(dump_buf - DUMP_PAGE_SIZE, dump_buf + 
++                      DUMP_BUFFER_SIZE - DUMP_PAGE_SIZE, DUMP_PAGE_SIZE);
++
++              /* now adjust the leftover bits back to the top of the page */
++              /* this case would not arise during stage 2 (passthru) */
++              memset(dump_buf, 'z', DUMP_BUFFER_SIZE);
++              if (left) {
++                      memcpy(dump_buf, dump_buf + DUMP_BUFFER_SIZE, left);
++              }
++              buf -= DUMP_BUFFER_SIZE;
++              dump_config.dumper->curr_buf = buf;
++      }
++                              
++      return 0;
++}
++
++int dump_generic_skip_data(unsigned long loc, unsigned long sz)
++{
++      /* dummy by default */
++      return 0;
++}
++
++/* 
++ * Common low level routine to write a buffer to current dump device 
++ * Expects checks for space etc to have been taken care of by the caller 
++ * Operates serially at the moment for simplicity. 
++ * TBD/Todo: Consider batching for improved throughput
++ */
++int dump_ll_write(void *buf, unsigned long len)
++{
++      long transferred = 0, last_transfer = 0;
++      int ret = 0;
++
++      /* make sure device is ready */
++      while ((ret = dump_dev_ready(NULL)) == -EAGAIN);
++      if  (ret < 0) {
++              printk("dump_dev_ready failed !err %d\n", ret);
++              return ret;
++      }
++
++      while (len) {
++              if ((last_transfer = dump_dev_write(buf, len)) <= 0)  {
++                      ret = last_transfer;
++                      printk("dump_dev_write failed !err %d\n", 
++                      ret);
++                      break;
++              }
++              /* wait till complete */
++              while ((ret = dump_dev_ready(buf)) == -EAGAIN)
++                      cpu_relax();
++
++              if  (ret < 0) {
++                      printk("i/o failed !err %d\n", ret);
++                      break;
++              }
++
++              len -= last_transfer;
++              buf += last_transfer;
++              transferred += last_transfer;
++      }
++      return (ret < 0) ? ret : transferred;
++}
++
++/* default writeout routine for single dump device */
++/* writes out the dump data ensuring enough space is left for the end marker */
++int dump_generic_write_buffer(void *buf, unsigned long len)
++{
++      long written = 0;
++      int err = 0;
++
++      /* check for space */
++      if ((err = dump_dev_seek(dump_config.dumper->curr_offset + len + 
++                      2*DUMP_BUFFER_SIZE)) < 0) {
++              printk("dump_write_buffer: insuff space after offset 0x%llx\n",
++                      dump_config.dumper->curr_offset);
++              return err;
++      }
++      /* alignment check would happen as a side effect of this */
++      if ((err = dump_dev_seek(dump_config.dumper->curr_offset)) < 0)
++              return err; 
++
++      written = dump_ll_write(buf, len);
++
++      /* all or none */
++
++      if (written < len)
++              written = written ? -ENOSPC : written;
++      else
++              dump_config.dumper->curr_offset += len;
++
++      return written;
++}
++
++int dump_generic_configure(unsigned long devid)
++{
++      struct dump_dev *dev = dump_config.dumper->dev;
++      struct dump_data_filter *filter;
++      void *buf;
++      int ret = 0;
++
++      /* Allocate the dump buffer and initialize dumper state */
++      /* Assume that we get aligned addresses */
++      if (!(buf = dump_alloc_mem(DUMP_BUFFER_SIZE + 3 * DUMP_PAGE_SIZE)))
++              return -ENOMEM;
++
++      if ((unsigned long)buf & (PAGE_SIZE - 1)) {
++              /* sanity check for page aligned address */
++              dump_free_mem(buf);
++              return -ENOMEM; /* fixme: better error code */
++      }
++
++      /* Initialize the rest of the fields */
++      dump_config.dumper->dump_buf = buf + DUMP_PAGE_SIZE;
++      dumper_reset();
++
++      /* Open the dump device */
++      if (!dev)
++              return -ENODEV;
++
++      if ((ret = dev->ops->open(dev, devid))) {
++             return ret;
++      }
++
++      /* Initialise the memory ranges in the dump filter */
++      for (filter = dump_config.dumper->filter ;filter->selector; filter++) {
++              if (!filter->start && !filter->end) {
++                      filter->start = 0;
++                      filter->end = num_physpages << PAGE_SHIFT;
++              }
++      }
++
++      return 0;
++}
++
++int dump_generic_unconfigure(void)
++{
++      struct dump_dev *dev = dump_config.dumper->dev;
++      void *buf = dump_config.dumper->dump_buf;
++      int ret = 0;
++
++      pr_debug("Generic unconfigure\n");
++      /* Close the dump device */
++      if (dev && (ret = dev->ops->release(dev)))
++              return ret;
++
++      printk("Closed dump device\n");
++      
++      if (buf)
++              dump_free_mem((buf - DUMP_PAGE_SIZE));
++
++      dump_config.dumper->curr_buf = dump_config.dumper->dump_buf = NULL;
++      pr_debug("Released dump buffer\n");
++
++      return 0;
++}
++
++
++/* Set up the default dump scheme */
++
++struct dump_scheme_ops dump_scheme_singlestage_ops = {
++      .configure      = dump_generic_configure,
++      .unconfigure    = dump_generic_unconfigure,
++      .sequencer      = dump_generic_sequencer,
++      .iterator       = dump_page_iterator,
++      .save_data      = dump_generic_save_data,
++      .skip_data      = dump_generic_skip_data,
++      .write_buffer   = dump_generic_write_buffer,
++};
++
++struct dump_scheme dump_scheme_singlestage = {
++      .name           = "single-stage",
++      .ops            = &dump_scheme_singlestage_ops
++};
++
++/* The single stage dumper comprising all these */
++struct dumper dumper_singlestage = {
++      .name           = "single-stage",
++      .scheme         = &dump_scheme_singlestage,
++      .fmt            = &dump_fmt_lcrash,
++      .compress       = &dump_none_compression,
++      .filter         = dump_filter_table,
++      .dev            = NULL,
++};            
++
+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.
++ *
++ * Created by: Matt Robinson (yakker@sourceforge.net)
++ * Contributions from SGI, IBM, HP, MCL, and others.
++ *
++ * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
++ * Copyright (C) 2000 - 2002 TurboLinux, Inc.  All rights reserved.
++ * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 Free Software Foundation, Inc. All rights reserved.
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/*
++ * -----------------------------------------------------------------------
++ *
++ * DUMP HISTORY
++ *
++ * This dump code goes back to SGI's first attempts at dumping system
++ * memory on SGI systems running IRIX.  A few developers at SGI needed
++ * a way to take this system dump and analyze it, and created 'icrash',
++ * or IRIX Crash.  The mechanism (the dumps and 'icrash') were used
++ * by support people to generate crash reports when a system failure
++ * occurred.  This was vital for large system configurations that
++ * couldn't apply patch after patch after fix just to hope that the
++ * problems would go away.  So the system memory, along with the crash
++ * dump analyzer, allowed support people to quickly figure out what the
++ * problem was on the system with the crash dump.
++ *
++ * In comes Linux.  SGI started moving towards the open source community,
++ * and upon doing so, SGI wanted to take its support utilities into Linux
++ * with the hopes that they would end up the in kernel and user space to
++ * be used by SGI's customers buying SGI Linux systems.  One of the first
++ * few products to be open sourced by SGI was LKCD, or Linux Kernel Crash
++ * Dumps.  LKCD comprises of a patch to the kernel to enable system
++ * dumping, along with 'lcrash', or Linux Crash, to analyze the system
++ * memory dump.  A few additional system scripts and kernel modifications
++ * are also included to make the dump mechanism and dump data easier to
++ * process and use.
++ *
++ * As soon as LKCD was released into the open source community, a number
++ * of larger companies started to take advantage of it.  Today, there are
++ * many community members that contribute to LKCD, and it continues to
++ * flourish and grow as an open source project.
++ */
++
++/*
++ * DUMP TUNABLES
++ *
++ * This is the list of system tunables (via /proc) that are available
++ * for Linux systems.  All the read, write, etc., functions are listed
++ * here.  Currently, there are a few different tunables for dumps:
++ *
++ * dump_device (used to be dumpdev):
++ *     The device for dumping the memory pages out to.  This 
++ *     may be set to the primary swap partition for disruptive dumps,
++ *     and must be an unused partition for non-disruptive dumps.
++ *     Todo: In the case of network dumps, this may be interpreted 
++ *     as the IP address of the netdump server to connect to.
++ *
++ * dump_compress (used to be dump_compress_pages):
++ *     This is the flag which indicates which compression mechanism
++ *     to use.  This is a BITMASK, not an index (0,1,2,4,8,16,etc.).
++ *     This is the current set of values:
++ *
++ *     0: DUMP_COMPRESS_NONE -- Don't compress any pages.
++ *     1: DUMP_COMPRESS_RLE  -- This uses RLE compression.
++ *     2: DUMP_COMPRESS_GZIP -- This uses GZIP compression.
++ *
++ * dump_level:
++ *     The amount of effort the dump module should make to save
++ *     information for post crash analysis.  This value is now
++ *     a BITMASK value, not an index:
++ *
++ *     0:   Do nothing, no dumping. (DUMP_LEVEL_NONE)
++ *
++ *     1:   Print out the dump information to the dump header, and
++ *          write it out to the dump_device. (DUMP_LEVEL_HEADER)
++ *
++ *     2:   Write out the dump header and all kernel memory pages.
++ *          (DUMP_LEVEL_KERN)
++ *
++ *     4:   Write out the dump header and all kernel and user
++ *          memory pages.  (DUMP_LEVEL_USED)
++ *
++ *     8:   Write out the dump header and all conventional/cached 
++ *        memory (RAM) pages in the system (kernel, user, free).  
++ *        (DUMP_LEVEL_ALL_RAM)
++ *
++ *    16:   Write out everything, including non-conventional memory
++ *        like firmware, proms, I/O registers, uncached memory.
++ *        (DUMP_LEVEL_ALL)
++ *
++ *     The dump_level will default to 1.
++ *
++ * dump_flags:
++ *     These are the flags to use when talking about dumps.  There
++ *     are lots of possibilities.  This is a BITMASK value, not an index.
++ * 
++ * -----------------------------------------------------------------------
++ */
++
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/reboot.h>
++#include <linux/fs.h>
++#include <linux/dump.h>
++#include "dump_methods.h"
++#include <linux/proc_fs.h>
++#include <linux/module.h>
++#include <linux/utsname.h>
++#include <linux/highmem.h>
++#include <linux/major.h>
++#include <linux/sysrq.h>
++#include <linux/sysctl.h>
++#include <linux/nmi.h>
++
++#include <asm/hardirq.h>
++#include <asm/uaccess.h>
++
++/*
++ * -----------------------------------------------------------------------
++ *                         V A R I A B L E S
++ * -----------------------------------------------------------------------
++ */
++
++/* Dump tunables */
++struct dump_config dump_config = {
++      .level          = 0,
++      .flags          = 0,
++      .dump_device    = 0,
++      .dump_addr      = 0,
++      .dumper         = NULL
++};
++
++
++/* Global variables used in dump.h */
++/* degree of system freeze when dumping */
++enum dump_silence_levels dump_silence_level = DUMP_HARD_SPIN_CPUS;     
++
++/* Other global fields */
++extern struct __dump_header dump_header; 
++struct dump_dev *dump_dev = NULL;  /* Active dump device                   */
++static int dump_compress = 0;
++
++static u16 dump_compress_none(const u8 *old, u16 oldsize, u8 *new, u16 newsize);
++struct __dump_compress dump_none_compression = {
++      .compress_type  = DUMP_COMPRESS_NONE,
++      .compress_func  = dump_compress_none,
++      .compress_name  = "none",
++};
++
++/* our device operations and functions */
++static int dump_ioctl(struct inode *i, struct file *f,
++      unsigned int cmd, unsigned long arg);
++
++static struct file_operations dump_fops = {
++      .ioctl          =       dump_ioctl,
++};
++
++/* static variables                                                   */
++static int dump_okay = 0;             /* can we dump out to disk?     */
++static spinlock_t dump_lock = SPIN_LOCK_UNLOCKED;
++
++/* used for dump compressors */
++static struct list_head dump_compress_list = LIST_HEAD_INIT(dump_compress_list);
++
++/* list of registered dump targets */
++static struct list_head dump_target_list = LIST_HEAD_INIT(dump_target_list);
++
++/* lkcd info structure -- this is used by lcrash for basic system data     */
++struct __lkcdinfo lkcdinfo = {
++      .ptrsz          = (sizeof(void *) * 8),
++#if defined(__LITTLE_ENDIAN) 
++      .byte_order     = __LITTLE_ENDIAN,
++#else
++      .byte_order     = __BIG_ENDIAN,
++#endif
++      .page_shift     = PAGE_SHIFT,
++      .page_size      = PAGE_SIZE,
++      .page_mask      = PAGE_MASK,
++      .page_offset    = PAGE_OFFSET,
++};
++
++/*
++ * -----------------------------------------------------------------------
++ *            / P R O C   T U N A B L E   F U N C T I O N S
++ * -----------------------------------------------------------------------
++ */
++
++static int proc_dump_device(ctl_table *ctl, int write, struct file *f,
++                          void *buffer, size_t *lenp);
++
++static int proc_doulonghex(ctl_table *ctl, int write, struct file *f,
++                          void *buffer, size_t *lenp);
++/*
++ * sysctl-tuning infrastructure.
++ */
++static ctl_table dump_table[] = {
++      { .ctl_name = CTL_DUMP_LEVEL,
++        .procname = DUMP_LEVEL_NAME, 
++        .data = &dump_config.level,    
++        .maxlen = sizeof(int),
++        .mode = 0644,
++        .proc_handler = proc_doulonghex, },
++
++      { .ctl_name = CTL_DUMP_FLAGS,
++        .procname = DUMP_FLAGS_NAME,
++        .data = &dump_config.flags,   
++        .maxlen = sizeof(int),
++        .mode = 0644,
++        .proc_handler = proc_doulonghex, },
++
++      { .ctl_name = CTL_DUMP_COMPRESS,
++        .procname = DUMP_COMPRESS_NAME,
++        .data = &dump_compress, /* FIXME */
++        .maxlen = sizeof(int),
++        .mode = 0644,
++        .proc_handler = proc_dointvec, },
++        
++      { .ctl_name = CTL_DUMP_DEVICE,
++        .procname = DUMP_DEVICE_NAME,
++        .mode = 0644,
++        .data = &dump_config.dump_device, /* FIXME */
++        .maxlen = sizeof(int),
++        .proc_handler = proc_dump_device },
++
++#ifdef CONFIG_CRASH_DUMP_MEMDEV
++      { .ctl_name = CTL_DUMP_ADDR,
++        .procname = DUMP_ADDR_NAME,
++        .mode = 0444,
++        .data = &dump_config.dump_addr,
++        .maxlen = sizeof(unsigned long),
++        .proc_handler = proc_doulonghex },
++#endif
++
++      { 0, }
++};
++
++static ctl_table dump_root[] = {
++      { .ctl_name = KERN_DUMP,
++        .procname = "dump",
++        .mode = 0555, 
++        .child = dump_table },
++      { 0, }
++};
++
++static ctl_table kernel_root[] = {
++      { .ctl_name = CTL_KERN,
++        .procname = "kernel",
++        .mode = 0555,
++        .child = dump_root, },
++      { 0, }
++};
++
++static struct ctl_table_header *sysctl_header;
++
++/*
++ * -----------------------------------------------------------------------
++ *              C O M P R E S S I O N   F U N C T I O N S
++ * -----------------------------------------------------------------------
++ */
++
++/*
++ * Name: dump_compress_none()
++ * Func: Don't do any compression, period.
++ */
++static u16
++dump_compress_none(const u8 *old, u16 oldsize, u8 *new, u16 newsize)
++{
++      /* just return the old size */
++      return oldsize;
++}
++
++
++/*
++ * Name: dump_execute()
++ * Func: Execute the dumping process.  This makes sure all the appropriate
++ *       fields are updated correctly, and calls dump_execute_memdump(),
++ *       which does the real work.
++ */
++void
++dump_execute(const char *panic_str, const struct pt_regs *regs)
++{
++      int state = -1;
++      unsigned long flags;
++
++      /* make sure we can dump */
++      if (!dump_okay) {
++              pr_info("LKCD not yet configured, can't take dump now\n");
++              return;
++      }
++
++      /* Exclude multiple dumps at the same time,
++       * and disable interrupts,  some drivers may re-enable
++       * interrupts in with silence()
++       *
++       * Try and acquire spin lock. If successful, leave preempt
++       * and interrupts disabled.  See spin_lock_irqsave in spinlock.h
++       */
++      local_irq_save(flags);
++      if (!spin_trylock(&dump_lock)) {
++              local_irq_restore(flags);
++              pr_info("LKCD dump already in progress\n");
++              return;
++      }
++
++      /* Bring system into the strictest level of quiescing for min drift 
++       * dump drivers can soften this as required in dev->ops->silence() 
++       */
++      dump_oncpu = smp_processor_id() + 1;
++      dump_silence_level = DUMP_HARD_SPIN_CPUS; 
++
++      state = dump_generic_execute(panic_str, regs);
++      
++      dump_oncpu = 0;
++      spin_unlock_irqrestore(&dump_lock, flags);
++
++      if (state < 0) {
++              printk("Dump Incomplete or failed!\n");
++      } else {
++              printk("Dump Complete; %d dump pages saved.\n", 
++                     dump_header.dh_num_dump_pages);
++      }
++}
++
++/*
++ * Name: dump_register_compression()
++ * Func: Register a dump compression mechanism.
++ */
++void
++dump_register_compression(struct __dump_compress *item)
++{
++      if (item)
++              list_add(&(item->list), &dump_compress_list);
++}
++
++/*
++ * Name: dump_unregister_compression()
++ * Func: Remove a dump compression mechanism, and re-assign the dump
++ *       compression pointer if necessary.
++ */
++void
++dump_unregister_compression(int compression_type)
++{
++      struct list_head *tmp;
++      struct __dump_compress *dc;
++
++      /* let's make sure our list is valid */
++      if (compression_type != DUMP_COMPRESS_NONE) {
++              list_for_each(tmp, &dump_compress_list) {
++                      dc = list_entry(tmp, struct __dump_compress, list);
++                      if (dc->compress_type == compression_type) {
++                              list_del(&(dc->list));
++                              break;
++                      }
++              }
++      }
++}
++
++/*
++ * Name: dump_compress_init()
++ * Func: Initialize (or re-initialize) compression scheme.
++ */
++static int
++dump_compress_init(int compression_type)
++{
++      struct list_head *tmp;
++      struct __dump_compress *dc;
++
++      /* try to remove the compression item */
++      list_for_each(tmp, &dump_compress_list) {
++              dc = list_entry(tmp, struct __dump_compress, list);
++              if (dc->compress_type == compression_type) {
++                      dump_config.dumper->compress = dc;
++                      dump_compress = compression_type;
++                      pr_debug("Dump Compress %s\n", dc->compress_name);
++                      return 0;
++              }
++      }
++
++      /* 
++       * nothing on the list -- return ENODATA to indicate an error 
++       *
++       * NB: 
++       *      EAGAIN: reports "Resource temporarily unavailable" which
++       *              isn't very enlightening.
++       */
++      printk("compression_type:%d not found\n", compression_type);
++
++      return -ENODATA;
++}
++
++static int
++dumper_setup(unsigned long flags, unsigned long devid)
++{
++      int ret = 0;
++
++      /* unconfigure old dumper if it exists */
++      dump_okay = 0;
++      if (dump_config.dumper) {
++              pr_debug("Unconfiguring current dumper\n");
++              dump_unconfigure();
++      }
++      /* set up new dumper */
++      if (dump_config.flags & DUMP_FLAGS_SOFTBOOT) {
++              printk("Configuring softboot based dump \n");
++#ifdef CONFIG_CRASH_DUMP_MEMDEV
++              dump_config.dumper = &dumper_stage1; 
++#else
++              printk("Requires CONFIG_CRASHDUMP_MEMDEV. Can't proceed.\n");
++              return -1;
++#endif
++      } else {
++              dump_config.dumper = &dumper_singlestage;
++      }       
++      dump_config.dumper->dev = dump_dev;
++
++      ret = dump_configure(devid);
++      if (!ret) {
++              dump_okay = 1;
++              pr_debug("%s dumper set up for dev 0x%lx\n", 
++                      dump_config.dumper->name, devid);
++              dump_config.dump_device = devid;
++      } else {
++              printk("%s dumper set up failed for dev 0x%lx\n", 
++                     dump_config.dumper->name, devid);
++              dump_config.dumper = NULL;
++      }
++      return ret;
++}
++
++static int
++dump_target_init(int target)
++{
++      char type[20];
++      struct list_head *tmp;
++      struct dump_dev *dev;
++      
++      switch (target) {
++              case DUMP_FLAGS_DISKDUMP:
++                      strcpy(type, "blockdev"); break;
++              case DUMP_FLAGS_NETDUMP:
++                      strcpy(type, "networkdev"); break;
++              default:
++                      return -1;
++      }
++
++      /*
++       * This is a bit stupid, generating strings from flag
++       * and doing strcmp. This is done because 'struct dump_dev'
++       * has string 'type_name' and not interger 'type'.
++       */
++      list_for_each(tmp, &dump_target_list) {
++              dev = list_entry(tmp, struct dump_dev, list);
++              if (strcmp(type, dev->type_name) == 0) {
++                      dump_dev = dev;
++                      return 0;
++              }
++      }
++      return -1;
++}
++
++/*
++ * Name: dump_ioctl()
++ * Func: Allow all dump tunables through a standard ioctl() mechanism.
++ *       This is far better than before, where we'd go through /proc,
++ *       because now this will work for multiple OS and architectures.
++ */
++static int
++dump_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
++{
++      /* check capabilities */
++      if (!capable(CAP_SYS_ADMIN))
++              return -EPERM;
++
++      if (!dump_config.dumper && cmd == DIOSDUMPCOMPRESS)
++              /* dump device must be configured first */
++              return -ENODEV;
++
++      /*
++       * This is the main mechanism for controlling get/set data
++       * for various dump device parameters.  The real trick here
++       * is setting the dump device (DIOSDUMPDEV).  That's what
++       * triggers everything else.
++       */
++      switch (cmd) {
++      case DIOSDUMPDEV:       /* set dump_device */
++              pr_debug("Configuring dump device\n"); 
++              if (!(f->f_flags & O_RDWR))
++                      return -EPERM;
++
++              __dump_open();
++              return dumper_setup(dump_config.flags, arg);
++
++              
++      case DIOGDUMPDEV:       /* get dump_device */
++              return put_user((long)dump_config.dump_device, (long *)arg);
++
++      case DIOSDUMPLEVEL:     /* set dump_level */
++              if (!(f->f_flags & O_RDWR))
++                      return -EPERM;
++
++              /* make sure we have a positive value */
++              if (arg < 0)
++                      return -EINVAL;
++
++              /* Fixme: clean this up */
++              dump_config.level = 0;
++              switch ((int)arg) {
++                      case DUMP_LEVEL_ALL:
++                      case DUMP_LEVEL_ALL_RAM:
++                              dump_config.level |= DUMP_MASK_UNUSED;
++                      case DUMP_LEVEL_USED:
++                              dump_config.level |= DUMP_MASK_USED;
++                      case DUMP_LEVEL_KERN:
++                              dump_config.level |= DUMP_MASK_KERN;
++                      case DUMP_LEVEL_HEADER:
++                              dump_config.level |= DUMP_MASK_HEADER;
++                      case DUMP_LEVEL_NONE:
++                              break;
++                      default:
++                              return (-EINVAL);
++                      }
++              pr_debug("Dump Level 0x%lx\n", dump_config.level);
++              break;
++
++      case DIOGDUMPLEVEL:     /* get dump_level */
++              /* fixme: handle conversion */
++              return put_user((long)dump_config.level, (long *)arg);
++
++              
++      case DIOSDUMPFLAGS:     /* set dump_flags */
++              /* check flags */
++              if (!(f->f_flags & O_RDWR))
++                      return -EPERM;
++
++              /* make sure we have a positive value */
++              if (arg < 0)
++                      return -EINVAL;
++                      
++              if (dump_target_init(arg & DUMP_FLAGS_TARGETMASK) < 0)
++                      return -EINVAL; /* return proper error */
++
++              dump_config.flags = arg;
++              
++              pr_debug("Dump Flags 0x%lx\n", dump_config.flags);
++              break;
++              
++      case DIOGDUMPFLAGS:     /* get dump_flags */
++              return put_user((long)dump_config.flags, (long *)arg);
++
++      case DIOSDUMPCOMPRESS:  /* set the dump_compress status */
++              if (!(f->f_flags & O_RDWR))
++                      return -EPERM;
++
++              return dump_compress_init((int)arg);
++
++      case DIOGDUMPCOMPRESS:  /* get the dump_compress status */
++              return put_user((long)(dump_config.dumper ? 
++                      dump_config.dumper->compress->compress_type : 0), 
++                      (long *)arg);
++                      
++      default:
++              /* 
++               * these are network dump specific ioctls, let the
++               * module handle them.
++               */
++              return dump_dev_ioctl(cmd, arg);
++      }
++      return 0;
++}
++
++/*
++ * Handle special cases for dump_device 
++ * changing dump device requires doing an opening the device
++ */
++static int 
++proc_dump_device(ctl_table *ctl, int write, struct file *f,
++               void *buffer, size_t *lenp)
++{
++      int *valp = ctl->data;
++      int oval = *valp;
++      int ret = -EPERM;
++
++      /* same permission checks as ioctl */
++      if (capable(CAP_SYS_ADMIN)) {
++              ret = proc_doulonghex(ctl, write, f, buffer, lenp);
++              if (ret == 0 && write && *valp != oval) {
++                      /* need to restore old value to close properly */
++                      dump_config.dump_device = (dev_t) oval;
++                      __dump_open();
++                      ret = dumper_setup(dump_config.flags, (dev_t) *valp);
++              }
++      }
++
++      return ret;
++}
++
++/* All for the want of a proc_do_xxx routine which prints values in hex */
++static int 
++proc_doulonghex(ctl_table *ctl, int write, struct file *f,
++               void *buffer, size_t *lenp)
++{
++#define TMPBUFLEN 20
++      unsigned long *i;
++      size_t len, left;
++      char buf[TMPBUFLEN];
++
++      if (!ctl->data || !ctl->maxlen || !*lenp || (f->f_pos)) {
++              *lenp = 0;
++              return 0;
++      }
++      
++      i = (unsigned long *) ctl->data;
++      left = *lenp;
++      
++      sprintf(buf, "0x%lx\n", (*i));
++      len = strlen(buf);
++      if (len > left)
++              len = left;
++      if(copy_to_user(buffer, buf, len))
++              return -EFAULT;
++      
++      left -= len;
++      *lenp -= left;
++      f->f_pos += *lenp;
++      return 0;
++}
++
++/*
++ * -----------------------------------------------------------------------
++ *                     I N I T   F U N C T I O N S
++ * -----------------------------------------------------------------------
++ */
++
++/*
++ * These register and unregister routines are exported for modules
++ * to register their dump drivers (like block, net etc)
++ */
++int
++dump_register_device(struct dump_dev *ddev)
++{
++      struct list_head *tmp;
++      struct dump_dev *dev;
++
++      list_for_each(tmp, &dump_target_list) {
++              dev = list_entry(tmp, struct dump_dev, list);
++              if (strcmp(ddev->type_name, dev->type_name) == 0) {
++                      printk("Target type %s already registered\n",
++                                      dev->type_name);
++                      return -1; /* return proper error */
++              }
++      }
++      list_add(&(ddev->list), &dump_target_list);
++      
++      return 0;
++}
++
++void
++dump_unregister_device(struct dump_dev *ddev)
++{
++      list_del(&(ddev->list));
++      if (ddev != dump_dev)
++              return;
++
++      dump_okay = 0;
++
++      if (dump_config.dumper)
++              dump_unconfigure();
++
++      dump_config.flags &= ~DUMP_FLAGS_TARGETMASK;
++      dump_okay = 0;
++      dump_dev = NULL;
++      dump_config.dumper = NULL;
++}
++
++static int panic_event(struct notifier_block *this, unsigned long event,
++                     void *ptr)
++{
++      struct pt_regs regs;
++
++      get_current_regs(&regs);
++      dump_execute((const char *)ptr, &regs);
++      return 0;
++}
++
++extern struct notifier_block *panic_notifier_list;
++static int panic_event(struct notifier_block *, unsigned long, void *);
++static struct notifier_block panic_block = {
++      .notifier_call = panic_event,
++};
++
++#ifdef CONFIG_MAGIC_SYSRQ
++/* Sysrq handler */
++static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
++              struct tty_struct *tty) {
++      dump_execute("sysrq", pt_regs);
++}
++
++static struct sysrq_key_op sysrq_crashdump_op = {
++      .handler        =       sysrq_handle_crashdump,
++      .help_msg       =       "Dump",
++      .action_msg     =       "Starting crash dump",
++};
++#endif
++
++static inline void
++dump_sysrq_register(void) 
++{
++#ifdef CONFIG_MAGIC_SYSRQ
++      __sysrq_lock_table();
++      __sysrq_put_key_op(DUMP_SYSRQ_KEY, &sysrq_crashdump_op);
++      __sysrq_unlock_table();
++#endif
++}
++
++static inline void
++dump_sysrq_unregister(void)
++{
++#ifdef CONFIG_MAGIC_SYSRQ
++      __sysrq_lock_table();
++      if (__sysrq_get_key_op(DUMP_SYSRQ_KEY) == &sysrq_crashdump_op)
++              __sysrq_put_key_op(DUMP_SYSRQ_KEY, NULL);
++      __sysrq_unlock_table();
++#endif
++}
++
++/*
++ * Name: dump_init()
++ * Func: Initialize the dump process.  This will set up any architecture
++ *       dependent code.  The big key is we need the memory offsets before
++ *       the page table is initialized, because the base memory offset
++ *       is changed after paging_init() is called.
++ */
++static int __init
++dump_init(void)
++{
++      struct sysinfo info;
++
++      /* try to create our dump device */
++      if (register_chrdev(CRASH_DUMP_MAJOR, "dump", &dump_fops)) {
++              printk("cannot register dump character device!\n");
++              return -EBUSY;
++      }
++
++      __dump_init((u64)PAGE_OFFSET);
++
++      /* set the dump_compression_list structure up */
++      dump_register_compression(&dump_none_compression);
++
++      /* grab the total memory size now (not if/when we crash) */
++      si_meminfo(&info);
++
++      /* set the memory size */
++      dump_header.dh_memory_size = (u64)info.totalram;
++
++      sysctl_header = register_sysctl_table(kernel_root, 0);
++      dump_sysrq_register();
++
++      notifier_chain_register(&panic_notifier_list, &panic_block);
++      dump_function_ptr = dump_execute;
++
++      pr_info("Crash dump driver initialized.\n");
++      return 0;
++}
++
++static void __exit
++dump_cleanup(void)
++{
++      dump_okay = 0;
++
++      if (dump_config.dumper)
++              dump_unconfigure();
++
++      /* arch-specific cleanup routine */
++      __dump_cleanup();
++
++      /* ignore errors while unregistering -- since can't do anything */
++      unregister_sysctl_table(sysctl_header);
++      unregister_chrdev(CRASH_DUMP_MAJOR, "dump");
++      dump_sysrq_unregister();
++      notifier_chain_unregister(&panic_notifier_list, &panic_block);
++      dump_function_ptr = NULL;
++}
++
++EXPORT_SYMBOL(dump_register_compression);
++EXPORT_SYMBOL(dump_unregister_compression);
++EXPORT_SYMBOL(dump_register_device);
++EXPORT_SYMBOL(dump_unregister_device);
++EXPORT_SYMBOL(dump_config);
++EXPORT_SYMBOL(dump_silence_level);
++
++EXPORT_SYMBOL(__dump_irq_enable);
++EXPORT_SYMBOL(__dump_irq_restore);
++
++MODULE_AUTHOR("Matt D. Robinson <yakker@sourceforge.net>");
++MODULE_DESCRIPTION("Linux Kernel Crash Dump (LKCD) driver");
++MODULE_LICENSE("GPL");
++
++module_init(dump_init);
++module_exit(dump_cleanup);
+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 
++ * (Enables variation of dump target types e.g disk, network, memory)
++ *
++ * These interfaces have evolved based on discussions on lkcd-devel. 
++ * Eventually the intent is to support primary and secondary or 
++ * alternate targets registered at the same time, with scope for 
++ * situation based failover or multiple dump devices used for parallel 
++ * dump i/o.
++ *
++ * Started: Oct 2002 - Suparna Bhattacharya (suparna@in.ibm.com)
++ *
++ * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++#ifndef _LINUX_DUMPDEV_H
++#define _LINUX_DUMPDEV_H
++
++#include <linux/kernel.h>
++#include <linux/wait.h>
++#include <linux/bio.h>
++
++/* Determined by the dump target (device) type */
++
++struct dump_dev;
++
++struct dump_dev_ops {
++      int (*open)(struct dump_dev *, unsigned long); /* configure */
++      int (*release)(struct dump_dev *); /* unconfigure */
++      int (*silence)(struct dump_dev *); /* when dump starts */
++      int (*resume)(struct dump_dev *); /* when dump is over */
++      int (*seek)(struct dump_dev *, loff_t);
++      /* trigger a write (async in nature typically) */
++      int (*write)(struct dump_dev *, void *, unsigned long);
++      /* not usually used during dump, but option available */
++      int (*read)(struct dump_dev *, void *, unsigned long);
++      /* use to poll for completion */
++      int (*ready)(struct dump_dev *, void *); 
++      int (*ioctl)(struct dump_dev *, unsigned int, unsigned long);
++};
++
++struct dump_dev {
++      char type_name[32]; /* block, net-poll etc */
++      unsigned long device_id; /* interpreted differently for various types */
++      struct dump_dev_ops *ops;
++      struct list_head list;
++      loff_t curr_offset;
++};
++
++/*
++ * dump_dev type variations: 
++ */
++
++/* block */
++struct dump_blockdev {
++      struct dump_dev ddev;
++      dev_t kdev_id;
++      struct block_device *bdev;
++      struct bio *bio;
++      loff_t start_offset;
++      loff_t limit;
++      int err;
++};
++
++static inline struct dump_blockdev *DUMP_BDEV(struct dump_dev *dev)
++{
++      return container_of(dev, struct dump_blockdev, ddev);
++}
++
++
++/* mem  - for internal use by soft-boot based dumper */
++struct dump_memdev {
++      struct dump_dev ddev;
++      unsigned long indirect_map_root;
++      unsigned long nr_free;
++      struct page *curr_page;
++      unsigned long *curr_map;
++      unsigned long curr_map_offset;
++      unsigned long last_offset;
++      unsigned long last_used_offset;
++      unsigned long last_bs_offset;
++};    
++
++static inline struct dump_memdev *DUMP_MDEV(struct dump_dev *dev)
++{
++      return container_of(dev, struct dump_memdev, ddev);
++}
++
++/* Todo/future - meant for raw dedicated interfaces e.g. mini-ide driver */
++struct dump_rdev {
++      struct dump_dev ddev;
++      char name[32];
++      int (*reset)(struct dump_rdev *, unsigned int, 
++              unsigned long);
++      /* ... to do ... */
++};
++
++/* just to get the size right when saving config across a soft-reboot */
++struct dump_anydev {
++      union {
++              struct dump_blockdev bddev;
++              /* .. add other types here .. */
++      };
++};
++
++
++
++/* Dump device / target operation wrappers */
++/* These assume that dump_dev is initiatized to dump_config.dumper->dev */
++
++extern struct dump_dev *dump_dev;
++
++static inline int dump_dev_open(unsigned long arg)
++{
++      return dump_dev->ops->open(dump_dev, arg);
++}
++
++static inline int dump_dev_release(void)
++{
++      return dump_dev->ops->release(dump_dev);
++}
++
++static inline int dump_dev_silence(void)
++{
++      return dump_dev->ops->silence(dump_dev);
++}
++
++static inline int dump_dev_resume(void)
++{
++      return dump_dev->ops->resume(dump_dev);
++}
++
++static inline int dump_dev_seek(loff_t offset)
++{
++      return dump_dev->ops->seek(dump_dev, offset);
++}
++
++static inline int dump_dev_write(void *buf, unsigned long len)
++{
++      return dump_dev->ops->write(dump_dev, buf, len);
++}
++
++static inline int dump_dev_ready(void *buf)
++{
++      return dump_dev->ops->ready(dump_dev, buf);
++}
++
++static inline int dump_dev_ioctl(unsigned int cmd, unsigned long arg)
++{
++      if (!dump_dev->ops->ioctl)
++              return -EINVAL;
++      return dump_dev->ops->ioctl(dump_dev, cmd, arg);
++}
++
++extern int dump_register_device(struct dump_dev *);
++extern void dump_unregister_device(struct dump_dev *);
++
++#endif /*  _LINUX_DUMPDEV_H */
+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.
++ *
++ * Created by: Matt Robinson (yakker@sgi.com)
++ * Copyright 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
++ *
++ * vmdump.h to dump.h by: Matt D. Robinson (yakker@sourceforge.net)
++ * Copyright 2001 - 2002 Matt D. Robinson.  All rights reserved.
++ * Copyright (C) 2002 Free Software Foundation, Inc. All rights reserved.
++ *
++ * Most of this is the same old stuff from vmdump.h, except now we're
++ * actually a stand-alone driver plugged into the block layer interface,
++ * with the exception that we now allow for compression modes externally
++ * loaded (e.g., someone can come up with their own).
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/* This header file includes all structure definitions for crash dumps. */
++#ifndef _DUMP_H
++#define _DUMP_H
++
++#if defined(CONFIG_CRASH_DUMP) || defined (CONFIG_CRASH_DUMP_MODULE)
++
++#include <linux/list.h>
++#include <linux/notifier.h>
++#include <linux/dumpdev.h>
++
++/* 
++ * Predefine default DUMP_PAGE constants, asm header may override.
++ *
++ * On ia64 discontinuous memory systems it's possible for the memory
++ * banks to stop at 2**12 page alignments, the smallest possible page
++ * size. But the system page size, PAGE_SIZE, is in fact larger.
++ */
++#define DUMP_PAGE_SHIFT       PAGE_SHIFT
++#define DUMP_PAGE_MASK                PAGE_MASK
++#define DUMP_PAGE_ALIGN(addr) PAGE_ALIGN(addr)
++#define DUMP_HEADER_OFFSET    PAGE_SIZE
++
++/* keep DUMP_PAGE_SIZE constant to 4K = 1<<12
++ * it may be different from PAGE_SIZE then.
++ */
++#define DUMP_PAGE_SIZE                4096
++
++/* 
++ * Predefined default memcpy() to use when copying memory to the dump buffer.
++ *
++ * On ia64 there is a heads up function that can be called to let the prom
++ * machine check monitor know that the current activity is risky and it should
++ * ignore the fault (nofault). In this case the ia64 header will redefine this
++ * macro to __dump_memcpy() and use it's arch specific version.
++ */
++#define DUMP_memcpy           memcpy
++
++/* necessary header files */
++#include <asm/dump.h>                 /* for architecture-specific header */
++
++/* 
++ * Size of the buffer that's used to hold:
++ *
++ *    1. the dump header (padded to fill the complete buffer)
++ *    2. the possibly compressed page headers and data
++ */
++#define DUMP_BUFFER_SIZE      (64 * 1024)  /* size of dump buffer         */
++#define DUMP_HEADER_SIZE      DUMP_BUFFER_SIZE
++
++/* standard header definitions */
++#define DUMP_MAGIC_NUMBER     0xa8190173618f23edULL  /* dump magic number */
++#define DUMP_MAGIC_LIVE               0xa8190173618f23cdULL  /* live magic number */
++#define DUMP_VERSION_NUMBER   0x8     /* dump version number              */
++#define DUMP_PANIC_LEN                0x100   /* dump panic string length         */
++
++/* dump levels - type specific stuff added later -- add as necessary */
++#define DUMP_LEVEL_NONE               0x0     /* no dumping at all -- just bail   */
++#define DUMP_LEVEL_HEADER     0x1     /* kernel dump header only          */
++#define DUMP_LEVEL_KERN               0x2     /* dump header and kernel pages     */
++#define DUMP_LEVEL_USED               0x4     /* dump header, kernel/user pages   */
++#define DUMP_LEVEL_ALL_RAM    0x8     /* dump header, all RAM pages       */
++#define DUMP_LEVEL_ALL                0x10    /* dump all memory RAM and firmware */
++
++
++/* dump compression options -- add as necessary */
++#define DUMP_COMPRESS_NONE    0x0     /* don't compress this dump         */
++#define DUMP_COMPRESS_RLE     0x1     /* use RLE compression              */
++#define DUMP_COMPRESS_GZIP    0x2     /* use GZIP compression             */
++
++/* dump flags - any dump-type specific flags -- add as necessary */
++#define DUMP_FLAGS_NONE               0x0     /* no flags are set for this dump   */
++#define DUMP_FLAGS_SOFTBOOT   0x2     /* 2 stage soft-boot based dump     */
++
++#define DUMP_FLAGS_TARGETMASK 0xf0000000 /* handle special case targets   */
++#define DUMP_FLAGS_DISKDUMP   0x80000000 /* dump to local disk            */
++#define DUMP_FLAGS_NETDUMP    0x40000000 /* dump over the network         */
++
++/* dump header flags -- add as necessary */
++#define DUMP_DH_FLAGS_NONE    0x0     /* no flags set (error condition!)  */
++#define DUMP_DH_RAW           0x1     /* raw page (no compression)        */
++#define DUMP_DH_COMPRESSED    0x2     /* page is compressed               */
++#define DUMP_DH_END           0x4     /* end marker on a full dump        */
++#define DUMP_DH_TRUNCATED     0x8     /* dump is incomplete               */
++#define DUMP_DH_TEST_PATTERN  0x10    /* dump page is a test pattern      */
++#define DUMP_DH_NOT_USED      0x20    /* 1st bit not used in flags        */
++
++/* names for various dump parameters in /proc/kernel */
++#define DUMP_ROOT_NAME                "sys/dump"
++#define DUMP_DEVICE_NAME      "device"
++#define DUMP_COMPRESS_NAME    "compress"
++#define DUMP_LEVEL_NAME               "level"
++#define DUMP_FLAGS_NAME               "flags"
++#define DUMP_ADDR_NAME                "addr"
++
++#define DUMP_SYSRQ_KEY                'd'     /* key to use for MAGIC_SYSRQ key   */
++
++/* CTL_DUMP names: */
++enum
++{
++      CTL_DUMP_DEVICE=1,
++      CTL_DUMP_COMPRESS=3,
++      CTL_DUMP_LEVEL=3,
++      CTL_DUMP_FLAGS=4,
++      CTL_DUMP_ADDR=5,
++      CTL_DUMP_TEST=6,
++};
++
++
++/* page size for gzip compression -- buffered slightly beyond hardware PAGE_SIZE used by DUMP */
++#define DUMP_DPC_PAGE_SIZE    (DUMP_PAGE_SIZE + 512)
++
++/* dump ioctl() control options */
++#define DIOSDUMPDEV           1       /* set the dump device              */
++#define DIOGDUMPDEV           2       /* get the dump device              */
++#define DIOSDUMPLEVEL         3       /* set the dump level               */
++#define DIOGDUMPLEVEL         4       /* get the dump level               */
++#define DIOSDUMPFLAGS         5       /* set the dump flag parameters     */
++#define DIOGDUMPFLAGS         6       /* get the dump flag parameters     */
++#define DIOSDUMPCOMPRESS      7       /* set the dump compress level      */
++#define DIOGDUMPCOMPRESS      8       /* get the dump compress level      */
++
++/* these ioctls are used only by netdump module */
++#define DIOSTARGETIP          9       /* set the target m/c's ip          */
++#define DIOGTARGETIP          10      /* get the target m/c's ip          */
++#define DIOSTARGETPORT                11      /* set the target m/c's port        */
++#define DIOGTARGETPORT                12      /* get the target m/c's port        */
++#define DIOSSOURCEPORT                13      /* set the source m/c's port        */
++#define DIOGSOURCEPORT                14      /* get the source m/c's port        */
++#define DIOSETHADDR           15      /* set ethernet address             */
++#define DIOGETHADDR           16      /* get ethernet address             */
++
++/*
++ * Structure: __dump_header
++ *  Function: This is the header dumped at the top of every valid crash
++ *            dump.  
++ */
++struct __dump_header {
++      /* the dump magic number -- unique to verify dump is valid */
++      u64     dh_magic_number;
++
++      /* the version number of this dump */
++      u32     dh_version;
++
++      /* the size of this header (in case we can't read it) */
++      u32     dh_header_size;
++
++      /* the level of this dump (just a header?) */
++      u32     dh_dump_level;
++
++      /* 
++       * We assume dump_page_size to be 4K in every case.
++       * Store here the configurable system page size (4K, 8K, 16K, etc.) 
++       */
++      u32     dh_page_size;
++
++      /* the size of all physical memory */
++      u64     dh_memory_size;
++
++      /* the start of physical memory */
++      u64     dh_memory_start;
++
++      /* the end of physical memory */
++      u64     dh_memory_end;
++
++      /* the number of hardware/physical pages in this dump specifically */
++      u32     dh_num_dump_pages;
++
++      /* the panic string, if available */
++      char    dh_panic_string[DUMP_PANIC_LEN];
++
++      /* timeval depends on architecture, two long values */
++      struct {
++              u64 tv_sec;
++              u64 tv_usec;
++      } dh_time; /* the time of the system crash */
++
++      /* the NEW utsname (uname) information -- in character form */
++      /* we do this so we don't have to include utsname.h         */
++      /* plus it helps us be more architecture independent        */
++      /* now maybe one day soon they'll make the [65] a #define!  */
++      char    dh_utsname_sysname[65];
++      char    dh_utsname_nodename[65];
++      char    dh_utsname_release[65];
++      char    dh_utsname_version[65];
++      char    dh_utsname_machine[65];
++      char    dh_utsname_domainname[65];
++
++      /* the address of current task (OLD = void *, NEW = u64) */
++      u64     dh_current_task;
++
++      /* what type of compression we're using in this dump (if any) */
++      u32     dh_dump_compress;
++
++      /* any additional flags */
++      u32     dh_dump_flags;
++
++      /* any additional flags */
++      u32     dh_dump_device;
++} __attribute__((packed));
++
++/*
++ * Structure: __dump_page
++ *  Function: To act as the header associated to each physical page of
++ *            memory saved in the system crash dump.  This allows for
++ *            easy reassembly of each crash dump page.  The address bits
++ *            are split to make things easier for 64-bit/32-bit system
++ *            conversions.
++ *
++ * dp_byte_offset and dp_page_index are landmarks that are helpful when
++ * looking at a hex dump of /dev/vmdump,
++ */
++struct __dump_page {
++      /* the address of this dump page */
++      u64     dp_address;
++
++      /* the size of this dump page */
++      u32     dp_size;
++
++      /* flags (currently DUMP_COMPRESSED, DUMP_RAW or DUMP_END) */
++      u32     dp_flags;
++} __attribute__((packed));
++
++/*
++ * Structure: __lkcdinfo
++ * Function:  This structure contains information needed for the lkcdutils
++ *            package (particularly lcrash) to determine what information is
++ *            associated to this kernel, specifically.
++ */
++struct __lkcdinfo {
++      int     arch;
++      int     ptrsz;
++      int     byte_order;
++      int     linux_release;
++      int     page_shift;
++      int     page_size;
++      u64     page_mask;
++      u64     page_offset;
++      int     stack_offset;
++};
++
++#ifdef __KERNEL__
++
++/*
++ * Structure: __dump_compress
++ *  Function: This is what an individual compression mechanism can use
++ *            to plug in their own compression techniques.  It's always
++ *            best to build these as individual modules so that people
++ *            can put in whatever they want.
++ */
++struct __dump_compress {
++      /* the list_head structure for list storage */
++      struct list_head list;
++
++      /* the type of compression to use (DUMP_COMPRESS_XXX) */
++      int compress_type;
++      const char *compress_name;
++
++      /* the compression function to call */
++      u16 (*compress_func)(const u8 *, u16, u8 *, u16);
++};
++
++/* functions for dump compression registration */
++extern void dump_register_compression(struct __dump_compress *);
++extern void dump_unregister_compression(int);
++
++/*
++ * Structure dump_mbank[]:
++ *
++ * For CONFIG_DISCONTIGMEM systems this array specifies the
++ * memory banks/chunks that need to be dumped after a panic.
++ *
++ * For classic systems it specifies a single set of pages from
++ * 0 to max_mapnr.
++ */
++struct __dump_mbank {
++      u64     start;
++      u64     end;
++      int     type;
++      int     pad1;
++      long    pad2;
++};
++
++#define DUMP_MBANK_TYPE_CONVENTIONAL_MEMORY           1
++#define DUMP_MBANK_TYPE_OTHER                         2
++
++#define MAXCHUNKS 256
++extern int dump_mbanks;
++extern struct __dump_mbank dump_mbank[MAXCHUNKS];
++
++/* notification event codes */
++#define DUMP_BEGIN            0x0001  /* dump beginning */
++#define DUMP_END              0x0002  /* dump ending */
++
++/* Scheduler soft spin control.
++ *
++ * 0 - no dump in progress
++ * 1 - cpu0 is dumping, ...
++ */
++extern unsigned long dump_oncpu;
++extern void dump_execute(const char *, const struct pt_regs *);
++
++/*
++ *    Notifier list for kernel code which wants to be called
++ *    at kernel dump. 
++ */
++extern struct notifier_block *dump_notifier_list;
++static inline int register_dump_notifier(struct notifier_block *nb)
++{
++      return notifier_chain_register(&dump_notifier_list, nb);
++}
++static inline int unregister_dump_notifier(struct notifier_block * nb)
++{
++      return notifier_chain_unregister(&dump_notifier_list, nb);
++}
++
++extern void (*dump_function_ptr)(const char *, const struct pt_regs *);
++static inline void dump(char * str, struct pt_regs * regs)
++{
++      if (dump_function_ptr)
++              dump_function_ptr(str, regs);
++}
++
++/*
++ * Common Arch Specific Functions should be declared here.
++ * This allows the C compiler to detect discrepancies.
++ */
++extern void   __dump_open(void);
++extern void   __dump_cleanup(void);
++extern void   __dump_init(u64);
++extern void   __dump_save_regs(struct pt_regs *, const struct pt_regs *);
++extern int    __dump_configure_header(const struct pt_regs *);
++extern void   __dump_irq_enable(void);
++extern void   __dump_irq_restore(void);
++extern int    __dump_page_valid(unsigned long index);
++#ifdef CONFIG_SMP
++extern void   __dump_save_other_cpus(void);
++#else
++#define       __dump_save_other_cpus()
++#endif
++
++/* to track all used (compound + zero order) pages */
++#define PageInuse(p)   (PageCompound(p) || page_count(p))
++
++#endif /* __KERNEL__ */
++
++#else /* !CONFIG_CRASH_DUMP */
++
++/* If not configured then make code disappear! */
++#define register_dump_watchdog(x)     do { } while(0)
++#define unregister_dump_watchdog(x)   do { } while(0)
++#define register_dump_notifier(x)     do { } while(0)
++#define unregister_dump_notifier(x)   do { } while(0)
++#define dump_in_progress()            0
++#define dump(x, y)                    do { } while(0)
++
++#endif        /* !CONFIG_CRASH_DUMP */
++
++#endif /* _DUMP_H */
+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
++ *
++ *  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.
++ */
++
++/****************************************************************
++ *      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.
++ *
++ ****************************************************************/
++
++#define NETCONSOLE_VERSION 0x03
++
++enum netdump_commands {
++      COMM_NONE = 0,
++      COMM_SEND_MEM = 1,
++      COMM_EXIT = 2,
++      COMM_REBOOT = 3,
++      COMM_HELLO = 4,
++      COMM_GET_NR_PAGES = 5,
++      COMM_GET_PAGE_SIZE = 6,
++      COMM_START_NETDUMP_ACK = 7,
++      COMM_GET_REGS = 8,
++      COMM_GET_MAGIC = 9,
++      COMM_START_WRITE_NETDUMP_ACK = 10,
++      COMM_SYSRQ = 11,
++};
++
++typedef struct netdump_req_s {
++      u64 magic;
++      u32 nr;
++      u32 command;
++      u32 from;
++      u32 to;
++} req_t;
++
++enum netdump_replies {
++      REPLY_NONE = 0,
++      REPLY_ERROR = 1,
++      REPLY_LOG = 2,
++      REPLY_MEM = 3,
++      REPLY_RESERVED = 4,
++      REPLY_HELLO = 5,
++      REPLY_NR_PAGES = 6,
++      REPLY_PAGE_SIZE = 7,
++      REPLY_START_NETDUMP = 8,
++      REPLY_END_NETDUMP = 9,
++      REPLY_REGS = 10,
++      REPLY_MAGIC = 11,
++      REPLY_START_WRITE_NETDUMP = 12,
++      REPLY_SYSRQ = 13,
++};
++
++typedef struct netdump_reply_s {
++      u32 nr;
++      u32 code;
++      u32 info;
++} reply_t;
++
++#define HEADER_LEN (1 + sizeof(reply_t))
++
++
+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.
++ *
++ * Created by: Matt Robinson (yakker@sgi.com)
++ *
++ * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++/* This header file holds the architecture specific crash dump header */
++#ifndef _ASM_DUMP_H
++#define _ASM_DUMP_H
++
++/* necessary header files */
++#include <asm/ptrace.h>
++#include <asm/page.h>
++#include <linux/threads.h>
++#include <linux/mm.h>
++
++/* definitions */
++#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL   /* magic number            */
++#define DUMP_ASM_VERSION_NUMBER       0x3     /* version number          */
++
++/* max number of cpus */
++#define DUMP_MAX_NUM_CPUS 32
++
++/*
++ * Structure: __dump_header_asm
++ *  Function: This is the header for architecture-specific stuff.  It
++ *            follows right after the dump header.
++ */
++struct __dump_header_asm {
++      /* the dump magic number -- unique to verify dump is valid */
++      u64             dha_magic_number;
++
++      /* the version number of this dump */
++      u32             dha_version;
++
++      /* the size of this header (in case we can't read it) */
++      u32             dha_header_size;
++
++      /* the esp for i386 systems */
++      u32             dha_esp;
++
++      /* the eip for i386 systems */
++      u32             dha_eip;
++
++      /* the dump registers */
++      struct pt_regs  dha_regs;
++
++      /* smp specific */
++      u32             dha_smp_num_cpus;
++      u32             dha_dumping_cpu;
++      struct pt_regs  dha_smp_regs[DUMP_MAX_NUM_CPUS];
++      u32             dha_smp_current_task[DUMP_MAX_NUM_CPUS];
++      u32             dha_stack[DUMP_MAX_NUM_CPUS];
++      u32             dha_stack_ptr[DUMP_MAX_NUM_CPUS];
++} __attribute__((packed));
++
++#ifdef __KERNEL__
++
++extern struct __dump_header_asm dump_header_asm;
++
++#ifdef CONFIG_SMP
++extern cpumask_t irq_affinity[];
++extern int (*dump_ipi_function_ptr)(struct pt_regs *);
++extern void dump_send_ipi(void);
++#else
++#define dump_send_ipi() do { } while(0)
++#endif
++
++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();
++}
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_DUMP_H */
+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
++ *
++ * Copyright (C) 2000 Tom Morano (tjm@sgi.com) and
++ *                    Matt D. Robinson (yakker@alacritech.com)
++ *
++ * Dummy module that includes headers for all kernel types of interest. 
++ * The kernel type information is used by the lcrash utility when 
++ * analyzing system crash dumps or the live system. Using the type 
++ * information for the running system, rather than kernel header files,
++ * makes for a more flexible and robust analysis tool.
++ *
++ * This source code is released under version 2 of the GNU GPL.
++ */
++
++#include <linux/compile.h>
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <linux/config.h>
++#include <linux/utsname.h>
++#include <linux/dump.h>
++
++#ifdef LINUX_COMPILE_VERSION_ID_TYPE
++/* Define version type for version validation of dump and kerntypes */
++LINUX_COMPILE_VERSION_ID_TYPE;
++#endif
++
++void
++kerntypes_dummy(void)
++{
++}
+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 
++ *
++ * Started: Oct 2002 -  Suparna Bhattacharya (suparna@in.ibm.com)
++ *
++ * Copyright (C) 2002 International Business Machines Corp. 
++ *
++ * This code is released under version 2 of the GNU GPL.
++ */
++
++#ifndef _LINUX_DUMP_METHODS_H
++#define _LINUX_DUMP_METHODS_H
++
++/*
++ * Inspired by Matt Robinson's suggestion of introducing dump 
++ * methods as a way to enable different crash dump facilities to 
++ * coexist where each employs its own scheme or dumping policy.
++ *
++ * The code here creates a framework for flexible dump by defining 
++ * a set of methods and providing associated helpers that differentiate
++ * between the underlying mechanism (how to dump), overall scheme 
++ * (sequencing of stages and data dumped and associated quiescing), 
++ * output format (what the dump output looks like), target type 
++ * (where to save the dump; see dumpdev.h), and selection policy 
++ * (state/data to dump).
++ * 
++ * These sets of interfaces can be mixed and matched to build a 
++ * dumper suitable for a given situation, allowing for 
++ * flexibility as well appropriate degree of code reuse.
++ * For example all features and options of lkcd (including
++ * granular selective dumping in the near future) should be
++ * available even when say, the 2 stage soft-boot based mechanism 
++ * is used for taking disruptive dumps.
++ *
++ * Todo: Additionally modules or drivers may supply their own
++ * custom dumpers which extend dump with module specific
++ * information or hardware state, and can even tweak the
++ * mechanism when it comes to saving state relevant to
++ * them.
++ */
++
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/highmem.h>
++#include <linux/dumpdev.h>
++
++#define MAX_PASSES    6
++#define MAX_DEVS      4
++
++
++/* To customise selection of pages to be dumped in a given pass/group */
++struct dump_data_filter{
++      char name[32];
++      int (*selector)(int, unsigned long, unsigned long);
++      ulong level_mask; /* dump level(s) for which this filter applies */
++      loff_t start, end; /* location range applicable */
++};
++
++
++/* 
++ * Determined by the kind of dump mechanism and appropriate 
++ * overall scheme 
++ */ 
++struct dump_scheme_ops {
++      /* sets aside memory, inits data structures etc */
++      int (*configure)(unsigned long devid); 
++      /* releases  resources */
++      int (*unconfigure)(void); 
++
++      /* ordering of passes, invoking iterator */
++      int (*sequencer)(void); 
++        /* iterates over system data, selects and acts on data to dump */
++      int (*iterator)(int, int (*)(unsigned long, unsigned long), 
++              struct dump_data_filter *); 
++        /* action when data is selected for dump */
++      int (*save_data)(unsigned long, unsigned long); 
++        /* action when data is to be excluded from dump */
++      int (*skip_data)(unsigned long, unsigned long); 
++      /* policies for space, multiple dump devices etc */
++      int (*write_buffer)(void *, unsigned long); 
++};
++
++struct dump_scheme {
++      /* the name serves as an anchor to locate the scheme after reboot */
++      char name[32]; 
++      struct dump_scheme_ops *ops;
++      struct list_head list;
++};
++
++/* Quiescing/Silence levels (controls IPI callback behaviour) */
++extern enum dump_silence_levels {
++      DUMP_SOFT_SPIN_CPUS     = 1,
++      DUMP_HARD_SPIN_CPUS     = 2,
++      DUMP_HALT_CPUS          = 3,
++} dump_silence_level;
++
++/* determined by the dump (file) format */
++struct dump_fmt_ops {
++      /* build header */
++      int (*configure_header)(const char *, const struct pt_regs *); 
++      int (*update_header)(void); /* update header and write it out */
++      /* save curr context  */
++      void (*save_context)(int, const struct pt_regs *, 
++              struct task_struct *); 
++      /* typically called by the save_data action */
++      /* add formatted data to the dump buffer */
++      int (*add_data)(unsigned long, unsigned long); 
++      int (*update_end_marker)(void);
++};
++
++struct dump_fmt {
++      unsigned long magic; 
++      char name[32];  /* lcrash, crash, elf-core etc */
++      struct dump_fmt_ops *ops;
++      struct list_head list;
++};
++
++/* 
++ * Modules will be able add their own data capture schemes by 
++ * registering their own dumpers. Typically they would use the 
++ * primary dumper as a template and tune it with their routines.
++ * Still Todo.
++ */
++
++/* The combined dumper profile (mechanism, scheme, dev, fmt) */
++struct dumper {
++      char name[32]; /* singlestage, overlay (stg1), passthru(stg2), pull */
++      struct dump_scheme *scheme;
++      struct dump_fmt *fmt;
++      struct __dump_compress *compress;
++      struct dump_data_filter *filter;
++      struct dump_dev *dev; 
++      /* state valid only for active dumper(s) - per instance */
++      /* run time state/context */
++      int curr_pass;
++      unsigned long count;
++      loff_t curr_offset; /* current logical offset into dump device */
++      loff_t curr_loc; /* current memory location */
++      void *curr_buf; /* current position in the dump buffer */
++      void *dump_buf; /* starting addr of dump buffer */
++      int header_dirty; /* whether the header needs to be written out */
++      int header_len; 
++      struct list_head dumper_list; /* links to other dumpers */
++};    
++
++/* Starting point to get to the current configured state */
++struct dump_config {
++      ulong level;
++      ulong flags;
++      struct dumper *dumper;
++      unsigned long dump_device;
++      unsigned long dump_addr; /* relevant only for in-memory dumps */
++      struct list_head dump_dev_list;
++};    
++
++extern struct dump_config dump_config;
++
++/* Used to save the dump config across a reboot for 2-stage dumps: 
++ * 
++ * Note: The scheme, format, compression and device type should be 
++ * registered at bootup, for this config to be sharable across soft-boot. 
++ * The function addresses could have changed and become invalid, and
++ * need to be set up again.
++ */
++struct dump_config_block {
++      u64 magic; /* for a quick sanity check after reboot */
++      struct dump_memdev memdev; /* handle to dump stored in memory */
++      struct dump_config config;
++      struct dumper dumper;
++      struct dump_scheme scheme;
++      struct dump_fmt fmt;
++      struct __dump_compress compress;
++      struct dump_data_filter filter_table[MAX_PASSES];
++      struct dump_anydev dev[MAX_DEVS]; /* target dump device */
++};
++
++
++/* Wrappers that invoke the methods for the current (active) dumper */
++
++/* Scheme operations */
++
++static inline int dump_sequencer(void)
++{
++      return dump_config.dumper->scheme->ops->sequencer();
++}
++
++static inline int dump_iterator(int pass, int (*action)(unsigned long, 
++      unsigned long), struct dump_data_filter *filter)
++{
++      return dump_config.dumper->scheme->ops->iterator(pass, action, filter);
++}
++
++#define dump_save_data dump_config.dumper->scheme->ops->save_data
++#define dump_skip_data dump_config.dumper->scheme->ops->skip_data
++
++static inline int dump_write_buffer(void *buf, unsigned long len)
++{
++      return dump_config.dumper->scheme->ops->write_buffer(buf, len);
++}
++
++static inline int dump_configure(unsigned long devid)
++{
++      return dump_config.dumper->scheme->ops->configure(devid);
++}
++
++static inline int dump_unconfigure(void)
++{
++      return dump_config.dumper->scheme->ops->unconfigure();
++}
++
++/* Format operations */
++
++static inline int dump_configure_header(const char *panic_str, 
++      const struct pt_regs *regs)
++{
++      return dump_config.dumper->fmt->ops->configure_header(panic_str, regs);
++}
++
++static inline void dump_save_context(int cpu, const struct pt_regs *regs, 
++              struct task_struct *tsk)
++{
++      dump_config.dumper->fmt->ops->save_context(cpu, regs, tsk);
++}
++
++static inline int dump_save_this_cpu(const struct pt_regs *regs)
++{
++      int cpu = smp_processor_id();
++
++      dump_save_context(cpu, regs, current);
++      return 1;
++}
++
++static inline int dump_update_header(void)
++{
++      return dump_config.dumper->fmt->ops->update_header();
++}
++
++static inline int dump_update_end_marker(void)
++{
++      return dump_config.dumper->fmt->ops->update_end_marker();
++}
++
++static inline int dump_add_data(unsigned long loc, unsigned long sz)
++{
++      return dump_config.dumper->fmt->ops->add_data(loc, sz);
++}
++
++/* Compression operation */
++static inline int dump_compress_data(char *src, int slen, char *dst)
++{
++      return dump_config.dumper->compress->compress_func(src, slen, 
++              dst, DUMP_DPC_PAGE_SIZE);
++}
++
++
++/* Prototypes of some default implementations of dump methods */
++
++extern struct __dump_compress dump_none_compression;
++
++/* Default scheme methods (dump_scheme.c) */
++
++extern int dump_generic_sequencer(void);
++extern int dump_page_iterator(int pass, int (*action)(unsigned long, unsigned
++      long), struct dump_data_filter *filter);
++extern int dump_generic_save_data(unsigned long loc, unsigned long sz);
++extern int dump_generic_skip_data(unsigned long loc, unsigned long sz);
++extern int dump_generic_write_buffer(void *buf, unsigned long len);
++extern int dump_generic_configure(unsigned long);
++extern int dump_generic_unconfigure(void);
++
++/* Default scheme template */
++extern struct dump_scheme dump_scheme_singlestage;
++
++/* Default dump format methods */
++
++extern int dump_lcrash_configure_header(const char *panic_str, 
++      const struct pt_regs *regs);
++extern void dump_lcrash_save_context(int  cpu, const struct pt_regs *regs, 
++      struct task_struct *tsk);
++extern int dump_generic_update_header(void);
++extern int dump_lcrash_add_data(unsigned long loc, unsigned long sz);
++extern int dump_lcrash_update_end_marker(void);
++
++/* Default format (lcrash) template */
++extern struct dump_fmt dump_fmt_lcrash;
++
++/* Default dump selection filter table */
++
++/* 
++ * Entries listed in order of importance and correspond to passes
++ * The last entry (with a level_mask of zero) typically reflects data that 
++ * won't be dumped  -- this may for example be used to identify data 
++ * that will be skipped for certain so the corresponding memory areas can be 
++ * utilized as scratch space.
++ */   
++extern struct dump_data_filter dump_filter_table[];
++
++/* Some pre-defined dumpers */
++extern struct dumper dumper_singlestage;
++extern struct dumper dumper_stage1;
++extern struct dumper dumper_stage2;
++
++/* These are temporary */
++#define DUMP_MASK_HEADER      DUMP_LEVEL_HEADER
++#define DUMP_MASK_KERN                DUMP_LEVEL_KERN
++#define DUMP_MASK_USED                DUMP_LEVEL_USED
++#define DUMP_MASK_UNUSED      DUMP_LEVEL_ALL_RAM
++#define DUMP_MASK_REST                0 /* dummy for now */
++
++/* Helpers - move these to dump.h later ? */
++
++int dump_generic_execute(const char *panic_str, const struct pt_regs *regs);
++extern int dump_ll_write(void *buf, unsigned long len); 
++int dump_check_and_free_page(struct dump_memdev *dev, struct page *page);
++
++static inline void dumper_reset(void)
++{
++      dump_config.dumper->curr_buf = dump_config.dumper->dump_buf;
++      dump_config.dumper->curr_loc = 0;
++      dump_config.dumper->curr_offset = 0;
++      dump_config.dumper->count = 0;
++      dump_config.dumper->curr_pass = 0;
++}
++
++/* 
++ * May later be moulded to perform boot-time allocations so we can dump 
++ * earlier during bootup 
++ */
++static inline void *dump_alloc_mem(unsigned long size)
++{
++      return kmalloc(size, GFP_KERNEL);
++}
++
++static inline void dump_free_mem(void *buf)
++{
++      struct page *page;
++
++      /* ignore reserved pages (e.g. post soft boot stage) */
++      if (buf && (page = virt_to_page(buf))) {
++              if (PageReserved(page))
++                      return;
++      }
++
++      kfree(buf);
++}
++
++
++#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-test5.patch b/lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test5.patch
new file mode 100644 (file)
index 0000000..553e30b
--- /dev/null
@@ -0,0 +1,616 @@
+ 0 files changed
+
+Index: linux-2.6.0-test5/drivers/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/Makefile    2003-09-09 03:50:21.000000000 +0800
++++ linux-2.6.0-test5/drivers/Makefile 2003-09-25 21:15:21.000000000 +0800
+@@ -49,3 +49,4 @@
+ obj-$(CONFIG_MCA)             += mca/
+ obj-$(CONFIG_EISA)            += eisa/
+ obj-$(CONFIG_CPU_FREQ)                += cpufreq/
++obj-$(CONFIG_CRASH_DUMP)      += dump/
+Index: linux-2.6.0-test5/include/linux/sysctl.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/sysctl.h      2003-09-09 03:50:06.000000000 +0800
++++ linux-2.6.0-test5/include/linux/sysctl.h   2003-09-25 21:15:22.000000000 +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-test5/include/linux/major.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/major.h       2003-09-25 20:50:36.000000000 +0800
++++ linux-2.6.0-test5/include/linux/major.h    2003-09-25 21:15:22.000000000 +0800
+@@ -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
+Index: linux-2.6.0-test5/include/asm-i386/mach-default/irq_vectors.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/mach-default/irq_vectors.h 2003-09-09 03:49:58.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/mach-default/irq_vectors.h      2003-09-25 21:15:22.000000000 +0800
+@@ -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
+ /*
+Index: linux-2.6.0-test5/include/asm-i386/kmap_types.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/kmap_types.h       2003-09-25 20:50:35.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/kmap_types.h    2003-09-25 21:17:25.000000000 +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,
+ };
+ #endif
+Index: linux-2.6.0-test5/include/asm-i386/smp.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/smp.h      2003-09-09 03:50:07.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/smp.h   2003-09-25 21:15:22.000000000 +0800
+@@ -37,6 +37,7 @@
+ 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 */
+Index: linux-2.6.0-test5/arch/i386/kernel/i386_ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/i386_ksyms.c       2003-09-25 20:50:21.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/i386_ksyms.c    2003-09-25 21:18:16.000000000 +0800
+@@ -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>
+@@ -34,6 +35,7 @@
+ #include <asm/nmi.h>
+ #include <asm/edd.h>
+ #include <asm/ist.h>
++#include <asm/e820.h>
+ extern void dump_thread(struct pt_regs *, struct user *);
+ extern spinlock_t rtc_lock;
+@@ -214,3 +216,20 @@
+ #if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
+ EXPORT_SYMBOL(ist_info);
+ #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
+Index: linux-2.6.0-test5/arch/i386/kernel/nmi.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/nmi.c      2003-09-25 20:50:21.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/nmi.c   2003-09-25 21:15:22.000000000 +0800
+@@ -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>
+@@ -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);
++                      dump("NMI Watchdog detected LOCKUP", regs);
+                       printk("console shuts up ...\n");
+                       console_silent();
+                       spin_unlock(&nmi_print_lock);
+Index: linux-2.6.0-test5/arch/i386/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/setup.c    2003-09-25 20:50:21.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/setup.c 2003-09-25 21:15:23.000000000 +0800
+@@ -450,6 +450,7 @@
+       print_memory_map(who);
+ } /* setup_memory_region */
++unsigned long crashdump_addr = 0xdeadbeef;
+ static void __init parse_cmdline_early (char ** cmdline_p)
+ {
+@@ -567,6 +568,9 @@
+               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;
+@@ -949,6 +953,8 @@
+ __setup("noreplacement", noreplacement_setup); 
++extern void crashdump_reserve(void);
++
+ void __init setup_arch(char **cmdline_p)
+ {
+       unsigned long max_low_pfn;
+Index: linux-2.6.0-test5/arch/i386/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/smp.c      2003-09-25 20:50:21.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/smp.c   2003-09-25 21:15:23.000000000 +0800
+@@ -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 @@
+        */
+       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.
+        */
+@@ -477,6 +485,11 @@
+       send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
+ }
++void dump_send_ipi(void)
++{
++      send_IPI_allbutself(DUMP_VECTOR);
++}
++
+ /*
+  * 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;
+ }
+-static void stop_this_cpu (void * dummy)
++void stop_this_cpu (void * dummy)
+ {
+       /*
+        * Remove this CPU:
+@@ -606,4 +619,3 @@
+               atomic_inc(&call_data->finished);
+       }
+ }
+-
+Index: linux-2.6.0-test5/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/kernel/traps.c    2003-09-25 20:50:21.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/kernel/traps.c 2003-09-25 21:15:23.000000000 +0800
+@@ -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 @@
+ #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())
+Index: linux-2.6.0-test5/arch/i386/mm/init.c
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/mm/init.c 2003-09-25 20:50:21.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/mm/init.c      2003-09-25 21:15:23.000000000 +0800
+@@ -96,6 +96,12 @@
+               SetPageReserved(page);
+ }
++/* 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
+ #ifndef CONFIG_DISCONTIGMEM
+Index: linux-2.6.0-test5/arch/i386/boot/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/boot/Makefile     2003-09-25 20:50:20.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/boot/Makefile  2003-09-25 21:19:54.000000000 +0800
+@@ -100,3 +100,4 @@
+ install: $(BOOTIMAGE)
+       sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
++      if [ -f init/kerntypes.o ]; then cp init/kerntypes.o $(INSTALL_PATH)/Kerntypes; fi
+Index: linux-2.6.0-test5/arch/i386/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/arch/i386/Kconfig   2003-09-25 20:50:20.000000000 +0800
++++ linux-2.6.0-test5/arch/i386/Kconfig        2003-09-25 21:15:23.000000000 +0800
+@@ -1229,6 +1229,56 @@
+ 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
+Index: linux-2.6.0-test5/arch/s390/boot/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/boot/Makefile     2003-09-09 03:50:58.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/boot/Makefile  2003-09-25 21:15:23.000000000 +0800
+@@ -16,4 +16,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)"
+Index: linux-2.6.0-test5/arch/s390/boot/install.sh
+===================================================================
+--- linux-2.6.0-test5.orig/arch/s390/boot/install.sh   2003-09-09 03:50:08.000000000 +0800
++++ linux-2.6.0-test5/arch/s390/boot/install.sh        2003-09-25 21:15:23.000000000 +0800
+@@ -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 @@
+ # 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
+Index: linux-2.6.0-test5/scripts/mkcompile_h
+===================================================================
+--- linux-2.6.0-test5.orig/scripts/mkcompile_h 2003-09-25 20:50:39.000000000 +0800
++++ linux-2.6.0-test5/scripts/mkcompile_h      2003-09-25 21:23:37.000000000 +0800
+@@ -33,7 +33,7 @@
+ 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 @@
+   fi
+   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,
+Index: linux-2.6.0-test5/kernel/ksyms.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/ksyms.c      2003-09-25 20:50:37.000000000 +0800
++++ linux-2.6.0-test5/kernel/ksyms.c   2003-09-25 21:15:23.000000000 +0800
+@@ -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>
+@@ -624,3 +626,9 @@
+ 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
+Index: linux-2.6.0-test5/kernel/panic.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/panic.c      2003-09-09 03:50:32.000000000 +0800
++++ linux-2.6.0-test5/kernel/panic.c   2003-09-25 21:26:46.000000000 +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;
+ int panic_on_oops;
+ int tainted;
++void (*dump_function_ptr)(const char *, const struct pt_regs *) = 0;
+ struct notifier_block *panic_notifier_list;
+@@ -55,6 +60,7 @@
+       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");
+@@ -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);
++                      }
++              }
++#endif
++ 
++
+               for (i = 0; i < panic_timeout; i++) {
+                       touch_nmi_watchdog();
+                       mdelay(1000);
+Index: linux-2.6.0-test5/kernel/sched.c
+===================================================================
+--- linux-2.6.0-test5.orig/kernel/sched.c      2003-09-25 20:50:37.000000000 +0800
++++ linux-2.6.0-test5/kernel/sched.c   2003-09-25 21:15:23.000000000 +0800
+@@ -43,6 +43,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 ],
+@@ -1460,6 +1463,15 @@
+       unsigned long run_time;
+       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.
+@@ -1583,6 +1595,16 @@
+       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
+Index: linux-2.6.0-test5/lib/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/lib/Kconfig 2003-09-09 03:50:07.000000000 +0800
++++ linux-2.6.0-test5/lib/Kconfig      2003-09-25 21:15:23.000000000 +0800
+@@ -17,14 +17,16 @@
+ #
+ 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
+Index: linux-2.6.0-test5/mm/page_alloc.c
+===================================================================
+--- linux-2.6.0-test5.orig/mm/page_alloc.c     2003-09-25 20:50:37.000000000 +0800
++++ linux-2.6.0-test5/mm/page_alloc.c  2003-09-25 21:15:23.000000000 +0800
+@@ -89,7 +89,8 @@
+       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
+Index: linux-2.6.0-test5/init/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/init/Makefile       2003-09-09 03:50:02.000000000 +0800
++++ linux-2.6.0-test5/init/Makefile    2003-09-25 21:15:23.000000000 +0800
+@@ -9,6 +9,9 @@
+ 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 @@
+ include/linux/compile.h: FORCE
+       @echo '  CHK     $@'
+       @sh $(srctree)/scripts/mkcompile_h $@ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
++
+Index: linux-2.6.0-test5/init/main.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/main.c 2003-09-25 20:50:37.000000000 +0800
++++ linux-2.6.0-test5/init/main.c      2003-09-25 21:15:23.000000000 +0800
+@@ -96,6 +96,16 @@
+ 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
+Index: linux-2.6.0-test5/init/version.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/version.c      2003-09-09 03:50:04.000000000 +0800
++++ linux-2.6.0-test5/init/version.c   2003-09-25 21:15:23.000000000 +0800
+@@ -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 @@
+ 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/netconsole-over-netpoll.patch b/lustre/kernel_patches/patches/netconsole-over-netpoll.patch
new file mode 100644 (file)
index 0000000..73a936f
--- /dev/null
@@ -0,0 +1,303 @@
+l-mpm/Documentation/networking/netconsole.txt |   57 +++++++++++
+ l-mpm/drivers/net/Kconfig                     |    7 +
+ l-mpm/drivers/net/Makefile                    |    1 
+ l-mpm/drivers/net/netconsole.c                |  129 ++++++++++++++++++++++++++
+ l-mpm/net/Kconfig                             |    2 
+ 5 files changed, 195 insertions(+), 1 deletion(-)
+
+Index: linux-2.6.0-test5/drivers/net/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Makefile        2003-09-30 19:57:04.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Makefile     2003-09-30 22:08:20.527853744 +0800
+@@ -197,3 +197,4 @@
+ # Must come after all NICs it might use
+ obj-$(CONFIG_KGDB) += kgdb_eth.o
++obj-$(CONFIG_NETCONSOLE) += netconsole.o
+Index: linux-2.6.0-test5/net/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/net/Kconfig 2003-09-30 19:57:04.000000000 +0800
++++ linux-2.6.0-test5/net/Kconfig      2003-09-30 22:08:20.535852528 +0800
+@@ -690,6 +690,6 @@
+ source "drivers/net/Kconfig"
+ config NETPOLL
+-      def_bool KGDB
++      def_bool KGDB || NETCONSOLE
+ endmenu
+Index: linux-2.6.0-test5/Documentation/networking/netconsole.txt
+===================================================================
+--- linux-2.6.0-test5.orig/Documentation/networking/netconsole.txt     2003-09-30 22:08:20.495858608 +0800
++++ linux-2.6.0-test5/Documentation/networking/netconsole.txt  2003-09-30 22:08:20.536852376 +0800
+@@ -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.
+Index: linux-2.6.0-test5/drivers/net/Kconfig
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/Kconfig 2003-09-30 19:57:04.000000000 +0800
++++ linux-2.6.0-test5/drivers/net/Kconfig      2003-09-30 22:08:20.563848272 +0800
+@@ -2718,6 +2718,13 @@
+ 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"
+Index: linux-2.6.0-test5/drivers/net/netconsole.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/net/netconsole.c    2003-09-30 22:08:20.496858456 +0800
++++ linux-2.6.0-test5/drivers/net/netconsole.c 2003-09-30 22:23:47.571921624 +0800
+@@ -0,0 +1,190 @@
++/*
++ *  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>
++
++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;
++
++#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 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)
++{
++      int frag, left;
++      unsigned long flags;
++      
++      if (!sysrq_mode)
++              return;
++      if (!np.dev)
++              return;
++      local_irq_save(flags);
++
++      for(left = len; left; ) {
++              frag = min(left, MAX_PRINT_CHUNK);
++              send_msg_buffer(&np, msg, frag);
++              msg += frag;
++              left -= frag;
++      }
++
++      local_irq_restore(flags);
++}
++static void netconsole_do_sysrq(req_t *req)
++{
++        struct pt_regs regs;
++      char tmp[200];
++      
++      get_current_regs(&regs);
++      handle_sysrq((int)req->from, &regs, NULL);
++
++      sprintf(tmp, "SYSRQ command %d \n", req->from);
++      write_msg(NULL, tmp, strlen(tmp));
++}
++static void rx_hook(struct netpoll *np, int port, char *msg, int len)
++{
++      /* add sysrq support */
++      req_t *__req;
++      req_t req;
++      
++      __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);
++      Set_Sysrq_mode();
++      netconsole_do_sysrq(&req);
++      Clear_Sysrq_mode();
++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);
diff --git a/lustre/kernel_patches/patches/netpoll-core.patch b/lustre/kernel_patches/patches/netpoll-core.patch
new file mode 100644 (file)
index 0000000..173ed8a
--- /dev/null
@@ -0,0 +1,847 @@
+ 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(-)
+
+diff -puN /dev/null net/core/netpoll.c
+--- /dev/null  2003-09-12 12:14:37.000000000 -0500
++++ l-mpm/net/core/netpoll.c   2003-09-22 13:15:31.000000000 -0500
+@@ -0,0 +1,632 @@
++/*
++ * 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;
++
++      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;
++
++              spin_unlock_irqrestore(&rx_list_lock, flags);
++
++              if (np->rx_hook)
++                      np->rx_hook(np, ntohs(uh->source),
++                                  (char *)(uh+1), ulen-sizeof(uh)-4);
++
++              return 1;
++      }
++      spin_unlock_irqrestore(&rx_list_lock, flags);
++
++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;
++}
+diff -puN /dev/null include/linux/netpoll.h
+--- /dev/null  2003-09-12 12:14:37.000000000 -0500
++++ l-mpm/include/linux/netpoll.h      2003-09-22 13:15:31.000000000 -0500
+@@ -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
+diff -puN net/core/Makefile~netpoll-core net/core/Makefile
+--- l/net/core/Makefile~netpoll-core   2003-09-22 13:15:31.000000000 -0500
++++ l-mpm/net/core/Makefile    2003-09-22 13:15:31.000000000 -0500
+@@ -13,3 +13,4 @@ obj-$(CONFIG_NETFILTER) += netfilter.o
+ obj-$(CONFIG_NET_DIVERT) += dv.o
+ obj-$(CONFIG_NET_PKTGEN) += pktgen.o
+ obj-$(CONFIG_NET_RADIO) += wireless.o
++obj-$(CONFIG_NETPOLL) += netpoll.o
+diff -puN net/Kconfig~netpoll-core net/Kconfig
+--- l/net/Kconfig~netpoll-core 2003-09-22 13:15:31.000000000 -0500
++++ l-mpm/net/Kconfig  2003-09-22 13:15:31.000000000 -0500
+@@ -689,4 +689,7 @@ endmenu
+ source "drivers/net/Kconfig"
++config NETPOLL
++      def_bool KGDB
++
+ endmenu
+diff -puN include/linux/netdevice.h~netpoll-core include/linux/netdevice.h
+--- l/include/linux/netdevice.h~netpoll-core   2003-09-22 13:15:31.000000000 -0500
++++ l-mpm/include/linux/netdevice.h    2003-09-22 13:15:31.000000000 -0500
+@@ -452,13 +452,13 @@ struct net_device
+                                                    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
+@@ -536,10 +536,8 @@ 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);
++#ifdef CONFIG_NETPOLL
++extern int            netpoll_trap(void);
+ #endif
+ typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
+@@ -599,10 +597,9 @@ 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()) {
++#ifdef CONFIG_NETPOLL
++      if (netpoll_trap())
+               return;
+-      }
+ #endif
+       if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
+               __netif_schedule(dev);
+@@ -610,10 +607,9 @@ static inline void netif_wake_queue(stru
+ 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);
+ }
+diff -puN net/core/dev.c~netpoll-core net/core/dev.c
+--- l/net/core/dev.c~netpoll-core      2003-09-22 13:15:31.000000000 -0500
++++ l-mpm/net/core/dev.c       2003-09-22 13:16:34.000000000 -0500
+@@ -184,9 +184,6 @@ int netdev_fastroute_obstacles;
+ extern int netdev_sysfs_init(void);
+ extern int netdev_register_sysfs(struct net_device *);
+ extern int netdev_unregister_sysfs(struct net_device *);
+-#ifdef CONFIG_KGDB
+-extern int kgdb_net_interrupt(struct sk_buff *skb);
+-#endif
+ /*******************************************************************************
+@@ -1353,16 +1350,8 @@ 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 */
++#ifdef CONFIG_NETPOLL
++      if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) {
+               kfree_skb(skb);
+               return NET_RX_DROP;
+       }
+@@ -1552,6 +1541,13 @@ int netif_receive_skb(struct sk_buff *sk
+       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);
+diff -puN include/asm-i386/irq.h~netpoll-core include/asm-i386/irq.h
+--- l/include/asm-i386/irq.h~netpoll-core      2003-09-22 13:15:31.000000000 -0500
++++ l-mpm/include/asm-i386/irq.h       2003-09-22 13:15:31.000000000 -0500
+@@ -24,6 +24,7 @@ extern void disable_irq(unsigned int);
+ 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 */
+diff -puN arch/i386/kernel/irq.c~netpoll-core arch/i386/kernel/irq.c
+--- l/arch/i386/kernel/irq.c~netpoll-core      2003-09-22 13:15:31.000000000 -0500
++++ l-mpm/arch/i386/kernel/irq.c       2003-09-22 13:15:31.000000000 -0500
+@@ -896,6 +896,21 @@ int setup_irq(unsigned int irq, struct i
+       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/uml-patch-2.6.0-test5.patch b/lustre/kernel_patches/patches/uml-patch-2.6.0-test5.patch
new file mode 100644 (file)
index 0000000..1c4ec8d
--- /dev/null
@@ -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/pc/uml-patch-2.6.0-test5.pc b/lustre/kernel_patches/pc/uml-patch-2.6.0-test5.pc
new file mode 100644 (file)
index 0000000..35c586a
--- /dev/null
@@ -0,0 +1,114 @@
+arch/um/config.release
+arch/um/defconfig
+arch/um/drivers/chan_kern.c
+arch/um/drivers/chan_user.c
+arch/um/drivers/cow.h
+arch/um/drivers/cow_kern.c
+arch/um/drivers/cow_sys.h
+arch/um/drivers/cow_user.c
+arch/um/drivers/hostaudio_kern.c
+arch/um/drivers/line.c
+arch/um/drivers/Makefile
+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/port_kern.c
+arch/um/drivers/ssl.c
+arch/um/drivers/stdio_console.c
+arch/um/drivers/ubd_kern.c
+arch/um/drivers/ubd_user.c
+arch/um/drivers/xterm.c
+arch/um/drivers/xterm_kern.c
+arch/um/dyn.lds.S
+arch/um/include/irq_kern.h
+arch/um/include/kern_util.h
+arch/um/include/line.h
+arch/um/include/mconsole.h
+arch/um/include/mem.h
+arch/um/include/mem_user.h
+arch/um/include/os.h
+arch/um/include/sysdep-i386/sigcontext.h
+arch/um/include/ubd_user.h
+arch/um/include/user.h
+arch/um/include/user_util.h
+arch/um/Kconfig
+arch/um/Kconfig_block
+arch/um/Kconfig_net
+arch/um/kernel/config.c.in
+arch/um/kernel/exec_kern.c
+arch/um/kernel/init_task.c
+arch/um/kernel/irq.c
+arch/um/kernel/Makefile
+arch/um/kernel/mem.c
+arch/um/kernel/mem_user.c
+arch/um/kernel/process.c
+arch/um/kernel/process_kern.c
+arch/um/kernel/ptrace.c
+arch/um/kernel/sigio_kern.c
+arch/um/kernel/signal_kern.c
+arch/um/kernel/skas/include/mode.h
+arch/um/kernel/skas/include/uaccess.h
+arch/um/kernel/skas/Makefile
+arch/um/kernel/skas/process.c
+arch/um/kernel/skas/process_kern.c
+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/sysrq.c
+arch/um/kernel/time.c
+arch/um/kernel/time_kern.c
+arch/um/kernel/trap_kern.c
+arch/um/kernel/trap_user.c
+arch/um/kernel/tt/exec_kern.c
+arch/um/kernel/tt/include/uaccess.h
+arch/um/kernel/tt/process_kern.c
+arch/um/kernel/tt/ptproxy/proxy.c
+arch/um/kernel/tt/tracer.c
+arch/um/kernel/tt/uaccess_user.c
+arch/um/kernel/tty_log.c
+arch/um/kernel/um_arch.c
+arch/um/kernel/umid.c
+arch/um/kernel/user_util.c
+arch/um/Makefile
+arch/um/Makefile-i386
+arch/um/Makefile-skas
+arch/um/os-Linux/drivers/tuntap_user.c
+arch/um/os-Linux/file.c
+arch/um/sys-i386/bugs.c
+arch/um/sys-i386/Makefile
+arch/um/uml.lds.S
+arch/um/util/mk_constants_kern.c
+fs/hostfs/hostfs.h
+fs/hostfs/hostfs_kern.c
+fs/hostfs/hostfs_user.c
+fs/hostfs/Makefile
+fs/hppfs/hppfs_kern.c
+fs/hppfs/Makefile
+fs/Makefile
+include/asm-um/archparam-i386.h
+include/asm-um/common.lds.S
+include/asm-um/cpufeature.h
+include/asm-um/current.h
+include/asm-um/fixmap.h
+include/asm-um/irq.h
+include/asm-um/local.h
+include/asm-um/module-generic.h
+include/asm-um/module-i386.h
+include/asm-um/page.h
+include/asm-um/pgtable.h
+include/asm-um/processor-generic.h
+include/asm-um/processor-i386.h
+include/asm-um/sections.h
+include/asm-um/smp.h
+include/asm-um/system-generic.h
+include/asm-um/thread_info.h
+include/asm-um/timex.h
+include/linux/mm.h
+include/linux/proc_mm.h
+mm/Makefile
+mm/memory.c
+mm/mmap.c
+mm/mprotect.c
+mm/proc_mm.c
diff --git a/lustre/portals/knals/gmnal/Makefile.mk b/lustre/portals/knals/gmnal/Makefile.mk
new file mode 100644 (file)
index 0000000..b799a47
--- /dev/null
@@ -0,0 +1,10 @@
+# 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 ../../Kernelenv
+
+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/gmnal_api.c b/lustre/portals/knals/gmnal/gmnal_api.c
new file mode 100644 (file)
index 0000000..40d23db
--- /dev/null
@@ -0,0 +1,474 @@
+/* -*- 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_stxd(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_stxd(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_stxd(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_stxd(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_stxd(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_stxd(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));
+}
+
+EXPORT_SYMBOL(gmnal_init);
+EXPORT_SYMBOL(gmnal_fini);
+EXPORT_SYMBOL(gmnal_api_forward);
+EXPORT_SYMBOL(gmnal_api_validate);
+EXPORT_SYMBOL(gmnal_api_yield);
+EXPORT_SYMBOL(gmnal_api_lock);
+EXPORT_SYMBOL(gmnal_api_unlock);
+EXPORT_SYMBOL(gmnal_api_shutdown);
diff --git a/lustre/portals/knals/gmnal/gmnal_comm.c b/lustre/portals/knals/gmnal/gmnal_comm.c
new file mode 100644 (file)
index 0000000..9e32145
--- /dev/null
@@ -0,0 +1,1316 @@
+/* -*- 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;
+
+       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);
+               CDEBUG(D_INFO, "got [%s]\n", gmnal_rxevent(rxevent));
+               if (nal_data->ctthread_flag == GMNAL_THREAD_STOP) {
+                       CDEBUG(D_INFO, "time to exit\n");
+                       break;
+               }
+               switch (GM_RECV_EVENT_TYPE(rxevent)) {
+
+                       case(GM_RECV_EVENT):
+                               CDEBUG(D_NET, "CTTHREAD:: GM_RECV_EVENT\n");
+                               GMNAL_GM_UNLOCK(nal_data);
+                               gmnal_add_rxtwe(nal_data, rxevent);
+                               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;
+       gm_recv_event_t         *rxevent = NULL;
+       gm_recv_t               *recv = NULL;
+       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;
+               }
+               rxevent = we->rx;
+               CDEBUG(D_INFO, "thread got [%s]\n", gmnal_rxevent(rxevent));
+               recv = (gm_recv_t*)&(rxevent->recv);
+               buffer = gm_ntohp(recv->buffer);
+               PORTAL_FREE(we, sizeof(gmnal_rxtwe_t));
+
+               switch(((gmnal_msghdr_t*)buffer)->type) {
+               case(GMNAL_SMALL_MESSAGE):
+                       gmnal_pre_receive(nal_data, recv, 
+                                          GMNAL_SMALL_MESSAGE);
+               break;  
+               case(GMNAL_LARGE_MESSAGE_INIT):
+                       gmnal_pre_receive(nal_data, recv, 
+                                          GMNAL_LARGE_MESSAGE_INIT);
+               break;  
+               case(GMNAL_LARGE_MESSAGE_ACK):
+                       gmnal_pre_receive(nal_data, recv, 
+                                          GMNAL_LARGE_MESSAGE_ACK);
+               break;  
+               default:
+                       CDEBUG(D_ERROR, "Unsupported message type\n");
+                       gmnal_rx_bad(nal_data, recv, NULL);
+               }
+       }
+
+       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, gm_recv_t *recv, 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], recv [%p] type [%d]\n", 
+              nal_data, recv, gmnal_type);
+
+       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);
+
+       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, gm_recv_t *recv, gmnal_srxd_t *srxd)
+{
+       CDEBUG(D_TRACE, "Can't handle message\n");
+
+       if (!srxd)
+               srxd = gmnal_rxbuffer_to_srxd(nal_data, 
+                                              gm_ntohp(recv->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");
+       }
+       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
+        */
+       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_stxd_t    *stxd = 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
+                */
+               stxd = gmnal_get_stxd(nal_data, 1);
+               stxd->srxd = srxd;
+               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");
+                               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, stxd);
+                               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");
+                               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, stxd);
+                               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");
+                               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, stxd);
+                               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_stxd_t    *stxd = (gmnal_stxd_t*)context;
+       gmnal_srxd_t    *srxd = stxd->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_stxd(nal_data, stxd);
+
+       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;
+}
+
+
+
+
+EXPORT_SYMBOL(gmnal_rx_thread);
+EXPORT_SYMBOL(gmnal_ct_thread);
+EXPORT_SYMBOL(gmnal_pre_receive);
+EXPORT_SYMBOL(gmnal_rx_requeue_buffer);
+EXPORT_SYMBOL(gmnal_rx_bad);
+EXPORT_SYMBOL(gmnal_small_rx);
+EXPORT_SYMBOL(gmnal_large_tx);
+EXPORT_SYMBOL(gmnal_large_tx_callback);
+EXPORT_SYMBOL(gmnal_small_tx_callback);
diff --git a/lustre/portals/knals/gmnal/gmnal_module.c b/lustre/portals/knals/gmnal/gmnal_module.c
new file mode 100644 (file)
index 0000000..8e0f64c
--- /dev/null
@@ -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 portal_ioctl_data *data, 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", 
+              data->ioc_nal_cmd, private);
+       nal_data = (gmnal_data_t*)private;
+       switch(data->ioc_nal_cmd) {
+       /*
+        * just reuse already defined GET_NID. Should define GMNAL version
+        */
+       case(GMNAL_IOC_GET_GNID):
+
+               PORTAL_ALLOC(name, data->ioc_plen1);
+               copy_from_user(name, data->ioc_pbuf1, data->ioc_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(data->ioc_pbuf2, &gnid, data->ioc_plen2);
+       break;
+       default:
+               CDEBUG(D_INFO, "gmnal_cmd UNKNOWN[%d]\n", data->ioc_nal_cmd);
+               data->ioc_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 (file)
index 0000000..84fc3a0
--- /dev/null
@@ -0,0 +1,1007 @@
+/* -*- 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 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.
+ */
+int
+gmnal_alloc_stxd(gmnal_data_t *nal_data)
+{
+       int ntx = 0, nstx = 0, i = 0, nrxt_stx = 10;
+       gmnal_stxd_t    *txd = NULL;
+       void    *txbuffer = NULL;
+
+       CDEBUG(D_TRACE, "gmnal_alloc_small tx\n");
+
+       GMNAL_GM_LOCK(nal_data);
+       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);
+       
+       nstx = ntx/2;
+       /*
+        * num_stxds from gmnal_module.c
+        */
+       nstx = num_stxds;
+        nrxt_stx = nstx + 1;
+
+       CDEBUG(D_INFO, "Allocated [%d] send tokens to small messages\n", nstx);
+
+
+       /*
+        * 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);
+       
+       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);
+       }
+
+       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_stxd(gmnal_data_t *nal_data)
+{
+       gmnal_stxd_t *txd = nal_data->stxd, *_txd = 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));
+       }
+       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;
+               if (txd)
+                       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;
+               if (txd)
+                       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;
+}
+
+
+/*
+ *     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);
+       }
+
+}
+
+int
+gmnal_add_rxtwe(gmnal_data_t *nal_data, gm_recv_event_t *rxevent)
+{
+       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->rx = rxevent;
+
+       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);
+}
+
+EXPORT_SYMBOL(gmnal_yield);
+EXPORT_SYMBOL(gmnal_alloc_srxd);
+EXPORT_SYMBOL(gmnal_get_srxd);
+EXPORT_SYMBOL(gmnal_return_srxd);
+EXPORT_SYMBOL(gmnal_free_srxd);
+EXPORT_SYMBOL(gmnal_alloc_stxd);
+EXPORT_SYMBOL(gmnal_get_stxd);
+EXPORT_SYMBOL(gmnal_return_stxd);
+EXPORT_SYMBOL(gmnal_free_stxd);
+EXPORT_SYMBOL(gmnal_rxbuffer_to_srxd);
+EXPORT_SYMBOL(gmnal_rxevent);
+EXPORT_SYMBOL(gmnal_gm_error);
+EXPORT_SYMBOL(gmnal_stop_ctthread);
+EXPORT_SYMBOL(gmnal_add_rxtwe);
+EXPORT_SYMBOL(gmnal_get_rxtwe);
diff --git a/lustre/portals/utils/gmnalnid.c b/lustre/portals/utils/gmnalnid.c
new file mode 100644 (file)
index 0000000..701a814
--- /dev/null
@@ -0,0 +1,118 @@
+/* -*- 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;
+       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);
+       }
+
+
+
+        PORTAL_IOC_INIT (data);
+
+       /*
+        *      set up the inputs
+        */
+       len = strlen(name) + 1;
+       data.ioc_pbuf1 = malloc(len);
+       strcpy(data.ioc_pbuf1, name);
+       data.ioc_plen1 = len;
+
+       /*
+        *      set up the outputs
+        */
+       data.ioc_pbuf2 = (void*)&nid;
+       data.ioc_plen2 = sizeof(unsigned int*);
+
+        pfd = open("/dev/portals", O_RDWR);
+        if ( pfd < 0 ) {
+                perror("opening portals device");
+               free(data.ioc_pbuf1);
+                exit(-1);
+        }
+
+        data.ioc_nal = GMNAL;
+       data.ioc_nal_cmd = GMNAL_IOC_GET_GNID;
+/*
+       data.ioc_len += data.ioc_inllen1;
+       data.ioc_len += data.ioc_plen1;
+*/
+        rc = ioctl (pfd, IOC_PORTAL_NAL_CMD, &data);
+        if (rc < 0)
+        {
+               perror ("Can't get my NID");
+        }
+                        
+       free(data.ioc_pbuf1);
+       close(pfd);
+       printf("%u\n", nid);
+        exit(nid);
+}